/**
 * SET 58 — sidebar: brand, extension/model truth, compose, runs. Static layout;
 * the only thing that ever changes shape is the runs list growing.
 */
import { useState, useSyncExternalStore } from 'react';
import { compile, getSnapshot, selectRun, subscribe } from './store';

function runTitle(prompt?: string): string {
  const first = (prompt ?? '').split('\n').find(l => l.trim());
  return first ? (first.length > 44 ? `${first.slice(0, 44)}…` : first) : '(untitled)';
}

export function Sidebar() {
  const s = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
  const [prompt, setPrompt] = useState('');
  const [mode, setMode] = useState<'rha' | 'vanilla'>('rha');
  const [unsupervised, setUnsupervised] = useState(false);
  const [sendError, setSendError] = useState<string | null>(null);
  const locked = s.liveRunning;
  const model = s.meta?.active?.model ?? null;
  const canCompile = !locked && prompt.trim().length > 0 && s.ext === 'present' && !!s.meta?.unlocked;

  return (
    <aside className="sh-side">
      {/* Brand always links home, same tab. */}
      <a className="sh-brand" href="/">
        <img src="/logo.svg" alt="RHA Wrapper" width="36" height="36" />
        <b>RHA<span className="sh-brand-w">Wrapper</span></b>
      </a>
      <div className="dim small sh-tagline">prompt → frozen IR → build → RHA. Deterministically verified.</div>

      <div className="sh-status small">
        {s.ext !== 'present'
          ? <span className="warn">Provider Vault extension not detected</span>
          : !s.meta?.unlocked
            ? <span className="warn">vault locked — open Provider Vault and unlock it</span>
            : model
              ? <span className="ok">{model}</span>
              : <span className="dim">no model connected — open Provider Vault → Set Active</span>}
        {s.meta?.vaultVersion ? <span className="dim"> · v{s.meta.vaultVersion}</span> : null}
      </div>

      <textarea
        data-rha-boot="control-prompt"
        className="sh-compose"
        value={prompt}
        disabled={locked}
        placeholder={locked
          ? 'Locked — a process is underway. New submissions unlock when it finishes.'
          : 'Paste your feature spec (author it in your LLM of choice). One feature per line: observable behavior + edge cases.'}
        onChange={e => setPrompt(e.target.value)}
      />
      <label className="small dim sh-mode">
        <input
          type="checkbox"
          checked={mode === 'vanilla'}
          disabled={locked}
          onChange={e => setMode(e.target.checked ? 'vanilla' : 'rha')}
        /> vanilla run (no RHA — baseline for comparison)
      </label>
      <label className="small dim sh-mode">
        <input
          type="checkbox"
          checked={unsupervised}
          disabled={locked}
          onChange={e => setUnsupervised(e.target.checked)}
        /> ⚡ Unsupervised E2E — no approval gates
      </label>
      <button
        type="button"
        className="primary sh-compile"
        data-rha-boot="control-compile"
        disabled={!canCompile}
        title={locked ? 'A process is underway — new submissions unlock when it finishes' : undefined}
        onClick={() => {
          setSendError(null);
          compile(prompt.trim(), mode, !unsupervised)
            .then(() => setPrompt(''))
            .catch(e => setSendError(e instanceof Error ? e.message : String(e)));
        }}
      >
        {locked ? 'Process underway…' : 'Compile'}
      </button>
      {sendError && <div className="bad small">{sendError}</div>}

      <div className="sh-runs" data-rha-shell="runs">
        <div className="sh-runs-head dim small">Web runs — {s.runs.length}</div>
        {s.runs.map(r => {
          const isLive = r.id === s.liveId && s.liveRunning;
          const selected = r.id === (s.viewingId ?? (s.liveRunning ? s.liveId : null));
          return (
            <button
              key={r.id}
              type="button"
              className={`sh-run${selected ? ' sel' : ''}`}
              onClick={() => selectRun(r.id)}
            >
              <span className="sh-run-title">{runTitle(r.prompt)}</span>
              <span className="dim small">
                {r.ts ? new Date(r.ts).toLocaleString() : '—'}
                {r.model ? ` · ${r.model}` : ''}
              </span>
              <span className={`small ${isLive ? 'warn' : statusTone(r.status)}`}>
                {isLive ? 'running' : (r.status ?? '—')}
              </span>
            </button>
          );
        })}
        {s.runs.length === 0 && <div className="dim small">no runs yet</div>}
      </div>
    </aside>
  );
}

function statusTone(status?: string): string {
  if (status === 'complete') return 'ok';
  if (status === 'failed' || status === 'interrupted') return 'bad';
  if (status === 'cancelled') return 'warn';
  return 'dim';
}
