// Pipeline diagram (5 stages, animated)

const { useState: uPi, useEffect: ePi, useRef: rPi } = React;

const STAGES = [
  {
    n: '01', id: 'collect', title: 'COLLECT',
    verb: '@eval → SQLite', punch: 'One decorator.',
    desc: 'Wrap any function with @eval and every LLM call, token cost, and span gets auto-captured from 14 frameworks — OpenAI, Anthropic, LangChain, DSPy, CrewAI...',
    cli: ['list-calls', 'show-trace -v', 'show-projects'],
    artifact: 'TRACE.db'
  },
  {
    n: '02', id: 'build', title: 'BUILD',
    verb: 'traces → dataset', punch: 'Curate your eval set.',
    desc: 'Sample traces into a dataset with random, diverse, stratified, or clustered sampling. Deduplicate near-matches. Validate schema before you burn tokens on eval.',
    cli: ['build-dataset', 'validate', 'status'],
    artifact: 'DATASET.jsonl'
  },
  {
    n: '03', id: 'eval', title: 'EVALUATE',
    verb: 'suggest → run → analyze', punch: 'Score everything.',
    desc: '136 built-in metrics across 76 objective checks and 60 LLM judges. LLM-guided metric selection inspects your traces to pick what actually matters for your domain.',
    cli: ['suggest-metrics', 'run-eval', 'analyze', 'insights --deep'],
    artifact: 'REPORT.html'
  },
  {
    n: '04', id: 'calibrate', title: 'CALIBRATE',
    verb: 'annotate → tune', punch: 'Teach the judges.',
    desc: 'Annotate items in the terminal. Then one of 9 optimizers — GEPA, APE, OPRO, MIPROv2, TextGrad, PromptBreeder — re-tunes LLM-judge rubrics to match your human labels.',
    cli: ['annotate', 'calibrate', 'cluster-misalignments'],
    artifact: 'CALIBRATION.json'
  },
  {
    n: '05', id: 'expand', title: 'EXPAND',
    verb: 'simulate → loop', punch: 'Stress-test with synthetics.',
    desc: 'Generate similar, outlier, and adversarial queries from your existing dataset. Re-run eval on the synthetic split to catch regressions before they reach prod.',
    cli: ['simulate --modes similar,outlier', 'run-eval'],
    artifact: '→ back to 03'
  },
];

