/* ============================================================
   Agent Chat — flowing transcript of agent deliberation
   Right-rail companion to the swarm canvas. Messages stream
   in over time with a typewriter effect, simulating the
   agents thinking out loud.
   ============================================================ */
const AgentChat = () => {
  const SCRIPT = [
    { role: "ANALYST",  tone: "neutral",  body: "Sat imagery shows mobilization at 3 of 5 forward sites. Above baseline." },
    { role: "DOVE",     tone: "calm",     body: "Diplomatic channels still open per Reuters 14:22 — don't overweight kinetic signal." },
    { role: "HAWK",     tone: "alert",    body: "Historical response window is 72h max. Pricing should reflect that decay." },
    { role: "QUANT",    tone: "data",     body: "Base rate on this marker stack: 67% (n=14, σ=0.08)." },
    { role: "INSIDER",  tone: "alert",    body: "Unusual oil futures activity flagged 12m ago — implied vol +18%." },
    { role: "POLICY",   tone: "neutral",  body: "UN session Thursday adds containment vector. Marginal." },
    { role: "WHALE",    tone: "data",     body: "+$2.4M into NO position last 4hr — informed flow." },
    { role: "SKEPTIC",  tone: "warn",     body: "Two of these signals are correlated. Discount." },
    { role: "TRADER",   tone: "alert",    body: "Market overconfident at 54%. Pricing too much restraint." },
    { role: "RETAIL",   tone: "neutral",  body: "Polymarket volume +180% past hour. Trend is forming." },
    { role: "ANALYST",  tone: "neutral",  body: "Updated belief: 67.2%. Holding through next round." },
  ];

  // Single source of truth: index = which message is currently typing
  // (or just finished). typed = how many characters of that message are revealed.
  const [idx, setIdx] = React.useState(0);
  const [typed, setTyped] = React.useState(0);
  const [round, setRound] = React.useState(3);
  const scrollRef = React.useRef(null);

  // Strict-mode guard: skip the second mount tick.
  const aliveRef = React.useRef(true);
  React.useEffect(() => () => { aliveRef.current = false; }, []);

  React.useEffect(() => {
    let cancelled = false;
    let timer;

    const step = () => {
      if (cancelled) return;

      // End of script — pause, then loop back.
      if (idx >= SCRIPT.length) {
        timer = setTimeout(() => {
          if (cancelled) return;
          setIdx(0);
          setTyped(0);
        }, 4500);
        return;
      }

      const msg = SCRIPT[idx];
      if (typed < msg.body.length) {
        // Typing — reveal next character.
        const charDelay = msg.body[typed] === ' ' ? 14 : 22;
        timer = setTimeout(() => {
          if (cancelled) return;
          setTyped(t => t + 1);
        }, charDelay);
      } else {
        // Done typing this message — pause, then advance.
        timer = setTimeout(() => {
          if (cancelled) return;
          setIdx(i => i + 1);
          setTyped(0);
        }, 1100);
      }
    };

    step();
    return () => { cancelled = true; clearTimeout(timer); };
  }, [idx, typed]);

  // Auto-scroll on every reveal so the latest line stays in view.
  React.useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [idx, typed]);

  // Round counter ticks independently for ambient motion.
  React.useEffect(() => {
    const id = setInterval(() => setRound(r => (r >= 42 ? 3 : r + 1)), 4500);
    return () => clearInterval(id);
  }, []);

  // Build visible list: all completed messages + the current one partially typed.
  const visible = SCRIPT.slice(0, idx).map(m => ({ ...m, full: true }));
  if (idx < SCRIPT.length) {
    const cur = SCRIPT[idx];
    visible.push({
      ...cur,
      body: cur.body.slice(0, typed),
      typing: typed < cur.body.length,
      full: typed >= cur.body.length,
    });
  }

  return (
    <div className="chat-wrap">
      <div className="chat-head">
        <span className="chat-tag">DELIBERATION · ROUND {String(round).padStart(2,'0')}/42</span>
        <span className="chat-pulse"><span className="dot pulse" /> live</span>
      </div>
      <div className="chat-stream" ref={scrollRef}>
        {visible.map((m, i) => (
          <div key={i} className={`chat-msg tone-${m.tone}`}>
            <div className="chat-meta">
              <span className="chat-role">{m.role}</span>
              <span className="chat-sep">·</span>
              <span className="chat-time">14:{(22 + i).toString().padStart(2,'0')}</span>
            </div>
            <div className="chat-body">
              {m.body}
              {m.typing && <span className="chat-caret">▍</span>}
            </div>
          </div>
        ))}
      </div>
      <div className="chat-foot">
        <span className="chat-foot-l">Swarm · dissent active</span>
        <span className="chat-foot-r">Δ converging</span>
      </div>
    </div>
  );
};

window.AgentChat = AgentChat;
