// Console.jsx — the animated "live collaboration" centerpiece.

function buildSchedule() {
  const strip = s => s.replace(/<[^>]+>/g, '');
  let t = 0;
  const schedule = TRANSMISSIONS.map((tx, i) => {
    const len = strip(tx.text).length;
    const gap = tx.type === 'route' ? 480 : Math.min(1200, Math.max(640, 460 + len * 6));
    const read = tx.type === 'route' ? 840
      : tx.type === 'verdict' ? 4400
      : Math.min(3600, Math.max(1600, 1200 + len * 20));
    const typingFrom = t;
    t += gap;
    const showAt = t;
    t += read;
    return { ...tx, idx: i, typingFrom, showAt };
  });
  return { schedule, total: t + 1600 };
}

const fmtT = (ms) => {
  const s = Math.max(0, Math.floor(ms / 1000));
  return `T+${String(Math.floor(s / 60)).padStart(2, '0')}:${String(s % 60).padStart(2, '0')}`;
};

const RAIL_ORDER = ['orch', 'marcus', 'calloway', 'sable', 'ada'];

function Transmission({ tx }) {
  const a = AGENTS[tx.agent];
  const Icon = Icons[a.icon];
  const cls = `tx ${tx.type}`;
  return (
    <div className={cls} style={{ '--ag-c': a.color }}>
      <div className="tx-avatar"><Icon /></div>
      <div className="tx-main">
        {tx.type === 'route' && (
          <div className="tx-arrow">{a.short || a.name} <Icons.arrowRight /> <b>{AGENTS[tx.to].short}</b></div>
        )}
        {(tx.type === 'challenge' || tx.type === 'revision') && tx.tag && (
          <span className="tx-tag">{tx.tag}</span>
        )}
        <div className="tx-head">
          <span className="tx-name">{a.name}</span>
          <span className="tx-role">{a.role}</span>
          <span className="tx-time">{fmtT(tx.showAt)}</span>
        </div>
        <div className="tx-body" dangerouslySetInnerHTML={{ __html: tx.text }} />
        {tx.type === 'verdict' && tx.verdict && (
          <div className="verdict-badge">
            <Icons.check /> RECOMMENDATION: {tx.verdict.call}
            <span className="pw">· {tx.verdict.pwin} · {tx.verdict.ptw}</span>
          </div>
        )}
      </div>
    </div>
  );
}

function TypingBubble({ tx }) {
  const a = AGENTS[tx.agent];
  const Icon = Icons[a.icon];
  return (
    <div className="tx typing" style={{ '--ag-c': a.color }}>
      <div className="tx-avatar"><Icon /></div>
      <div className="tx-main">
        <div className="tx-head">
          <span className="tx-name">{a.name}</span>
          <span className="tx-role">{a.role}</span>
        </div>
        <div className="tx-body">
          <span className="typing-dot"></span><span className="typing-dot"></span><span className="typing-dot"></span>
        </div>
      </div>
    </div>
  );
}