function PipelineDiagram({ theme }) {
  const [active, setActive] = useState(0);
  const [ref, visible] = useReveal();

  useEffect(() => {
    if (!visible) return;
    const t = setInterval(() => {
      setActive(a => (a + 1) % STAGES.length);
    }, 3800);
    return () => clearInterval(t);
  }, [visible]);

  const stage = STAGES[active];

  return (
    <Section theme={theme} id="pipeline" eyebrow="the pipeline" title="One loop. Five stages. Zero cloud."
             sub="Every step is a CLI command and a folder on disk. Nothing is magic. Nothing is remote.">
      <div ref={ref} style={{
        border: `1px solid ${theme.border}`,
        background: theme.panel,
      }}>
        {/* Stage strip */}
        <div style={{ display: 'grid', gridTemplateColumns: `repeat(${STAGES.length}, 1fr)` }}>
          {STAGES.map((s, i) => (
            <button
              key={s.id}
              onClick={() => setActive(i)}
              style={{
                appearance: 'none',
                cursor: 'pointer',
                padding: '24px 20px 22px',
                background: active === i ? theme.panel2 : 'transparent',
                border: 'none',
                borderRight: i < STAGES.length - 1 ? `1px solid ${theme.border}` : 'none',
                borderBottom: `2px solid ${active === i ? theme.accent : 'transparent'}`,
                textAlign: 'left',
                transition: 'all 0.3s',
                color: theme.text,
                position: 'relative',
              }}
            >
              <div style={{
                fontFamily: 'var(--mono)', fontSize: 11,
                color: active === i ? theme.accent : theme.textMute,
                letterSpacing: '0.15em', marginBottom: 10,
              }}>STAGE {s.n}</div>
              <div style={{
                fontFamily: 'var(--display)', fontSize: 22, fontWeight: 500,
                letterSpacing: '-0.01em',
                color: active === i ? theme.text : theme.textDim,
                marginBottom: 6,
              }}>{s.title}</div>
              <div style={{
                fontFamily: 'var(--mono)', fontSize: 10,
                color: theme.textMute, letterSpacing: '0.05em',
              }}>{s.verb}</div>
              {/* progress bar */}
              {active === i && visible && (
                <div style={{
                  position: 'absolute', left: 0, bottom: -2, height: 2,
                  background: theme.accent,
                  animation: 'progressBar 3.8s linear',
                }} />
              )}
            </button>
          ))}
        </div>
        {/* Detail panel */}
        <div style={{
          padding: '40px 40px 44px',
          borderTop: `1px solid ${theme.border}`,
          display: 'grid',
          gridTemplateColumns: '1.2fr 1fr',
          gap: 48,
          minHeight: 320,
        }}>
          <div>
            <div style={{
              display: 'inline-block',
              fontFamily: 'var(--mono)', fontSize: 11,
              color: theme.accent, letterSpacing: '0.18em',
              marginBottom: 14, padding: '4px 10px',
              border: `1px solid ${theme.accentHair}`,
            }}>
              {stage.n} · {stage.title}
            </div>
            <div style={{
              fontFamily: 'var(--display)', fontSize: 42, lineHeight: 1.05,
              letterSpacing: '-0.02em', fontWeight: 500,
              color: theme.text, marginBottom: 16, textWrap: 'balance',
            }}>{stage.punch}</div>
            <p style={{
              fontFamily: 'var(--body)', fontSize: 16, lineHeight: 1.6,
              color: theme.textDim, margin: '0 0 24px', maxWidth: 520,
            }}>{stage.desc}</p>
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              {stage.cli.map(c => (
                <code key={c} style={{
                  fontFamily: 'var(--mono)', fontSize: 11,
                  padding: '6px 10px',
                  background: theme.scheme === 'dark' ? 'rgba(0,0,0,0.35)' : 'rgba(255,255,255,0.4)',
                  border: `1px solid ${theme.border}`,
                  color: theme.text,
                  letterSpacing: '0.02em',
                }}>
                  <span style={{ color: theme.accent }}>$</span> evalyn {c}
                </code>
              ))}
            </div>
          </div>
          {/* Artifact visual */}
          <ArtifactVisual theme={theme} stage={stage} index={active} />
        </div>
      </div>

      {/* compact horizontal flow */}
      <div style={{
        marginTop: 24, padding: '16px 20px',
        border: `1px solid ${theme.border}`,
        background: theme.scheme === 'dark' ? 'rgba(0,0,0,0.25)' : 'rgba(255,255,255,0.3)',
        display: 'flex', alignItems: 'center', gap: 14, flexWrap: 'wrap',
        fontFamily: 'var(--mono)', fontSize: 12, color: theme.textDim,
      }}>
        <span style={{ color: theme.accent, letterSpacing: '0.1em' }}>FLOW ▸</span>
        {STAGES.map((s, i) => (
          <React.Fragment key={s.id}>
            <span style={{
              color: active === i ? theme.accent : theme.textDim,
              fontWeight: active === i ? 600 : 400,
            }}>{s.n} {s.title.toLowerCase()}</span>
            {i < STAGES.length - 1 && <span style={{ color: theme.textMute }}>→</span>}
          </React.Fragment>
        ))}
        <span style={{ color: theme.textMute }}>→ loop</span>
      </div>
    </Section>
  );
}

function ArtifactVisual({ theme, stage, index }) {
  return (
    <div style={{
      background: theme.scheme === 'dark' ? 'rgba(0,0,0,0.4)' : 'rgba(255,255,255,0.4)',
      border: `1px dashed ${theme.border}`,
      padding: 24,
      position: 'relative',
      display: 'flex', flexDirection: 'column',
      fontFamily: 'var(--mono)', fontSize: 11,
      minHeight: 260,
      overflow: 'hidden',
    }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 18 }}>
        <span style={{ color: theme.textMute, letterSpacing: '0.15em' }}>OUTPUT</span>
        <span style={{ color: theme.accent }}>{stage.artifact}</span>
      </div>
      {index === 0 && <TraceVisual theme={theme} />}
      {index === 1 && <DatasetVisual theme={theme} />}
      {index === 2 && <EvalVisual theme={theme} />}
      {index === 3 && <CalibrateVisual theme={theme} />}
      {index === 4 && <SimulateVisual theme={theme} />}
    </div>
  );
}

function TraceVisual({ theme }) {
  const rows = [
    { id: '960912fa', fn: 'research_agent', dur: '21215', status: 'OK' },
    { id: '75489541', fn: 'research_agent', dur: '22097', status: 'OK' },
    { id: '2567ea62', fn: 'chat',           dur: '14618', status: 'OK' },
    { id: 'a1b2c3d4', fn: 'summarize',      dur: '3045',  status: 'OK' },
    { id: 'ee00ff11', fn: 'research_agent', dur: '—',     status: 'ERR' },
  ];
  return (
    <div>
      {rows.map((r, i) => (
        <div key={r.id} style={{
          display: 'grid', gridTemplateColumns: '80px 1fr 60px 44px',
          gap: 10, padding: '6px 0',
          borderBottom: i < rows.length-1 ? `1px solid ${theme.border}` : 'none',
          opacity: 0, animation: `fadeInRow 0.4s ${i*80}ms forwards`,
        }}>
          <span style={{ color: theme.accent }}>{r.id}</span>
          <span style={{ color: theme.text }}>{r.fn}</span>
          <span style={{ color: theme.textDim, textAlign: 'right' }}>{r.dur}ms</span>
          <span style={{
            color: r.status === 'OK' ? theme.accent : '#ff6b6b',
            textAlign: 'right',
          }}>{r.status}</span>
        </div>
      ))}
    </div>
  );
}

