// Code samples, Claude skills callout, comparison table, roadmap, FAQ, footer

const { useState: uC, useEffect: eC } = React;

function CodeSamples({ theme }) {
  const [tab, setTab] = useState(0);
  const samples = [
    {
      name: '@eval decorator',
      file: 'agent.py',
      lang: 'python',
      code: `from evalyn_sdk import eval

@eval(project="research-agent", version="v1")
def my_agent(query: str) -> str:
    # Any LLM call inside is auto-captured
    # Works with OpenAI, Anthropic, Gemini, LangChain,
    # CrewAI, DSPy, LlamaIndex, and 10 others.
    return call_llm(query)

my_agent("What is antimatter?")
# → trace saved to .evalyn/traces.db
# → tokens, cost, spans, errors — all auto-recorded`,
    },
    {
      name: 'suggest-metrics',
      file: 'shell',
      lang: 'bash',
      code: `$ evalyn suggest-metrics --dataset data/prod/... --mode llm-registry

→ LLM is inspecting your traces to pick metrics that fit...

  helpfulness_accuracy    [llm]  answers the user question accurately
  factual_accuracy        [llm]  factual claims are accurate & verifiable
  output_nonempty         [obj]  PASS if output is not empty
  latency_ms              [obj]  execution latency in ms
  url_count               [obj]  counts URLs (proxy for citations)

  saved 5 metrics to <dataset>/metrics/metrics.json
  hint: add --mode llm-brainstorm --append for custom metrics`,
    },
    {
      name: 'run-eval',
      file: 'shell',
      lang: 'bash',
      code: `$ evalyn run-eval --dataset data/prod/...

  loaded 10 metrics (3 objective · 7 subjective)
  dataset: 137 items

  Eval run 220e8590-2ccd-4cb5-a585-a0110285e786
  folder  .../eval_runs/20260127-055659_220e8590
          results.json · report.html

  metric                         type  count  pass    avg
  ────────────────────────────────────────────────────────
  output_nonempty                obj   137   100.0%  1.000
  latency_ms                     obj   137    —      23986
  url_count                      obj   137   100.0%  55.18
  factual_accuracy               llm   137    79.6%  0.801
  clarity_and_readability        llm   137    97.1%  1.000
  helpfulness_accuracy           llm   137    95.6%  0.985

  tokens: 10,048,041 in + 70,929 out → $1.03`,
    },
    {
      name: 'annotate',
      file: 'shell',
      lang: 'bash',
      code: `$ evalyn annotate --latest

  ═══════════════════════════════════════════════
    INTERACTIVE ANNOTATION
  ═══════════════════════════════════════════════
    dataset: gemini-deep-research-agent
    items to annotate: 137
    using eval run: 220e8590

    commands: [y]es  [n]o  [s]kip  [v]iew  [q]uit

  Item 1/137 [960912fa-637...]
  INPUT : {"question": "What is antimatter?"}
  OUTPUT: Antimatter is a form of matter that is...

  LLM JUDGE RESULTS
    factual_accuracy         PASS
    clarity_and_readability  PASS
    helpfulness_accuracy     PASS

  Pass? [y/n/s/v/q] _`,
    },
  ];

  const s = samples[tab];
  const [copied, copy] = useCopy();

  return (
    <Section theme={theme} id="code"
             eyebrow="the surface area"
             title="One decorator. A handful of commands. That's it."
             sub="Evalyn's API is deliberately thin. If you can write a Python function and run a shell command, you can evaluate your agent.">
      <div style={{
        border: `1px solid ${theme.border}`,
        background: theme.scheme === 'dark' ? '#0a0805' : '#1a1510',
        overflow: 'hidden',
      }}>
        <div style={{ display: 'flex', borderBottom: `1px solid ${theme.border}`, alignItems: 'center' }}>
          {samples.map((sm, i) => (
            <button key={i} onClick={() => setTab(i)} style={{
              background: tab === i ? (theme.scheme === 'dark' ? 'rgba(255,255,255,0.04)' : 'rgba(0,0,0,0.04)') : 'transparent',
              border: 'none',
              borderRight: `1px solid ${theme.border}`,
              borderTop: `2px solid ${tab === i ? theme.accent : 'transparent'}`,
              color: tab === i ? theme.text : theme.textDim,
              padding: '14px 20px',
              fontFamily: 'var(--mono)', fontSize: 12,
              letterSpacing: '0.05em', cursor: 'pointer',
              display: 'flex', gap: 10, alignItems: 'center',
            }}>
              <span style={{ color: tab === i ? theme.accent : theme.textMute, fontSize: 10 }}>
                {String(i + 1).padStart(2, '0')}
              </span>
              {sm.name}
            </button>
          ))}
          <div style={{ flex: 1 }} />
          <div style={{
            padding: '10px 16px', fontFamily: 'var(--mono)', fontSize: 11,
            color: theme.textMute, display: 'flex', alignItems: 'center', gap: 12,
          }}>
            <span>{s.file}</span>
            <button onClick={() => copy(s.code)} style={{
              background: 'transparent',
              border: `1px solid ${theme.border}`,
              color: copied ? theme.accent : theme.textDim,
              padding: '4px 10px', fontFamily: 'var(--mono)', fontSize: 10,
              letterSpacing: '0.1em', textTransform: 'uppercase', cursor: 'pointer',
            }}>{copied ? '✓ copied' : 'copy'}</button>
          </div>
        </div>
        <pre style={{
          margin: 0, padding: '24px 28px',
          fontFamily: 'var(--mono)', fontSize: 13, lineHeight: 1.65,
          color: theme.text, overflow: 'auto', minHeight: 380,
        }}>
          {highlightCode(s.code, s.lang, theme)}
        </pre>
      </div>
    </Section>
  );
}

