/* global React */
const { useEffect: useEffectPreview, useRef: useRefPreview, useState: useStatePreview } = React;

const MONITOR_TOOLS = [
  { ns: 'agent', name: 'plan_steps', dur: 412, kind: 'r' },
  { ns: 'docs', name: 'search_docs', dur: 92, kind: 't' },
  { ns: 'stripe', name: 'list_accounts', dur: 103, kind: 't' },
  { ns: 'pagerduty', name: 'get_status', dur: 114, kind: 't' },
  { ns: 'github', name: 'read_file', dur: 58, kind: 't' },
  { ns: 'linear', name: 'update_issue', dur: 192, kind: 't' },
  { ns: 'agent', name: 'identify_owner', dur: 188, kind: 'r' },
  { ns: 'linear', name: 'add_comment', dur: 76, kind: 't' },
];

const MONITOR_CAPTIONS = [
  "while you sign up · we're already running",
  'agent is picking tools…',
  'response received · evaluating',
  'judge scoring against rubric',
  'all assertions passed ✓',
];

const JUDGE_PHRASES = [
  'Agent invoked the required tools in the correct order. ',
  'Final output references the source incident and assigns the correct team. ',
  'No hallucinated arguments observed. Verdict: pass.',
];

function rand(min, max) { return min + Math.random() * (max - min); }
function sleep(ms) { return new Promise((r) => setTimeout(r, ms)); }

function LiveMonitorPanel({ captionIntro = MONITOR_CAPTIONS[0] } = {}) {
  const [rows, setRows] = useStatePreview([]);
  const [judgeText, setJudgeText] = useStatePreview('');
  const [verdictShown, setVerdictShown] = useStatePreview(false);
  const [caption, setCaption] = useStatePreview(captionIntro);

  useEffectPreview(() => {
    let cancelled = false;
    let captionIdx = 0;
    const captions = [captionIntro, ...MONITOR_CAPTIONS.slice(1)];
    setCaption(captions[0]);
    const captionTimer = setInterval(() => {
      captionIdx = (captionIdx + 1) % captions.length;
      setCaption(captions[captionIdx]);
    }, 3200);

    let runId = 0;

    async function runCycle() {
      while (!cancelled) {
        runId += 1;
        setRows([]);
        setJudgeText('');
        setVerdictShown(false);

        for (let i = 0; i < MONITOR_TOOLS.length; i += 1) {
          if (cancelled) return;
          const tool = MONITOR_TOOLS[i];
          const id = `${runId}-${i}`;
          setRows((current) => {
            const next = [...current, { ...tool, id, status: 'pending', shownDur: null }];
            return next.length > 6 ? next.slice(next.length - 6) : next;
          });
          await sleep(rand(220, 540));
          if (cancelled) return;
          setRows((current) => current.map((row) => (
            row.id === id ? { ...row, status: 'pass', shownDur: tool.dur } : row
          )));
          await sleep(80);
        }

        // Stream the judge verdict
        let acc = '';
        for (const phrase of JUDGE_PHRASES) {
          for (const ch of phrase) {
            if (cancelled) return;
            acc += ch;
            setJudgeText(acc);
            await sleep(rand(14, 38));
          }
          await sleep(120);
        }
        if (cancelled) return;
        setVerdictShown(true);
        await sleep(2600);
      }
    }

    runCycle();

    return () => {
      cancelled = true;
      clearInterval(captionTimer);
    };
  }, [captionIntro]);

  return (
    <aside className="preview-pane" aria-hidden="true">
      <div className="preview-head">
        <div>
          <div className="preview-title">Live monitor</div>
          <div className="preview-cap">{caption}</div>
        </div>
        <span className="live-pill"><span className="ld"></span>LIVE</span>
      </div>

      <div className="live-monitor">
        <div className="live-monitor-head">
          <div className="dots">
            <span className="dot"></span>
            <span className="dot"></span>
            <span className="dot"></span>
          </div>
          <span className="crumb">
            mcp://tools<span className="slash">/</span>
            <span style={{ color: 'rgba(245,241,232,0.5)' }}>demo-run</span>
          </span>
          <span className="meta">run_7B3F920A · claude-sonnet-4.6</span>
        </div>
        <div className="live-monitor-tools">
          {rows.map((row) => (
            <div
              key={row.id}
              className={`live-monitor-row${row.status === 'pending' ? ' pending' : ''}`}
            >
              <span className={`ic ${row.kind}`}>{row.kind === 'r' ? 'R' : 'T'}</span>
              <span className="name">
                <span className="ns">{row.ns}.</span>{row.name}
              </span>
              <span className="dur">
                {row.status === 'pending' ? 'pending' : `${row.shownDur}ms`}
              </span>
              <span className={`status ${row.status}`}>
                {row.status === 'pass' ? '✓' : ''}
              </span>
            </div>
          ))}
        </div>
      </div>

      <div className="judge-card">
        <div className="judge-card-head">
          <span className="badge">⚖ JUDGE</span>
          <span>LLM-as-judge reviewing</span>
          <span className="ml">claude-opus-4 · rubric v3</span>
        </div>
        <div className="judge-text">
          {judgeText}
          {!verdictShown && <span className="cursor"></span>}
        </div>
        <div className={`judge-verdict${verdictShown ? ' show' : ''}`}>
          <span className="verdict-pill"><span className="check">✓</span>PASS</span>
          <span className="score">Score <b>0.94</b> · 3 / 3 assertions</span>
          <span className="duration">12.4s</span>
        </div>
      </div>
    </aside>
  );
}