function Console({ speed, autoplay, density }) {
  const { schedule, total } = React.useMemo(buildSchedule, []);
  const [clock, setClock] = React.useState(0);
  const [playing, setPlaying] = React.useState(false);
  const [started, setStarted] = React.useState(false);
  const speedRef = React.useRef(speed);
  const playingRef = React.useRef(false);
  const clockRef = React.useRef(0);
  const feedRef = React.useRef(null);
  const sectionRef = React.useRef(null);
  const draggingRef = React.useRef(false);

  React.useEffect(() => { speedRef.current = speed; }, [speed]);
  React.useEffect(() => { playingRef.current = playing; }, [playing]);
  React.useEffect(() => { clockRef.current = clock; }, [clock]);

  // clock driven by setInterval + performance.now() deltas
  // (robust even when the tab is backgrounded and rAF is paused)
  React.useEffect(() => {
    let last = performance.now();
    const id = setInterval(() => {
      const now = performance.now();
      const dt = now - last; last = now;
      if (playingRef.current && !draggingRef.current) {
        let next = clockRef.current + dt * speedRef.current;
        if (next >= total) next = 0;
        clockRef.current = next;
        setClock(next);
      }
    }, 1000 / 60);
    return () => clearInterval(id);
  }, [total]);

  // autoplay when scrolled into view (first time)
  React.useEffect(() => {
    if (!autoplay || started) return;
    const el = sectionRef.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) { setPlaying(true); setStarted(true); io.disconnect(); }
      });
    }, { threshold: 0.25 });
    io.observe(el);
    return () => io.disconnect();
  }, [autoplay, started]);

  // derived view
  let shownCount = 0, typingIdx = -1;
  for (const s of schedule) {
    if (clock >= s.showAt) shownCount++;
    else if (clock >= s.typingFrom && typingIdx === -1) typingIdx = s.idx;
  }
  const shown = schedule.slice(0, shownCount);
  const activeTx = typingIdx >= 0 ? schedule[typingIdx] : schedule[Math.max(0, shownCount - 1)];
  const done = shownCount >= schedule.length;

  // active rail agent + status
  let activeAgent = activeTx ? activeTx.agent : 'orch';
  let activeStatus = activeTx ? (activeTx.status || 'WORKING') : 'STANDBY';
  if (activeTx && activeTx.type === 'challenge') { activeAgent = activeTx.to; activeStatus = 'UNDER REVIEW'; }

  const spokeKeys = new Set(shown.filter(s => ['msg', 'revision', 'verdict'].includes(s.type)).map(s => s.agent));
  const passedGates = new Set(shown.filter(s => s.gate).map(s => s.gate));

  const railStatus = (key) => {
    if (key === activeAgent && started) return activeStatus;
    if (key === 'orch') return done ? 'COMPLETE' : (started ? 'COORDINATING' : 'STANDBY');
    if (spokeKeys.has(key)) return 'CLEARED';
    return 'IDLE';
  };

  const currentPhase = activeTx ? activeTx.phase : 0;

  // auto-scroll feed
  React.useEffect(() => {
    if (feedRef.current && !draggingRef.current) {
      feedRef.current.scrollTop = feedRef.current.scrollHeight;
    }
  }, [shownCount, typingIdx]);

  // scrubbing
  const seekFromEvent = (e) => {
    const bar = e.currentTarget.getBoundingClientRect ? e.currentTarget : e.target;
    const rect = (scrubElRef.current || bar).getBoundingClientRect();
    const frac = Math.min(1, Math.max(0, (e.clientX - rect.left) / rect.width));
    const next = frac * total;
    clockRef.current = next; setClock(next);
  };
  const scrubElRef = React.useRef(null);
  const onScrubDown = (e) => {
    draggingRef.current = true; setStarted(true); seekFromEvent(e);
    const move = (ev) => { if (draggingRef.current) seekFromEvent(ev); };
    const up = () => { draggingRef.current = false; window.removeEventListener('pointermove', move); window.removeEventListener('pointerup', up); };
    window.addEventListener('pointermove', move);
    window.addEventListener('pointerup', up);
  };

  const togglePlay = () => { setStarted(true); setPlaying(p => !p); };
  const restart = () => { clockRef.current = 0; setClock(0); setStarted(true); setPlaying(true); };

  const S = window.SOLICITATION;
  const frac = clock / total;

  return (
    <section id="console" className="console-section" ref={sectionRef}>
      <div className="wrap" style={{ textAlign: 'center' }}>
        <div className="reveal" style={{ display: 'inline-block', textAlign: 'left', maxWidth: 760 }}>
          <SectionTag>The Collaboration</SectionTag>
          <h2 className="section-title">Watch the workforce work<span style={{ color: 'var(--accent)' }}>.</span></h2>
          <p className="section-desc">
            A live solicitation enters the system. The Orchestrator assesses it, activates the right
            specialists, and the pod deliberates in the open — handing off, challenging weak points,
            and revising until every gate clears. This is the part no single model does.
          </p>
        </div>
      </div>

      <div className="console-shell reveal">
        {/* top bar: solicitation context */}
        <div className="console-topbar">
          <div className="solbar">
            <div className="solbar-id">
              <span className="live"><span className="pulse"></span>{done ? 'COMPLETE' : 'LIVE'}</span>
              <span className="solbar-title">{S.agencyShort} · {S.title}</span>
            </div>
            <div className="solbar-meta">
              <div className="sol-meta"><span className="k">Solicitation</span><span className="v">{S.id}</span></div>
              <div className="sol-meta"><span className="k">Ceiling</span><span className="v accent">{S.ceiling}</span></div>
              <div className="sol-meta"><span className="k">Vehicle</span><span className="v">{S.vehicle}</span></div>
              <div className="sol-meta"><span className="k">Response Due</span><span className="v">{S.due}</span></div>
            </div>
          </div>
          {/* phase stepper */}
          <div className="stepper">
            {PHASES.map((p, i) => {
              const state = done ? 'done' : i < currentPhase ? 'done' : i === currentPhase && started ? 'active' : '';
              return (
                <div className={`step ${state}`} key={p.n}>
                  <div className="step-n">{p.n}</div>
                  <div className="step-label">{p.label}</div>
                  <div className="step-bar"><i style={{ width: state === 'active' && !done ? '55%' : '' }}></i></div>
                </div>
              );
            })}
          </div>
        </div>

        {/* body: rail + feed */}
        <div className="console-body">
          <aside className="console-rail">
            <div className="rail-head">Active Workforce</div>
            {RAIL_ORDER.map(key => {
              const a = AGENTS[key]; const Icon = Icons[a.icon];
              const isActive = key === activeAgent && started && !done;
              return (
                <div className={`rail-agent${isActive ? ' active' : ''}`} key={key} style={{ '--ag-c': a.color }}>
                  <div className="rail-dot"><Icon /></div>
                  <div className="rail-info">
                    <span className="rail-name">{a.short}</span>
                    <span className="rail-status">{railStatus(key)}</span>
                  </div>
                </div>
              );
            })}
            <div className="rail-spacer"></div>
            <div className="rail-gates">
              <div className="rail-head" style={{ padding: '0 0 10px' }}>Quality Gates</div>
              {GATES.map(g => {
                const passed = passedGates.has(g.key);
                const GIcon = Icons[g.key === 'critic' ? 'scale' : g.key === 'redteam' ? 'redteam' : 'compliance'];
                return (
                  <div className={`rail-gate${passed ? ' passed' : ''}`} key={g.key}>
                    <span className="gicon"><GIcon /></span>
                    <span className="glabel">{g.label}</span>
                    <span className="gstate">{passed ? '✓ PASS' : 'PENDING'}</span>
                  </div>
                );
              })}
            </div>
          </aside>

          <div className="console-feed" ref={feedRef}>
            {shown.map(tx => <Transmission key={tx.idx} tx={tx} />)}
            {typingIdx >= 0 && started && <TypingBubble key={`typing-${typingIdx}`} tx={schedule[typingIdx]} />}
            {!started && (
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: 380, flexDirection: 'column', gap: 18, textAlign: 'center', color: 'var(--text-secondary)' }}>
                <div style={{ fontFamily: 'var(--font-display)', fontSize: '1.3rem', color: 'var(--text-white)', letterSpacing: '-0.02em' }}>Pod on standby.</div>
                <div style={{ fontSize: '0.9rem', maxWidth: 360, lineHeight: 1.6 }}>Press play to release the solicitation into the workforce and watch the seven-phase deliberation unfold.</div>
                <button className="ctrl-btn" onClick={togglePlay} style={{ width: 52, height: 52, marginTop: 6 }}><Icons.play /></button>
              </div>
            )}
          </div>
        </div>

        {/* speaker-style narration caption */}
        {started && (
          <div className="console-caption">
            <div className="cap-rail" aria-hidden="true"></div>
            <div className="cap-content" key={currentPhase}>
              <div className="cap-eyebrow">
                Narration · Phase {PHASES[currentPhase].n} <span className="cap-sep">/</span> {PHASES[currentPhase].label}
              </div>
              <p className="cap-text">{PHASES[currentPhase].caption}</p>
            </div>
          </div>
        )}

        {/* controls */}
        <div className="console-controls">
          <button className="ctrl-btn" onClick={togglePlay} aria-label={playing ? 'Pause' : 'Play'}>
            {playing ? <Icons.pause /> : <Icons.play />}
          </button>
          <button className="ctrl-restart" onClick={restart} aria-label="Restart"><Icons.restart /></button>
          <div className="scrub" ref={scrubElRef} onPointerDown={onScrubDown}>
            <div className="scrub-fill" style={{ width: `${frac * 100}%` }}></div>
            <div className="scrub-head" style={{ left: `${frac * 100}%` }}></div>
          </div>
          <div className="ctrl-time">{fmtT(clock)} / {fmtT(total)}</div>
        </div>
      </div>
    </section>
  );
}
window.Console = Console;
