// screen-triage.jsx — Interlude between P01 and P02.
// Distress signals from fellow operatives stream in; route each to the
// correct support uplink before the queue overflows.

const { useState: useStTr, useEffect: useEfTr, useRef: useRfTr, useMemo: useMmTr } = React;

function TriageScreen({ run, difficulty, onComplete }) {
  // ── Difficulty knobs ────────────────────────────────────────────────
  const tMul = window.__sylExtendedTime ? 1.5 : 1;
  const cfg = difficulty === 'recruit' ? { count: 5, time: Math.round(75 * tMul), nodes: 4 }
    : difficulty === 'ghost'   ? { count: 7, time: Math.round(50 * tMul), nodes: 6 }
    :                            { count: 6, time: Math.round(60 * tMul), nodes: 5 };

  // Pick a random subset of signals; for each signal ensure its target node
  // is one of the visible nodes.
  const session = useMmTr(() => {
    const shuffled = [...TRIAGE_SIGNALS].sort(() => Math.random() - 0.5);
    const picked = shuffled.slice(0, cfg.count);

    // Ensure every needed resource is among the visible nodes
    const needed = [...new Set(picked.map((s) => s.resource))];
    const extras = TRIAGE_NODES.filter((n) => !needed.includes(n.id))
      .sort(() => Math.random() - 0.5)
      .slice(0, Math.max(0, cfg.nodes - needed.length));
    const visibleNodes = [
      ...needed.map((id) => TRIAGE_NODES.find((n) => n.id === id)),
      ...extras,
    ].sort(() => Math.random() - 0.5);

    return { signals: picked, nodes: visibleNodes };
  }, [difficulty]);

  // ── State ───────────────────────────────────────────────────────────
  const [idx, setIdx] = useStTr(0);
  const [routed, setRouted] = useStTr([]);     // [{signalId, nodeId, correct}]
  const [feedback, setFeedback] = useStTr(null); // {nodeId, correct, signal, why}
  const [time, setTime] = useStTr(cfg.time);
  const [done, setDone] = useStTr(false);
  const [hoverNode, setHoverNode] = useStTr(null);
  const [pulseId, setPulseId] = useStTr(null);
  const tickRef = useRfTr(null);

  const signal = session.signals[idx];

  // ── Tick the queue clock ───────────────────────────────────────────
  const trPaused = window.useSylPaused ? window.useSylPaused() : false;
  useEfTr(() => {
    if (done || trPaused) return;
    tickRef.current = setInterval(() => {
      setTime((t) => {
        if (t <= 1) { clearInterval(tickRef.current); finalize(); return 0; }
        return t - 1;
      });
    }, 1000);
    return () => clearInterval(tickRef.current);
    // eslint-disable-next-line
  }, [done, trPaused]);

  // Auto-advance after feedback flash
  useEfTr(() => {
    if (!feedback) return;
    const t = setTimeout(() => {
      setFeedback(null);
      const next = idx + 1;
      if (next >= session.signals.length) finalize();
      else setIdx(next);
    }, 1500);
    return () => clearTimeout(t);
    // eslint-disable-next-line
  }, [feedback]);

  function route(nodeId) {
    if (feedback || done || !signal) return;
    const correct = nodeId === signal.resource;
    const node = session.nodes.find((n) => n.id === nodeId);
    const correctNode = TRIAGE_NODES.find((n) => n.id === signal.resource);
    setRouted((r) => [...r, { signalId: signal.id, nodeId, correct }]);
    setPulseId(nodeId);
    setFeedback({ correct, node, signal, correctNode });
    window.sylAnnounce && window.sylAnnounce(
      correct
        ? `Routed correctly to ${node.label}. Plus 120 XP.`
        : `Misrouted. Correct uplink was ${correctNode.label}.`,
      true
    );
    setTimeout(() => setPulseId(null), 600);
  }

  function finalize() {
    if (done) return;
    setDone(true);
    const correct = [...routed].filter((r) => r.correct).length
      + (feedback?.correct ? 1 : 0);
    const total = session.signals.length;
    const accuracy = correct / total;
    // Score: 100 base per correct + 30 timing bonus when accuracy ≥ 80%
    const base = correct * 120;
    const bonus = accuracy >= 0.8 ? Math.round(time * 4) : 0;
    const integrity = Math.round(accuracy * 100);
    setTimeout(() => onComplete({
      protocol: 'triage',
      score: base + bonus,
      correct, total, integrity,
      badge: accuracy >= 0.8 ? 'FIELD MEDIC' : null,
    }), 800);
  }

  const correctCount = routed.filter((r) => r.correct).length;
  const integrityNow = routed.length === 0 ? 100
    : Math.round((correctCount / routed.length) * 100);

  return (
    <div style={{ width: '100%', height: '100%', padding: '24px 32px',
      display: 'flex', flexDirection: 'column', gap: 18, overflow: 'hidden' }}>

      {/* Header */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end',
        borderBottom: '1px solid rgba(255,45,149,.25)', paddingBottom: 14 }}>
        <div>
          <div className="t-mono" style={{ fontSize: 11, color: 'var(--neon-magenta)',
            letterSpacing: '0.18em', marginBottom: 6 }}>
            ◢ INTERLUDE / UPLINK_TRIAGE
          </div>
          <div style={{ fontFamily: 'Orbitron', fontWeight: 800, fontSize: 30,
            letterSpacing: '0.04em', color: 'var(--ink-100)' }}>
            ROUTE THE DISTRESS SIGNALS
          </div>
          <div style={{ fontSize: 12, color: 'var(--ink-60)', marginTop: 6, maxWidth: 720, lineHeight: 1.5 }}>
            Squad's regrouping. Operatives in adjacent ops are pinging your channel — drop each
            signal onto the right uplink. Wrong route still helps, but costs cycles.
          </div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="t-mono" style={{ fontSize: 10, color: 'var(--ink-60)', letterSpacing: '0.14em' }}>
            QUEUE TIME
          </div>
          <div style={{ fontFamily: 'Orbitron', fontWeight: 800, fontSize: 36,
            color: time < 15 ? 'var(--neon-magenta)' : 'var(--neon-yellow)',
            lineHeight: 1, letterSpacing: '0.04em' }}>
            {time}s
          </div>
          <div className="t-mono" style={{ fontSize: 10, color: 'var(--ink-60)',
            letterSpacing: '0.14em', marginTop: 6 }}>
            INTEGRITY · <b style={{ color: integrityNow >= 80 ? 'var(--neon-lime)' : 'var(--neon-yellow)' }}>{integrityNow}%</b>
          </div>
        </div>
      </div>

      {/* Progress dots */}
      <div style={{ display: 'flex', gap: 6 }}>
        {session.signals.map((s, i) => {
          const r = routed[i];
          return (
            <div key={s.id} style={{
              flex: 1, height: 4,
              background: r ? (r.correct ? 'var(--neon-lime)' : 'var(--neon-magenta)')
                : i === idx ? 'var(--neon-cyan)' : 'rgba(0,234,255,.1)',
              boxShadow: i === idx && !r ? '0 0 10px var(--neon-cyan)' : 'none',
              transition: 'background .25s',
            }} />
          );
        })}
      </div>

      {/* Main area: signal card + node grid */}
      <div style={{ flex: 1, display: 'grid', gridTemplateRows: 'auto 1fr', gap: 20, minHeight: 0 }}>
        {/* Signal card */}
        <div className="panel panel-magenta" style={{
          padding: 24, position: 'relative',
          animation: feedback ? 'none' : 'sigPulse 2s ease-in-out infinite',
          opacity: feedback?.correct ? 0.4 : 1,
          transition: 'opacity .3s',
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 8 }}>
            <div className="chip chip-magenta">◢ INCOMING / SIGNAL {idx + 1} of {session.signals.length}</div>
            <div className="t-mono" style={{ fontSize: 10, color: 'var(--ink-60)', letterSpacing: '0.14em' }}>
              ENCRYPTED · SRC/anonymous-op-{(idx * 7 + 13) % 99}
            </div>
          </div>
          <div style={{ fontFamily: 'Orbitron', fontWeight: 600, fontSize: 22, lineHeight: 1.4,
            color: 'var(--ink-100)', letterSpacing: '0.01em' }}>
            "{signal?.text}"
          </div>
        </div>

        {/* Node grid */}
        <div style={{ display: 'grid',
          gridTemplateColumns: `repeat(${Math.min(session.nodes.length, 5)}, 1fr)`,
          gap: 12, minHeight: 0 }}>
          {session.nodes.map((n) => {
            const showCorrect = feedback && n.id === feedback.signal.resource;
            const showWrong = feedback && pulseId === n.id && !feedback.correct;
            const showPulse = pulseId === n.id && feedback?.correct;
            const isHover = hoverNode === n.id && !feedback;
            return (
              <button key={n.id}
                onClick={() => route(n.id)}
                onMouseEnter={() => setHoverNode(n.id)}
                onMouseLeave={() => setHoverNode(null)}
                disabled={!!feedback}
                aria-label={`Route signal to ${n.label}${n.desc ? `: ${n.desc}` : ''}`}
                className="panel"
                style={{
                  padding: 16, cursor: feedback ? 'default' : 'pointer',
                  display: 'flex', flexDirection: 'column', gap: 8, minHeight: 130,
                  background: showCorrect ? `${n.accent}25`
                    : showWrong ? 'rgba(255,45,149,.18)'
                    : isHover ? `${n.accent}12` : undefined,
                  borderColor: showCorrect ? n.accent
                    : showWrong ? 'var(--neon-magenta)'
                    : isHover ? n.accent : `${n.accent}33`,
                  boxShadow: showPulse ? `0 0 28px ${n.accent}` :
                    showCorrect ? `0 0 24px ${n.accent}aa` :
                    showWrong ? '0 0 24px rgba(255,45,149,.7)' :
                    isHover ? `0 0 18px ${n.accent}66` : 'none',
                  transition: 'all .2s',
                  textAlign: 'left',
                  fontFamily: 'inherit',
                }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                  <div style={{
                    width: 38, height: 38, background: `${n.accent}22`,
                    border: `1px solid ${n.accent}88`, color: n.accent,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: 'Orbitron', fontWeight: 800, fontSize: 18,
                  }}>{n.glyph}</div>
                  <div className="t-mono" style={{ fontSize: 10, color: n.accent,
                    letterSpacing: '0.14em' }}>UPLINK</div>
                </div>
                <div style={{ fontFamily: 'Orbitron', fontWeight: 700, fontSize: 13,
                  letterSpacing: '0.02em', color: 'var(--ink-100)', lineHeight: 1.3 }}>
                  {n.label}
                </div>
                <div style={{ fontSize: 11, color: 'var(--ink-60)', lineHeight: 1.4 }}>
                  {n.desc}
                </div>
              </button>
            );
          })}
        </div>
      </div>

      {/* Feedback flash */}
      {feedback && (
        <div className="t-mono" style={{
          position: 'absolute', left: 32, right: 32, bottom: 24,
          padding: '12px 16px',
          background: feedback.correct ? 'rgba(170,255,0,.1)' : 'rgba(255,45,149,.1)',
          border: `1px solid ${feedback.correct ? 'var(--neon-lime)' : 'var(--neon-magenta)'}`,
          color: feedback.correct ? 'var(--neon-lime)' : 'var(--neon-magenta)',
          fontSize: 12, letterSpacing: '0.1em', display: 'flex',
          justifyContent: 'space-between', gap: 16,
        }}>
          <span>
            {feedback.correct
              ? `✓ ROUTED → ${feedback.node.label.toUpperCase()}`
              : `✗ MISROUTED. CORRECT UPLINK: ${feedback.correctNode.label.toUpperCase()}`}
          </span>
          <span style={{ color: 'var(--ink-60)' }}>
            {feedback.correct ? '+ 120 XP' : '+ 0 XP'}
          </span>
        </div>
      )}

      <style>{`
        @keyframes sigPulse {
          0%, 100% { box-shadow: 0 0 0 rgba(255,45,149,.3); }
          50% { box-shadow: 0 0 24px rgba(255,45,149,.4); }
        }
      `}</style>
    </div>
  );
}

window.TriageScreen = TriageScreen;