function DatasetVisual({ theme }) {
  return (
    <div style={{ color: theme.text }}>
      <div style={{ color: theme.accent, marginBottom: 12 }}>→ stratified · deduplicated</div>
      <pre style={{ margin: 0, color: theme.textDim, fontSize: 10, lineHeight: 1.6 }}>{`{"id": "960912fa-637a",
 "input": {"question": "What is antimatter?"},
 "output": "Antimatter is a form of matter ...",
 "meta": {"tokens_in": 1240, "tokens_out": 389,
          "project": "gemini-deep-research-agent",
          "strata": "science.physics"}}
{"id": "75489541-8b13", ...}
{"id": "2567ea62-c442", ...}
... 137 items`}</pre>
    </div>
  );
}

function EvalVisual({ theme }) {
  const rows = [
    ['factual_accuracy', 0.80, 'row-warn'],
    ['helpfulness', 0.98, 'row-ok'],
    ['clarity', 0.97, 'row-ok'],
    ['conciseness', 0.91, 'row-warn'],
    ['grounding', 0.94, 'row-ok'],
  ];
  return (
    <div>
      {rows.map(([name, val, cls], i) => (
        <div key={name} style={{ padding: '5px 0', opacity: 0, animation: `fadeInRow 0.4s ${i*80}ms forwards` }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 3 }}>
            <span style={{ color: theme.text }}>{name}</span>
            <span style={{ color: cls === 'row-warn' ? theme.accent : theme.textDim }}>{val.toFixed(2)}</span>
          </div>
          <div style={{ height: 4, background: theme.border, position: 'relative' }}>
            <div style={{
              position: 'absolute', left: 0, top: 0, bottom: 0,
              width: `${val * 100}%`,
              background: cls === 'row-warn' ? theme.accent : theme.textDim,
              animation: `fillBar 0.8s ${i*80 + 200}ms both`,
            }} />
          </div>
        </div>
      ))}
    </div>
  );
}

function CalibrateVisual({ theme }) {
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
      <div>
        <div style={{ color: theme.textMute, marginBottom: 6 }}>BEFORE</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ color: theme.text }}>human</span>
          <div style={{ flex: 1, height: 6, background: theme.border, position: 'relative' }}>
            <div style={{ position: 'absolute', inset: 0, background: theme.accent, width: '72%' }} />
          </div>
          <span style={{ color: theme.accent }}>72</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
          <span style={{ color: theme.text }}>judge</span>
          <div style={{ flex: 1, height: 6, background: theme.border, position: 'relative' }}>
            <div style={{ position: 'absolute', inset: 0, background: theme.textDim, width: '44%' }} />
          </div>
          <span style={{ color: theme.textDim }}>44</span>
        </div>
      </div>
      <div style={{
        padding: '8px 12px',
        border: `1px solid ${theme.accentHair}`,
        color: theme.accent, letterSpacing: '0.1em', textAlign: 'center',
      }}>↓ GEPA · 9 iterations · Δ +27%</div>
      <div>
        <div style={{ color: theme.textMute, marginBottom: 6 }}>AFTER</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ color: theme.text }}>human</span>
          <div style={{ flex: 1, height: 6, background: theme.border, position: 'relative' }}>
            <div style={{ position: 'absolute', inset: 0, background: theme.accent, width: '72%' }} />
          </div>
          <span style={{ color: theme.accent }}>72</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginTop: 4 }}>
          <span style={{ color: theme.text }}>judge</span>
          <div style={{ flex: 1, height: 6, background: theme.border, position: 'relative' }}>
            <div style={{ position: 'absolute', inset: 0, background: theme.accent, width: '69%' }} />
          </div>
          <span style={{ color: theme.accent }}>69</span>
        </div>
      </div>
    </div>
  );
}

function SimulateVisual({ theme }) {
  const dots = Array.from({ length: 48 });
  return (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(12, 1fr)', gap: 4, alignContent: 'center', flex: 1 }}>
      {dots.map((_, i) => {
        const kind = i % 4;
        const c = kind === 0 ? theme.accent : theme.textDim;
        return (
          <div key={i} style={{
            aspectRatio: '1',
            background: c,
            opacity: kind === 0 ? 1 : 0.35,
            animation: `pop 0.4s ${i * 20}ms both`,
          }} />
        );
      })}
      <div style={{ gridColumn: '1 / -1', fontFamily: 'var(--mono)', fontSize: 10, color: theme.textMute, marginTop: 10, textAlign: 'center' }}>
        orig · similar · outlier · adversarial
      </div>
    </div>
  );
}

Object.assign(window, { PipelineDiagram, STAGES });
