// S — It researches until nothing's missing.
// The loop doesn't stop at the first answer. It plans angles + hypotheses,
// runs them, then ASSESSES coverage two ways: a deterministic verdict-rate
// gate and a senior-analyst reflection that lists gaps by severity. Closeable
// gaps reopen the loop and target the unused metrics — bounded by hard caps.
// Left: the loop. Right: the coverage assessment closing its own gaps.

const { useState: covUse, useEffect: covEff } = React;
const { pitchC, pitchMono } = window;

function SlideCoverage() {
  // 0 init · 1 round-1 assess (partial) · 2 go deeper · 3 round-2 sufficient
  const [stage, setStage] = covUse(0);
  covEff(() => {
    const ts = [
      setTimeout(() => setStage(1), 700),
      setTimeout(() => setStage(2), 2100),
      setTimeout(() => setStage(3), 3300),
    ];
    return () => ts.forEach(clearTimeout);
  }, []);

  const round = stage >= 2 ? 2 : 1;
  const done = stage >= 3;

  return (
    <div style={{
      flex: 1, minHeight: 0,
      display: 'grid',
      gridTemplateColumns: '0.92fr 1.08fr',
      gap: 28,
      marginTop: 24,
    }}>
      <LoopDiagram stage={stage} round={round} done={done} />
      <CoveragePanel stage={stage} done={done} />
    </div>
  );
}

function LoopDiagram({ stage, round, done }) {
  const NODES = [
    { k: 'plan',  label: 'Plan angles', sub: 'hypotheses from unused metrics' },
    { k: 'inv',   label: 'Investigate', sub: 'NL → SQL → DuckDB' },
    { k: 'assess',label: 'Assess coverage', sub: 'deterministic gate + reflection' },
  ];
  return (
    <div style={{
      display: 'flex', flexDirection: 'column', gap: 14,
      justifyContent: 'center', minHeight: 0,
    }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <div style={{
          fontFamily: pitchMono, fontSize: 14, fontWeight: 700,
          letterSpacing: 1.8, textTransform: 'uppercase', color: pitchC.navy,
        }}>The research loop</div>
        <span style={{
          fontFamily: pitchMono, fontSize: 12.5, fontWeight: 700,
          padding: '3px 10px', borderRadius: 999,
          background: done ? pitchC.mossBg : pitchC.seaBg,
          color: done ? pitchC.moss : pitchC.sea,
          letterSpacing: 0.4,
        }}>{done ? 'round 2 · complete' : `round ${round} / 3`}</span>
      </div>

      <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 12 }}>
        {NODES.map((nd, i) => {
          const active = !done && ((stage <= 1 && i === 2) || true);
          return (
            <div key={nd.k} style={{
              display: 'flex', alignItems: 'center', gap: 14,
              padding: '16px 18px',
              background: '#fff',
              border: `1px solid ${pitchC.hair}`,
              borderRadius: 13,
            }}>
              <span style={{
                fontFamily: pitchMono, fontSize: 13, fontWeight: 700,
                width: 26, height: 26, borderRadius: 8, flexShrink: 0,
                background: pitchC.bgSoft, color: pitchC.navy,
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
              }}>{i + 1}</span>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 18.5, fontWeight: 600, color: pitchC.ink, letterSpacing: -0.01 }}>{nd.label}</div>
                <div style={{ fontFamily: pitchMono, fontSize: 13, color: pitchC.muted2, marginTop: 2 }}>{nd.sub}</div>
              </div>
            </div>
          );
        })}

        {/* go-deeper return / synthesize */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 12,
          padding: '13px 18px', borderRadius: 13,
          border: `1px solid ${done ? pitchC.moss + '55' : pitchC.orange + '55'}`,
          background: done ? '#f3fbf7' : '#fff7f3',
          transition: 'all 400ms ease',
        }}>
          <svg width="22" height="22" viewBox="0 0 24 24" fill="none"
               stroke={done ? pitchC.moss : pitchC.orange} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
            {done
              ? <path d="M5 12l4 4 10-10"/>
              : <path d="M4 9a8 8 0 0114-3l2 2M20 5v4h-4"/>}
          </svg>
          <span style={{ fontSize: 16.5, fontWeight: 500, color: pitchC.ink }}>
            {done
              ? <>Coverage sufficient — <strong style={{ fontWeight: 600 }}>synthesize the answer</strong></>
              : <>Closeable gap found — <strong style={{ fontWeight: 600 }}>reopen the loop, go deeper</strong></>}
          </span>
        </div>
      </div>

      <div style={{
        fontFamily: pitchMono, fontSize: 12.5, color: pitchC.muted2, marginTop: 2,
      }}>bounded: ≤ 3 rounds · caps on hypotheses, time &amp; model calls</div>
    </div>
  );
}