const DISCOVER_TOOLS = [
  { name: 'linear.search_issues', desc: 'Find issues by query, project, or label', params: ['query', 'project_id', 'limit'] },
  { name: 'linear.update_issue', desc: 'Mutate state, assignee, or priority', params: ['issue_id', 'state', 'assignee'] },
  { name: 'linear.add_comment', desc: 'Append a comment to a Linear issue', params: ['issue_id', 'body'] },
  { name: 'github.list_prs', desc: 'List open pull requests for a repo', params: ['repo', 'state'] },
  { name: 'github.read_file', desc: 'Read a file at a given ref', params: ['path', 'ref'] },
  { name: 'stripe.list_accounts', desc: 'List connected Stripe accounts', params: ['limit'] },
  { name: 'stripe.get_balance', desc: 'Get current balance for an account', params: ['account_id'] },
  { name: 'pagerduty.get_status', desc: 'Read on-call status for a service', params: ['service_id'] },
];

function DiscoverToolsPanel() {
  const [cards, setCards] = useStatePreview([]);
  const [counter, setCounter] = useStatePreview('0 / 24');
  const [tps, setTps] = useStatePreview('3.2');
  const cancelledRef = useRefPreview(false);

  useEffectPreview(() => {
    cancelledRef.current = false;
    let runId = 0;

    async function runCycle() {
      while (!cancelledRef.current) {
        runId += 1;
        setCards([]);
        setCounter('0 / 24');

        for (let i = 0; i < DISCOVER_TOOLS.length; i += 1) {
          if (cancelledRef.current) return;
          await sleep(rand(260, 520));
          const tool = DISCOVER_TOOLS[i];
          const id = `${runId}-${i}`;
          setCards((current) => {
            const next = [...current, { ...tool, id }];
            return next.length > 6 ? next.slice(next.length - 6) : next;
          });
          // fake the larger catalog total ticking up
          const fakeCount = Math.min(24, i + 1 + Math.floor(i / 2) * 2);
          setCounter(`${fakeCount} / 24`);
          setTps((2.5 + Math.random() * 1.6).toFixed(1));
        }
        if (cancelledRef.current) return;
        setCounter('24 / 24 ✓');
        await sleep(2800);
      }
    }

    runCycle();
    return () => { cancelledRef.current = true; };
  }, []);

  return (
    <aside className="preview-pane" aria-hidden="true">
      <div className="preview-head">
        <div>
          <div className="preview-title">
            Cataloging tools
            <span className="discover-counter">{counter}</span>
          </div>
          <div className="preview-cap">parsing schemas · inferring intent</div>
        </div>
        <span className="live-pill"><span className="ld"></span>LIVE</span>
      </div>

      <div className="discover-spark">
        <div>
          <div className="l">Tools/sec</div>
          <div className="v">{tps}</div>
        </div>
        <svg viewBox="0 0 200 36" preserveAspectRatio="none">
          <defs>
            <linearGradient id="discoverSparkGradient" x1="0" x2="0" y1="0" y2="1">
              <stop offset="0%" stopColor="#d13500" stopOpacity="0.4" />
              <stop offset="100%" stopColor="#d13500" stopOpacity="0" />
            </linearGradient>
          </defs>
          <path
            d="M0,28 L20,24 L40,18 L60,22 L80,12 L100,16 L120,8 L140,14 L160,6 L180,10 L200,4 L200,36 L0,36 Z"
            fill="url(#discoverSparkGradient)"
          />
          <path
            d="M0,28 L20,24 L40,18 L60,22 L80,12 L100,16 L120,8 L140,14 L160,6 L180,10 L200,4"
            stroke="#d13500"
            strokeWidth="1.5"
            fill="none"
          />
        </svg>
      </div>

      <div className="discover-cards">
        {cards.map((card) => (
          <div key={card.id} className="discover-card">
            <div className="name">{card.name}</div>
            <div className="desc">{card.desc}</div>
            <div className="params">
              {card.params.map((p) => (
                <span key={p} className="p">{p}</span>
              ))}
            </div>
          </div>
        ))}
      </div>
    </aside>
  );
}

window.LiveMonitorPanel = LiveMonitorPanel;
window.DiscoverToolsPanel = DiscoverToolsPanel;
