// screen-board.jsx
// Mission Board — the squad's map through the network.
// Shows 3 protocol nodes + start/end nodes, connected by data lines.
// Players "select" the next available node to launch into a protocol.
// Re-shown between protocols so progress is visible.

const { useState: useStBd, useEffect: useEfBd } = React;

const BOARD_NODES = [
  { id: 'entry',      label: 'UPLINK',     sub: 'Entry Point',         x: 8,  y: 50, kind: 'entry' },
  { id: 'datastream', label: 'PROTOCOL 01', sub: 'Datastream Decode',  x: 28, y: 22, kind: 'protocol', accent: 'var(--neon-cyan)' },
  { id: 'heist',      label: 'PROTOCOL 02', sub: 'Deadline Heist',     x: 52, y: 65, kind: 'protocol', accent: 'var(--neon-magenta)' },
  { id: 'policy',     label: 'PROTOCOL 03', sub: 'Policy Firewall',    x: 76, y: 30, kind: 'protocol', accent: 'var(--neon-yellow)' },
  { id: 'mainframe',  label: 'MAINFRAME',  sub: 'Override Target',     x: 92, y: 60, kind: 'goal' },
];

const BOARD_EDGES = [
  ['entry', 'datastream'],
  ['datastream', 'heist'],
  ['heist', 'policy'],
  ['policy', 'mainframe'],
];

// Map phase ids to board node ids
const PHASE_NODE = { datastream: 'datastream', heist: 'heist', policy: 'policy' };

