// AgentTests — capability test runner panel.
//
// Calls POST /api/agents/test to run the test suite (backend/agent_tests.py)
// against the live editor agent. Each test fires a fixed question, validates
// the response satisfies a contract (right tool called, required keywords
// present, citation discipline, length budget), and reports pass/fail with
// an approximate token cost. Use as the SET STANDARD any token-efficiency
// change must preserve.

const { useState: atUseState, useEffect: atUseEffect, useCallback: atUseCallback } = React;

function AgentTests({ open, onClose }) {
  if (!open) return null;
  const [manifest, setManifest] = atUseState([]);
  const [running, setRunning] = atUseState(false);
  const [report, setReport] = atUseState(null);
  const [err, setErr] = atUseState('');
  const [selected, setSelected] = atUseState(new Set());

  // Load manifest on open
  atUseEffect(() => {
    fetch('/api/agents/test/manifest')
      .then(r => r.ok ? r.json() : null)
      .then(j => setManifest(j?.tests || []))
      .catch(() => {});
  }, []);

  const run = atUseCallback(async (idsArg = null) => {
    if (running) return;
    setRunning(true);
    setReport(null);
    setErr('');
    try {
      const body = {};
      if (idsArg && idsArg.length > 0) body.ids = idsArg;
      const r = await fetch('/api/agents/test', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });
      if (!r.ok) {
        throw new Error(`HTTP ${r.status}: ${(await r.text()).slice(0, 100)}`);
      }
      setReport(await r.json());
    } catch (e) {
      setErr(String(e.message || e));
    } finally {
      setRunning(false);
    }
  }, [running]);

  const toggle = (id) => {
    setSelected(s => {
      const n = new Set(s);
      n.has(id) ? n.delete(id) : n.add(id);
      return n;
    });
  };

  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 105,
      background: 'rgba(10,10,12,0.85)', backdropFilter: 'blur(8px)',
      display: 'flex', alignItems: 'flex-start', justifyContent: 'center',
      padding: '40px 20px',
    }} onClick={onClose}>
      <div onClick={e => e.stopPropagation()} style={{
        width: '100%', maxWidth: 880, maxHeight: 'calc(100vh - 80px)', overflowY: 'auto',
        background: 'var(--bg)', border: '1px solid var(--line-2)',
        borderRadius: 6, padding: 20, fontFamily: 'var(--font-body)',
      }}>
        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 12,
          paddingBottom: 12, marginBottom: 14, borderBottom: '1px solid var(--line)',
        }}>
          <h1 style={{
            fontFamily: 'Instrument Serif, serif', fontStyle: 'italic',
            fontSize: 24, margin: 0, color: 'var(--text)',
          }}>Agent capability tests</h1>
          <span style={{
            fontSize: 11, letterSpacing: '0.18em', textTransform: 'uppercase',
            color: 'var(--text-dim)',
          }}>
            brain + API + recall + citation discipline · {manifest.length} tests
          </span>
          <button onClick={onClose} style={{
            marginLeft: 'auto',
            padding: '4px 10px', fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
            background: 'transparent', color: 'var(--text-dim)',
            border: '1px solid var(--line)', borderRadius: 3, cursor: 'pointer',
          }}>close</button>
        </div>

        {err && (
          <div style={{
            padding: 10, marginBottom: 12, fontSize: 11,
            background: 'rgba(217,106,106,0.12)', color: '#d96a6a',
            border: '1px solid rgba(217,106,106,0.4)', borderRadius: 4,
          }}>{err}</div>
        )}

        {/* Run controls */}
        <div style={{ display: 'flex', gap: 8, marginBottom: 14, alignItems: 'center' }}>
          <button
            onClick={() => run()}
            disabled={running}
            style={{
              padding: '8px 16px', fontSize: 12, fontWeight: 700,
              fontFamily: "'JetBrains Mono', monospace",
              background: running ? 'transparent' : 'rgba(95,179,124,0.14)',
              color: running ? 'var(--text-dim)' : '#5fb37c',
              border: '1px solid ' + (running ? 'var(--line)' : '#5fb37c'),
              borderRadius: 3,
              cursor: running ? 'wait' : 'pointer',
              letterSpacing: '0.06em',
            }}
          >
            {running ? '⏵ Running…' : '▶ Run all'}
          </button>
          <button
            onClick={() => run(Array.from(selected))}
            disabled={running || selected.size === 0}
            title={selected.size === 0 ? 'Select tests below first' : `Run ${selected.size} selected`}
            style={{
              padding: '8px 14px', fontSize: 11,
              fontFamily: "'JetBrains Mono', monospace",
              background: 'transparent', color: 'var(--text-2)',
              border: '1px solid var(--line)', borderRadius: 3,
              cursor: (running || selected.size === 0) ? 'not-allowed' : 'pointer',
              opacity: (running || selected.size === 0) ? 0.5 : 1,
            }}
          >Run selected ({selected.size})</button>
          {report && (
            <span style={{
              marginLeft: 'auto', fontSize: 12, fontWeight: 700,
              fontFamily: "'JetBrains Mono', monospace",
              color: report.pass_rate === 1.0 ? '#5fb37c'
                   : report.pass_rate >= 0.7 ? '#d9a85f' : '#d96a6a',
            }}>
              {report.passed}/{report.n} pass · {(report.pass_rate * 100).toFixed(0)}%
              <span style={{ marginLeft: 12, fontSize: 10, color: 'var(--text-dim)', fontWeight: 400 }}>
                · {report.duration_s}s · ~{report.approx_tokens_input + report.approx_tokens_output} tokens
              </span>
            </span>
          )}
        </div>

        {/* Manifest with results merged in */}
        {manifest.map(t => {
          const r = report?.results?.find(x => x.id === t.id);
          const isSel = selected.has(t.id);
          const status = r ? (r.passed ? 'pass' : 'fail') : 'idle';
          const accent = status === 'pass' ? '#5fb37c'
                       : status === 'fail' ? '#d96a6a'
                       : 'var(--line)';
          return (
            <div key={t.id} style={{
              marginBottom: 8, padding: '10px 12px',
              background: 'var(--bg-2)',
              borderLeft: `3px solid ${accent}`,
              border: '1px solid var(--line)',
              borderRadius: 3,
            }}>
              <div style={{ display: 'flex', gap: 10, alignItems: 'baseline' }}>
                <input
                  type="checkbox"
                  checked={isSel}
                  onChange={() => toggle(t.id)}
                  style={{ marginRight: 4, cursor: 'pointer' }}
                />
                <span style={{
                  fontSize: 11, fontFamily: "'JetBrains Mono', monospace",
                  color: 'var(--accent)', fontWeight: 700,
                }}>{t.id}</span>
                <span style={{
                  padding: '1px 6px', fontSize: 8,
                  letterSpacing: '0.14em', textTransform: 'uppercase',
                  fontWeight: 700, background: 'rgba(255,255,255,0.05)',
                  color: 'var(--text-dim)',
                  border: '1px solid var(--line)', borderRadius: 2,
                  fontFamily: "'JetBrains Mono', monospace",
                }}>{t.tag}</span>
                {r && (
                  <>
                    <span style={{
                      fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
                      color: r.tool_pass ? '#5fb37c' : '#d96a6a',
                    }}>{r.tool_pass ? '✓' : '✗'} tool</span>
                    <span style={{
                      fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
                      color: r.content_pass ? '#5fb37c' : '#d96a6a',
                    }}>{r.content_pass ? '✓' : '✗'} content</span>
                    {t.must_cite_path && (
                      <span style={{
                        fontSize: 10, fontFamily: "'JetBrains Mono', monospace",
                        color: r.citation_pass ? '#5fb37c' : '#d96a6a',
                      }}>{r.citation_pass ? '✓' : '✗'} cite</span>
                    )}
                    <span style={{
                      marginLeft: 'auto', fontSize: 9, color: 'var(--text-dim)',
                      fontFamily: "'JetBrains Mono', monospace",
                    }}>
                      {r.duration_s}s · {r.tools_called.join(',') || '—'}
                    </span>
                  </>
                )}
              </div>
              <div style={{
                marginTop: 4, marginLeft: 22,
                fontSize: 11, color: 'var(--text)', lineHeight: 1.4,
              }}>
                {t.question}
              </div>
              {t.must_call_tool && (
                <div style={{
                  marginTop: 4, marginLeft: 22,
                  fontSize: 9, color: 'var(--text-dim)',
                  fontFamily: "'JetBrains Mono', monospace",
                }}>
                  must call: <b>{t.must_call_tool}</b>
                  {t.must_contain.length > 0 && ` · must contain: ${t.must_contain.join(', ')}`}
                  {t.must_cite_path && ' · must cite path'}
                </div>
              )}
              {r && r.notes.length > 0 && (
                <div style={{
                  marginTop: 4, marginLeft: 22,
                  fontSize: 10, color: '#d96a6a',
                  fontFamily: "'JetBrains Mono', monospace",
                }}>
                  {r.notes.map((n, i) => <div key={i}>⚠ {n}</div>)}
                </div>
              )}
              {r && r.response_preview && (
                <div style={{
                  marginTop: 6, marginLeft: 22, padding: '6px 8px',
                  fontSize: 10, color: 'var(--text-2)',
                  background: 'var(--bg-3)', borderRadius: 2,
                  fontStyle: 'italic', lineHeight: 1.5,
                }}>
                  {r.response_preview}
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}

window.AgentTests = AgentTests;
