/* Krytz · Decision Trace Theater
 *
 * Cinematic end-to-end flow: a raw paragraph is captured, entities are
 * highlighted, items are extracted as cards, each card is scored on the
 * 7-signal priority layer, and the final ranked list assembles. Auto-plays on
 * a ~32s loop with replay control.
 */

function DecisionTrace() {
  const [phase, setPhase] = React.useState(0);   // 0…5
  const [typed, setTyped] = React.useState('');
  const [playing, setPlaying] = React.useState(true);
  const timersRef = React.useRef([]);

  // The script ──────────────────────────────────────────────────────────
  const TEXT = `Meeting w/ Asha 4pm Friday — needs the Q3 forecast doc before then. Daniel still blocked on legal review (mentioned 3rd time). Standup tomorrow @ 9. Priya asked twice about the design system rollout — owes her an answer. Budget approval needs 2 eng hires by Q3.`;

  const ENTITIES = [
    // [matchText, type]
    ['Asha',                  'person'],
    ['4pm Friday',            'date'],
    ['Q3 forecast doc',       'doc'],
    ['Daniel',                'person'],
    ['legal review',          'topic'],
    ['Standup',               'event'],
    ['9',                     'date'],
    ['Priya',                 'person'],
    ['design system rollout', 'topic'],
    ['2 eng hires by Q3',     'commitment'],
  ];

  const ITEMS = [
    { id: 't1', type: 'task',     who: 'Asha',  text: 'Send Q3 forecast doc',           due: 'Fri 4pm',      signals: { urgency: 0.92, dependency: 0.84, deadline: 0.91, recency: 0.71, mention: 0.55, fit: 0.68, effort: 0.42 } },
    { id: 't2', type: 'blocker',  who: 'Daniel', text: 'Daniel blocked on legal review', due: '3rd ping',     signals: { urgency: 0.74, dependency: 0.92, deadline: 0.42, recency: 0.81, mention: 0.88, fit: 0.40, effort: 0.30 } },
    { id: 't3', type: 'task',     who: 'Priya', text: 'Reply on design system rollout',  due: 'overdue 2d',   signals: { urgency: 0.66, dependency: 0.51, deadline: 0.70, recency: 0.62, mention: 0.74, fit: 0.62, effort: 0.28 } },
    { id: 't4', type: 'meeting',  who: 'team',  text: 'Standup tomorrow 9am',            due: 'tmrw',         signals: { urgency: 0.40, dependency: 0.21, deadline: 0.55, recency: 0.30, mention: 0.20, fit: 0.50, effort: 0.10 } },
    { id: 't5', type: 'plan',     who: 'you',   text: 'Q3 hiring plan · 2 eng',          due: 'this week',    signals: { urgency: 0.52, dependency: 0.40, deadline: 0.30, recency: 0.45, mention: 0.18, fit: 0.85, effort: 0.78 } },
  ];

  // Composite score (weighted, same family as the Krytz priority layer)
  function score(s) {
    return (s.urgency * 0.22 + s.dependency * 0.18 + s.deadline * 0.20 +
            s.recency * 0.10 + s.mention * 0.12 + s.fit * 0.10 +
            (1 - s.effort) * 0.08);
  }
  const RANKED = [...ITEMS].sort((a, b) => score(b.signals) - score(a.signals));
  const PRIMARY = RANKED[0];
  const NEXT    = RANKED.slice(1, 3);
  const QUIET   = RANKED.slice(3);

  // Phase 0 → 1: type the paragraph (≈ 5.5s)
  // Phase 1 → 2: highlight entities    (≈ 3.0s)
  // Phase 2 → 3: extract cards         (≈ 4.0s)
  // Phase 3 → 4: score cards           (≈ 5.0s)
  // Phase 4 → 5: rank & assemble       (≈ 4.0s)
  // Hold        : (≈ 6.0s) before replay

  function clearTimers() {
    timersRef.current.forEach(id => clearTimeout(id));
    timersRef.current = [];
  }
  function at(ms, fn) {
    const id = setTimeout(fn, ms);
    timersRef.current.push(id);
  }

  function start() {
    clearTimers();
    setTyped('');
    setPhase(0);

    // Typewriter
    const perChar = 28;
    for (let i = 1; i <= TEXT.length; i++) {
      at(i * perChar, () => setTyped(TEXT.slice(0, i)));
    }
    const t0 = TEXT.length * perChar + 300;

    at(t0, () => setPhase(1));         // entities
    at(t0 + 3000, () => setPhase(2));  // extract
    at(t0 + 7000, () => setPhase(3));  // score
    at(t0 + 12000, () => setPhase(4)); // rank
    at(t0 + 16000, () => setPhase(5)); // hold
    at(t0 + 22000, () => { if (playing) start(); });
  }

  React.useEffect(() => {
    if (playing) start();
    return clearTimers;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [playing]);

  function replay() {
    clearTimers();
    start();
  }
  function togglePlay() {
    if (playing) { clearTimers(); setPlaying(false); }
    else setPlaying(true);
  }

  // Highlighter — renders TEXT with entity matches wrapped after phase ≥ 1
  function renderHighlighted(t) {
    if (phase < 1) return t;
    const segments = [];
    let cursor = 0;
    // Greedy left-to-right, longest-first
    const sorted = [...ENTITIES].sort((a, b) => b[0].length - a[0].length);
    const taken = [];
    sorted.forEach(([word, kind]) => {
      let idx = 0;
      while ((idx = t.indexOf(word, idx)) !== -1) {
        if (!taken.some(r => idx < r.e && idx + word.length > r.s)) {
          taken.push({ s: idx, e: idx + word.length, kind, word });
        }
        idx += word.length;
      }
    });
    taken.sort((a, b) => a.s - b.s);
    taken.forEach((r, i) => {
      if (cursor < r.s) segments.push({ text: t.slice(cursor, r.s) });
      segments.push({ text: t.slice(r.s, r.e), kind: r.kind, id: `e${i}` });
      cursor = r.e;
    });
    if (cursor < t.length) segments.push({ text: t.slice(cursor) });

    return segments.map((seg, i) =>
      seg.kind
        ? <span key={i} className={`dt-ent dt-ent-${seg.kind}`} style={{ animationDelay: `${i * 50}ms` }}>{seg.text}</span>
        : <span key={i}>{seg.text}</span>
    );
  }

  const signalKeys = ['urgency','dependency','deadline','recency','mention','fit','effort'];

  return (
    <div className="dt-theater">
      <div className="dt-bar">
        <div className="dt-title">
          <span className="dt-live"><span className="dt-live-dot"></span>DECISION TRACE</span>
          <span className="dt-step">Step {Math.min(phase + 1, 5)} of 5</span>
        </div>
        <div className="dt-progress">
          <div className="dt-progress-track">
            <div className="dt-progress-fill" style={{ width: `${Math.min((phase / 4) * 100, 100)}%` }}></div>
          </div>
        </div>
        <div className="dt-controls">
          <button className="dt-btn" onClick={togglePlay} aria-label={playing ? 'Pause' : 'Play'}>
            {playing ? '⏸' : '▶'}
          </button>
          <button className="dt-btn" onClick={replay} aria-label="Replay">↻</button>
        </div>
      </div>

      <div className="dt-stage">
        {/* ── LEFT — raw capture ─────────────────────────── */}
        <div className="dt-col dt-col-input">
          <div className="dt-col-label">01 · Capture</div>
          <div className="dt-paper">
            <div className="dt-paper-meta">voice memo · 14:22 · 38 sec</div>
            <p className="dt-paper-text">
              {renderHighlighted(typed)}
              {typed.length < TEXT.length && <span className="dt-caret"></span>}
            </p>
          </div>
          {phase >= 1 && (
            <div className="dt-legend">
              <span><span className="dt-chip dt-ent-person"></span>person</span>
              <span><span className="dt-chip dt-ent-date"></span>date</span>
              <span><span className="dt-chip dt-ent-doc"></span>doc</span>
              <span><span className="dt-chip dt-ent-topic"></span>topic</span>
              <span><span className="dt-chip dt-ent-commitment"></span>commit</span>
            </div>
          )}
        </div>

        {/* ── MIDDLE — extracted items + scores ────────── */}
        <div className="dt-col dt-col-process">
          <div className="dt-col-label">02 · Extract  ·  03 · Score</div>
          <div className="dt-cards">
            {ITEMS.map((it, i) => (
              <article
                key={it.id}
                className={`dt-card ${phase >= 2 ? 'is-in' : ''} ${phase >= 3 ? 'is-scored' : ''}`}
                style={{ '--d': `${i * 220}ms` }}
              >
                <div className="dt-card-head">
                  <span className={`dt-type t-${it.type}`}>{it.type}</span>
                  <span className="dt-who">@ {it.who}</span>
                  <span className="dt-due">{it.due}</span>
                </div>
                <div className="dt-card-text">{it.text}</div>
                <div className="dt-signals" aria-hidden={phase < 3}>
                  {signalKeys.map((k, j) => (
                    <div key={k} className="dt-sig">
                      <span className="dt-sig-l">{k.slice(0,3)}</span>
                      <div className="dt-sig-bar">
                        <i style={{ width: phase >= 3 ? `${it.signals[k] * 100}%` : 0, transitionDelay: `${j * 80}ms` }}></i>
                      </div>
                      <span className="dt-sig-v">{phase >= 3 ? it.signals[k].toFixed(2) : '—'}</span>
                    </div>
                  ))}
                </div>
                {phase >= 3 && (
                  <div className="dt-score">
                    <span>composite</span>
                    <strong>{score(it.signals).toFixed(2)}</strong>
                  </div>
                )}
              </article>
            ))}
          </div>
        </div>

        {/* ── RIGHT — final prioritization ──────────────────────── */}
        <div className="dt-col dt-col-output">
          <div className="dt-col-label">04 · Decide</div>
          <div className={`dt-rank ${phase >= 4 ? 'is-ready' : ''}`}>
            <div className="dt-tier dt-primary">
              <span className="dt-tier-label">Primary</span>
              {phase >= 4 ? (
                <div className="dt-rank-row">
                  <span className={`dt-type t-${PRIMARY.type}`}>{PRIMARY.type}</span>
                  <span className="dt-rank-text">{PRIMARY.text}</span>
                  <strong>{score(PRIMARY.signals).toFixed(2)}</strong>
                </div>
              ) : (
                <div className="dt-rank-empty">…</div>
              )}
            </div>
            <div className="dt-tier dt-next">
              <span className="dt-tier-label">Next</span>
              {phase >= 4
                ? NEXT.map(n => (
                    <div key={n.id} className="dt-rank-row">
                      <span className={`dt-type t-${n.type}`}>{n.type}</span>
                      <span className="dt-rank-text">{n.text}</span>
                      <strong>{score(n.signals).toFixed(2)}</strong>
                    </div>
                  ))
                : <div className="dt-rank-empty">…</div>}
            </div>
            <div className="dt-tier dt-quiet">
              <span className="dt-tier-label">Quiet</span>
              {phase >= 4
                ? QUIET.map(q => (
                    <div key={q.id} className="dt-rank-row is-quiet">
                      <span className={`dt-type t-${q.type}`}>{q.type}</span>
                      <span className="dt-rank-text">{q.text}</span>
                      <strong>{score(q.signals).toFixed(2)}</strong>
                    </div>
                  ))
                : <div className="dt-rank-empty">…</div>}
            </div>
          </div>
        </div>
      </div>

      <div className="dt-foot">
        Watch the system think — 1 capture → 10 entities → 5 items → 35 signal scores → 1 Primary, 2 Next, 2 Quiet. Auto-replays.
      </div>
    </div>
  );
}

window.DecisionTrace = DecisionTrace;