function BoardScreen({ run, scores, nextPhase, onLaunch }) {
  const completed = new Set();
  if (scores.datastream != null) completed.add('datastream');
  if (scores.heist != null) completed.add('heist');
  if (scores.policy != null) completed.add('policy');

  const activeNodeId = PHASE_NODE[nextPhase];
  const cumulative = (scores.datastream || 0) + (scores.heist || 0) + (scores.policy || 0);

  // Pulsing scan-line on the active edge
  const [pulse, setPulse] = useStBd(0);
  useEfBd(() => {
    const t = setInterval(() => setPulse((p) => (p + 1) % 1000), 32);
    return () => clearInterval(t);
  }, []);

  const nodeById = Object.fromEntries(BOARD_NODES.map(n => [n.id, n]));

  function isEdgeLive(from, to) {
    // Edge is "live" (animated) when 'from' is completed (or entry) and 'to' is the active node
    const fromDone = from === 'entry' || completed.has(from);
    return fromDone && to === activeNodeId;
  }
  function isEdgeDone(from, to) {
    if (from === 'entry') return completed.has(to);
    return completed.has(from) && (completed.has(to) || (to === 'mainframe' && completed.size === 3));
  }

  return (
    <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minHeight: 0, padding: '24px 48px 32px' }}>
      <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', marginBottom: 16 }}>
        <div>
          <div className="chip" style={{ marginBottom: 10 }}>◆ NETWORK MAP // ACADEMY MAINFRAME</div>
          <h2 className="t-display glow-cyan" style={{ fontSize: 32, letterSpacing: '0.04em' }}>MISSION BOARD</h2>
          <div style={{ color: 'var(--ink-60)', fontSize: 12, marginTop: 6 }}>
            ◇ Squad <b style={{ color: 'var(--neon-cyan)' }}>{run.squadName}</b> — route the run through three protocols. Tap the active node to engage.
          </div>
        </div>
        <div style={{ display: 'flex', gap: 24 }}>
          <Stat label="PROTOCOLS" value={`${completed.size}/3`} accent="var(--neon-cyan)" />
          <Stat label="XP BANKED" value={cumulative.toLocaleString()} accent="var(--neon-yellow)" />
        </div>
      </div>

      {/* Map */}
      <div className="panel" style={{ flex: 1, position: 'relative', overflow: 'hidden', minHeight: 360 }}>
        {/* Background grid texture */}
        <svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none' }}>
          <defs>
            <pattern id="bgrid" width="32" height="32" patternUnits="userSpaceOnUse">
              <path d="M 32 0 L 0 0 0 32" fill="none" stroke="rgba(0,234,255,.06)" strokeWidth="1" />
            </pattern>
            <radialGradient id="hotspot" cx="50%" cy="50%" r="50%">
              <stop offset="0%" stopColor="rgba(255,45,149,.12)" />
              <stop offset="100%" stopColor="rgba(255,45,149,0)" />
            </radialGradient>
          </defs>
          <rect width="100%" height="100%" fill="url(#bgrid)" />
          <rect width="100%" height="100%" fill="url(#hotspot)" />
        </svg>

        {/* Edges (SVG, percentage-based) */}
        <svg viewBox="0 0 100 100" preserveAspectRatio="none" style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', overflow: 'visible' }}>
          {BOARD_EDGES.map(([a, b]) => {
            const A = nodeById[a], B = nodeById[b];
            const live = isEdgeLive(a, b);
            const done = isEdgeDone(a, b);
            const stroke = done ? 'var(--neon-lime)' : live ? 'var(--neon-cyan)' : 'rgba(0,234,255,.18)';
            const dashOffset = live ? -((pulse * 0.5) % 12) : 0;
            return (
              <g key={`${a}-${b}`}>
                <line x1={A.x} y1={A.y} x2={B.x} y2={B.y}
                  stroke={stroke} strokeWidth={done ? 0.4 : 0.3}
                  vectorEffect="non-scaling-stroke"
                  style={{ filter: done || live ? `drop-shadow(0 0 4px ${stroke})` : 'none' }}
                />
                {live && (
                  <line x1={A.x} y1={A.y} x2={B.x} y2={B.y}
                    stroke="var(--neon-cyan)" strokeWidth={0.4}
                    strokeDasharray="2 4" strokeDashoffset={dashOffset}
                    vectorEffect="non-scaling-stroke" opacity="0.9"
                  />
                )}
              </g>
            );
          })}
        </svg>

        {/* Nodes */}
        {BOARD_NODES.map((node) => {
          const isActive = node.id === activeNodeId;
          const isDone = completed.has(node.id);
          const isGoal = node.kind === 'goal';
          const isEntry = node.kind === 'entry';
          const reachable = isGoal && completed.size === 3;

          let accent = node.accent || 'var(--neon-cyan)';
          if (isGoal) accent = reachable ? 'var(--neon-lime)' : 'var(--ink-40)';
          if (isEntry) accent = 'var(--neon-cyan)';

          const status = isDone ? 'COMPLETE' : isActive ? 'AVAILABLE' : isGoal && reachable ? 'AWAITING' : isEntry ? 'BREACHED' : 'LOCKED';

          const gain = scores[node.id];

          return (
            <button
              key={node.id}
              disabled={!isActive}
              onClick={() => isActive && onLaunch && onLaunch()}
              style={{
                position: 'absolute',
                left: `${node.x}%`, top: `${node.y}%`,
                transform: 'translate(-50%, -50%)',
                background: 'transparent', border: 0, padding: 0,
                cursor: isActive ? 'pointer' : 'default',
                display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8,
              }}
            >
              {/* Hex node */}
              <div style={{
                position: 'relative',
                width: isGoal ? 96 : isEntry ? 64 : 84, height: isGoal ? 96 : isEntry ? 64 : 84,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {/* Pulse ring on active */}
                {isActive && (
                  <div style={{
                    position: 'absolute', inset: -8,
                    border: `2px solid ${accent}`,
                    clipPath: 'polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%)',
                    animation: 'boardpulse 1.6s ease-out infinite',
                    opacity: .6,
                  }} />
                )}
                <div style={{
                  position: 'absolute', inset: 0,
                  background: isDone
                    ? `linear-gradient(135deg, ${accent}28, ${accent}06)`
                    : isActive
                      ? `linear-gradient(135deg, ${accent}40, ${accent}10)`
                      : 'rgba(0,0,0,.4)',
                  border: `1.5px solid ${isDone || isActive ? accent : 'rgba(0,234,255,.25)'}`,
                  clipPath: 'polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%)',
                  boxShadow: isActive ? `0 0 24px ${accent}88, inset 0 0 16px ${accent}33` : isDone ? `0 0 12px ${accent}66` : 'none',
                  transition: 'all .3s',
                }} />
                <div style={{ position: 'relative', textAlign: 'center', padding: 8 }}>
                  {isDone ? (
                    <div className="t-display" style={{ fontSize: 24, color: accent, textShadow: `0 0 8px ${accent}` }}>◉</div>
                  ) : isActive ? (
                    <div className="t-display" style={{ fontSize: 22, color: accent, textShadow: `0 0 8px ${accent}` }}>◇</div>
                  ) : isEntry ? (
                    <div className="t-display" style={{ fontSize: 14, color: accent, letterSpacing: '0.1em' }}>{'>'}_</div>
                  ) : isGoal ? (
                    <div className="t-display" style={{ fontSize: 18, color: accent, letterSpacing: '0.04em' }}>⌬</div>
                  ) : (
                    <div className="t-display" style={{ fontSize: 14, color: 'var(--ink-40)' }}>⊘</div>
                  )}
                </div>
              </div>

              {/* Label */}
              <div style={{ textAlign: 'center', whiteSpace: 'nowrap' }}>
                <div className="t-display" style={{
                  fontSize: 11, letterSpacing: '0.14em',
                  color: isDone || isActive ? accent : 'var(--ink-60)',
                  textShadow: isActive ? `0 0 8px ${accent}66` : 'none',
                }}>
                  {node.label}
                </div>
                <div style={{ fontSize: 9, color: 'var(--ink-60)', letterSpacing: '0.12em', marginTop: 2 }}>
                  {node.sub}
                </div>
                <div style={{
                  fontSize: 9, marginTop: 4, letterSpacing: '0.18em',
                  color: isDone ? 'var(--neon-lime)' : isActive ? 'var(--neon-yellow)' : 'var(--ink-40)',
                }}>
                  {gain != null ? `+${gain.toLocaleString()} XP` : `◇ ${status}`}
                </div>
              </div>
            </button>
          );
        })}

        {/* Corner readouts */}
        <div style={{ position: 'absolute', top: 16, right: 20, fontSize: 9, color: 'var(--ink-60)', letterSpacing: '0.18em', textAlign: 'right' }}>
          <div>SECTION-04 / SPRING-26</div>
          <div style={{ color: 'var(--neon-lime)', marginTop: 2 }}>● UPLINK STABLE</div>
        </div>
        <div style={{ position: 'absolute', bottom: 16, left: 20, fontSize: 9, color: 'var(--ink-60)', letterSpacing: '0.18em' }}>
          ◇ MAP_ID/0xA399 · LAYER 03/12
        </div>
      </div>

      {/* Squad strip + launch */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginTop: 16 }}>
        <div style={{ display: 'flex', gap: 8 }}>
          {[run.role, ...run.teammates].map((tm, i) => (
            <div key={i} style={{
              width: 36, height: 36, background: `${tm.accent}22`, border: `1px solid ${tm.accent}aa`,
              color: tm.accent, display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'Orbitron', fontWeight: 800, fontSize: 16,
              textShadow: `0 0 6px ${tm.accent}`,
            }}>{tm.glyph}</div>
          ))}
        </div>
        <div style={{ flex: 1, fontSize: 11, color: 'var(--ink-60)', letterSpacing: '0.04em' }}>
          {completed.size === 0 && '◇ All systems green. Launch the first protocol when ready.'}
          {completed.size === 1 && '◇ One node down. The mainframe noticed. Stay sharp.'}
          {completed.size === 2 && '◇ Two of three. Final firewall ahead.'}
          {completed.size === 3 && '◇ All protocols clear. Override the mainframe to extract.'}
        </div>
        <button
          className="btn btn-primary"
          onClick={onLaunch}
          disabled={completed.size === 3}
        >
          {completed.size === 3 ? '◢ EXTRACTING…' : `► ENGAGE ${activeNodeId?.toUpperCase()}`}
        </button>
      </div>
    </div>
  );
}

// Inject pulse animation
const __boardStyle = document.createElement('style');
__boardStyle.textContent = `
  @keyframes boardpulse {
    0% { transform: scale(1); opacity: .6; }
    100% { transform: scale(1.4); opacity: 0; }
  }
`;
document.head.appendChild(__boardStyle);

window.BoardScreen = BoardScreen;