function CoveragePanel({ stage, done }) {
  const pct = done ? 100 : stage >= 1 ? 58 : 12;
  const verdict = done ? 'sufficient' : stage >= 1 ? 'partial' : 'assessing…';
  const vColor = done ? pitchC.moss : stage >= 1 ? pitchC.amber : pitchC.muted2;

  const gaps = [
    { label: 'furniture funnel not yet measured', sev: 'important', closeable: true },
    { label: 'category average (engine can’t compute)', sev: 'nice', closeable: false },
  ];

  return (
    <div style={{
      background: '#fff',
      border: `1px solid ${pitchC.hair}`,
      borderRadius: 16,
      padding: '22px 26px',
      display: 'flex', flexDirection: 'column', gap: 18,
      minHeight: 0,
    }}>
      {/* coverage meter */}
      <div>
        <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
          <span style={{
            fontFamily: pitchMono, fontSize: 12.5, fontWeight: 700, letterSpacing: 1.6,
            textTransform: 'uppercase', color: pitchC.muted2,
          }}>Coverage</span>
          <span style={{ fontFamily: pitchMono, fontSize: 15, fontWeight: 700, color: vColor }}>{verdict}</span>
        </div>
        <div style={{ height: 12, borderRadius: 999, background: pitchC.bgSoft, overflow: 'hidden' }}>
          <div style={{
            height: '100%', width: `${pct}%`, borderRadius: 999,
            background: done ? pitchC.moss : 'linear-gradient(90deg, #ff663a, #c97a00)',
            transition: 'width 800ms cubic-bezier(.3,.7,.3,1)',
          }} />
        </div>
      </div>

      {/* gaps */}
      <div>
        <div style={{
          fontFamily: pitchMono, fontSize: 12.5, fontWeight: 700, letterSpacing: 1.6,
          textTransform: 'uppercase', color: pitchC.muted2, marginBottom: 10,
        }}>Gaps it found</div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 9 }}>
          {gaps.map((g) => {
            const closed = done && g.closeable;
            return (
              <div key={g.label} style={{
                display: 'flex', alignItems: 'center', gap: 11,
                padding: '11px 14px', borderRadius: 11,
                background: closed ? '#f3fbf7' : pitchC.bgSoft,
                border: `1px solid ${closed ? pitchC.moss + '40' : pitchC.hair}`,
                transition: 'all 400ms ease',
              }}>
                <span style={{
                  display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                  width: 20, height: 20, borderRadius: '50%', flexShrink: 0,
                  background: closed ? pitchC.moss : (g.closeable ? pitchC.amberBg : '#eceef2'),
                  color: '#fff',
                }}>
                  {closed
                    ? <svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 8.5l3 3 7-7"/></svg>
                    : <span style={{ width: 6, height: 6, borderRadius: '50%', background: g.closeable ? pitchC.amber : pitchC.muted2 }} />}
                </span>
                <span style={{ flex: 1, fontSize: 15.5, color: pitchC.ink, textDecoration: closed ? 'line-through' : 'none', opacity: closed ? 0.7 : 1 }}>{g.label}</span>
                <span style={{
                  fontFamily: pitchMono, fontSize: 11, fontWeight: 700, letterSpacing: 0.6, textTransform: 'uppercase',
                  color: closed ? pitchC.moss : (g.closeable ? pitchC.amber : pitchC.muted2),
                  padding: '2px 8px', borderRadius: 5,
                  background: closed ? pitchC.mossBg : (g.closeable ? pitchC.amberBg : '#eceef2'),
                }}>{closed ? 'closed' : g.sev}</span>
              </div>
            );
          })}
        </div>
        <div style={{ fontFamily: pitchMono, fontSize: 12.5, color: pitchC.muted2, marginTop: 9 }}>
          uncloseable gaps are kept as honest synthesis caveats
        </div>
      </div>

      {/* two judges */}
      <div style={{ marginTop: 'auto', paddingTop: 16, borderTop: `1px solid ${pitchC.hair}`, display: 'flex', flexDirection: 'column', gap: 9 }}>
        <Judge ok={done} label="deterministic gate" detail="≥ 3 validated / refuted, or ≥ 30% meaningful" />
        <Judge ok={done} label="analyst reflection" detail={done ? 'coverage: sufficient' : 'coverage: partial · 1 closeable gap'} amber={!done} />
      </div>
    </div>
  );
}

function Judge({ ok, label, detail, amber }) {
  const color = ok ? pitchC.moss : amber ? pitchC.amber : pitchC.muted2;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 11 }}>
      <span style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        width: 19, height: 19, borderRadius: '50%', flexShrink: 0,
        background: ok ? pitchC.moss : (amber ? pitchC.amberBg : '#eceef2'), color: '#fff',
      }}>
        {ok
          ? <svg width="11" height="11" viewBox="0 0 16 16" fill="none" stroke="#fff" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"><path d="M3 8.5l3 3 7-7"/></svg>
          : <span style={{ width: 6, height: 6, borderRadius: '50%', background: amber ? pitchC.amber : pitchC.muted2 }} />}
      </span>
      <span style={{ fontFamily: pitchMono, fontSize: 13.5, fontWeight: 700, color: pitchC.ink, minWidth: 168 }}>{label}</span>
      <span style={{ fontFamily: pitchMono, fontSize: 13, color }}>{detail}</span>
    </div>
  );
}

window.SlideCoverage = SlideCoverage;