// Very light syntax highlighting
function highlightCode(code, lang, theme) {
  const lines = code.split('\n');
  return lines.map((line, i) => {
    let parts = [];
    if (lang === 'python') {
      // Keywords, comments, strings, decorators
      const rules = [
        [/(#.*$)/,                 theme.textMute],
        [/(@\w+)/,                 theme.accent],
        [/(".*?"|'.*?')/,          `oklch(0.78 0.08 ${theme.hue + 90})`],
        [/\b(def|return|from|import|class|if|else|for|in|as|with|try|except|None|True|False)\b/, theme.accent],
      ];
      parts = colorize(line, rules, theme.text);
    } else {
      const rules = [
        [/^(\s*\$\s)/,             theme.accent],
        [/(--?[\w-]+)/,            `oklch(0.78 0.08 ${theme.hue + 90})`],
        [/(\[.*?\])/,              theme.accent],
        [/(PASS|FAIL|OK|ERR|HEALTH)/, theme.accent],
        [/(#.*$|→.*$)/,            theme.textMute],
      ];
      parts = colorize(line, rules, theme.text);
    }
    return <div key={i} style={{ minHeight: '1.65em' }}>{parts.length === 0 ? '\u00a0' : parts}</div>;
  });
}

function colorize(line, rules, defaultColor) {
  if (!line) return [];
  const marks = new Array(line.length).fill(null);
  for (const [re, color] of rules) {
    const globalRe = new RegExp(re.source, re.flags.includes('g') ? re.flags : re.flags + 'g');
    let m;
    while ((m = globalRe.exec(line)) !== null) {
      const start = m.index + (m[0].length - (m[1]?.length ?? m[0].length));
      for (let i = m.index; i < m.index + m[0].length; i++) {
        if (marks[i] == null) marks[i] = color;
      }
      if (m[0].length === 0) globalRe.lastIndex++;
    }
  }
  const out = [];
  let cur = '', curColor = marks[0] || defaultColor;
  for (let i = 0; i < line.length; i++) {
    const c = marks[i] || defaultColor;
    if (c !== curColor) {
      out.push(<span key={out.length} style={{ color: curColor }}>{cur}</span>);
      cur = ''; curColor = c;
    }
    cur += line[i];
  }
  if (cur) out.push(<span key={out.length} style={{ color: curColor }}>{cur}</span>);
  return out;
}

// ---------- Claude skills ----------

function ClaudeSkills({ theme }) {
  const skills = [
    { id: 'evalyn-setup',     trigger: 'Help me set up evaluation for my agent',  does: 'detects your framework, adds the @eval decorator, verifies traces are captured' },
    { id: 'evalyn-eval',      trigger: 'Evaluate my agent\'s performance',         does: 'builds a dataset, inspects traces to recommend metric bundles, runs evaluation' },
    { id: 'evalyn-analyze',   trigger: 'What do the evaluation results mean?',     does: 'runs progressive analysis, clusters failures, interprets pass rates' },
    { id: 'evalyn-calibrate', trigger: 'The judges seem too strict on factual_accuracy', does: 'guides annotation, runs calibration, re-evaluates with tuned judges' },
  ];
  return (
    <Section theme={theme} id="skills"
             eyebrow="claude code integration"
             title="Skip the docs. Ask Claude."
             sub="Evalyn ships with Claude Code skills. Drop them in ~/.claude/skills/ and Claude drives the whole pipeline — picking metrics from your real traces, not an abstract questionnaire.">
      <div style={{ display: 'grid', gridTemplateColumns: '1fr', gap: 1, background: theme.border, border: `1px solid ${theme.border}` }}>
        {skills.map((s, i) => (
          <div key={s.id} style={{
            background: theme.panel,
            display: 'grid', gridTemplateColumns: '260px 1fr 1fr 40px',
            gap: 24, padding: '22px 28px', alignItems: 'center',
          }}>
            <code style={{
              fontFamily: 'var(--mono)', fontSize: 14, color: theme.accent,
              display: 'flex', alignItems: 'center', gap: 10,
            }}>
              <span style={{ color: theme.textMute, fontSize: 11 }}>{String(i + 1).padStart(2, '0')}</span>
              {s.id}
            </code>
            <div style={{ fontFamily: 'var(--body)', fontSize: 14, color: theme.textDim, fontStyle: 'italic' }}>
              <span style={{ color: theme.textMute }}>"</span>{s.trigger}<span style={{ color: theme.textMute }}>"</span>
            </div>
            <div style={{ fontFamily: 'var(--body)', fontSize: 14, color: theme.text }}>
              → {s.does}
            </div>
            <span style={{ color: theme.accent, textAlign: 'right' }}><Icon.arrow /></span>
          </div>
        ))}
      </div>
      <div style={{ marginTop: 20 }}>
        <InstallCommand theme={theme} cmd="cp -r sdk/skills/evalyn-* ~/.claude/skills/" compact />
      </div>
    </Section>
  );
}

// ---------- Comparison ----------

function Comparison({ theme }) {
  const rows = [
    ['local-first storage',         '✓', '—', '—', '—'],
    ['no cloud account required',   '✓', '—', '—', '—'],
    ['built-in metric bank',        '136', '20+', '15+', '10+'],
    ['LLM-judge calibration',       '9 optimizers', '—', 'manual', 'manual'],
    ['auto-instrumentation',        '14 frameworks', '3', '4', '—'],
    ['one-click full pipeline',     '✓', '—', '—', '—'],
    ['annotation TUI',              '✓', '—', '—', '—'],
    ['HTML dashboard per run',      '✓', '✓', '✓', '—'],
    ['audio / image / video eval',  '✓', '—', '—', '—'],
    ['license',                     'MIT', 'Commercial', 'Commercial', 'Apache-2'],
  ];
  const cols = ['evalyn', 'tool A', 'tool B', 'tool C'];
  return (
    <Section theme={theme} id="compare"
             eyebrow="compared"
             title="Where evalyn fits."
             sub="Not a replacement for your observability stack. Not a competitor to your foundation model. A missing primitive between your agent and your users.">
      <div style={{ border: `1px solid ${theme.border}`, background: theme.panel, overflowX: 'auto' }}>
        <table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: 'var(--mono)', fontSize: 13 }}>
          <thead>
            <tr>
              <th style={{ ...thStyle(theme), width: 280 }}></th>
              {cols.map((c, i) => (
                <th key={c} style={{
                  ...thStyle(theme),
                  color: i === 0 ? theme.accent : theme.textDim,
                  textAlign: 'left', letterSpacing: '0.15em', textTransform: 'uppercase',
                  background: i === 0 ? theme.accentSoft : 'transparent',
                }}>
                  {i === 0 && <span style={{ marginRight: 6 }}>▸</span>}{c}
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {rows.map(([feat, ...vals], i) => (
              <tr key={i} style={{ borderTop: `1px solid ${theme.border}` }}>
                <td style={{ padding: '14px 20px', color: theme.text, fontFamily: 'var(--body)', fontSize: 14 }}>{feat}</td>
                {vals.map((v, j) => (
                  <td key={j} style={{
                    padding: '14px 20px',
                    color: j === 0 ? theme.accent : (v === '—' ? theme.textMute : theme.textDim),
                    background: j === 0 ? theme.accentSoft : 'transparent',
                    fontFamily: j === 0 ? 'var(--mono)' : 'var(--mono)',
                    fontSize: 13, fontWeight: j === 0 ? 500 : 400,
                  }}>{v}</td>
                ))}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <p style={{
        marginTop: 16, fontFamily: 'var(--mono)', fontSize: 11,
        color: theme.textMute, letterSpacing: '0.05em',
      }}>
        * competitor columns are anonymized; swap in the real names for your comparison.
      </p>
    </Section>
  );
}

function thStyle(theme) {
  return {
    padding: '14px 20px',
    textAlign: 'left',
    fontFamily: 'var(--mono)', fontSize: 11,
    color: theme.textMute, letterSpacing: '0.15em', fontWeight: 500,
    borderBottom: `1px solid ${theme.border}`,
  };
}

Object.assign(window, { CodeSamples, ClaudeSkills, Comparison });
