// screen-hexsweep.jsx — Interlude between P02 and P03.
// Resource hex tiles drop in a 3-tile stack. Player rotates the active
// stack so its bottom face matches the highlighted need slot, then locks.

const { useState: useStHx, useEffect: useEfHx, useRef: useRfHx, useMemo: useMmHx } = React;

function HexSweepScreen({ run, difficulty, onComplete }) {
  const tMul = window.__sylExtendedTime ? 1.5 : 1;
  const cfg = difficulty === 'recruit' ? { rounds: 6, dropTime: 6 * tMul }
    : difficulty === 'ghost'   ? { rounds: 9, dropTime: 3 * tMul }
    :                            { rounds: 7, dropTime: 4.5 * tMul };

  // Build the round queue: each round = (need, stack of 3 hexes, one of which matches)
  const queue = useMmHx(() => {
    const rounds = [];
    for (let i = 0; i < cfg.rounds; i++) {
      const need = HEX_NEEDS[Math.floor(Math.random() * HEX_NEEDS.length)];
      // Always include at least one matching resource
      const matches = HEX_RESOURCES.filter((r) => r.face === need.id);
      const others  = HEX_RESOURCES.filter((r) => r.face !== need.id);
      const correct = matches[Math.floor(Math.random() * matches.length)];
      const distract = [...others].sort(() => Math.random() - 0.5).slice(0, 2);
      const stack = [correct, ...distract].sort(() => Math.random() - 0.5);
      rounds.push({ need, stack });
    }
    return rounds;
    // eslint-disable-next-line
  }, [difficulty]);

  const [round, setRound] = useStHx(0);
  const [activeIdx, setActiveIdx] = useStHx(0); // 0..2 — which face of the stack is "down"
  const [time, setTime] = useStHx(cfg.dropTime);
  const [feedback, setFeedback] = useStHx(null); // {correct, locked, need}
  const [results, setResults] = useStHx([]);
  const [done, setDone] = useStHx(false);
  const tickRef = useRfHx(null);
  const paused = window.useSylPaused ? window.useSylPaused() : false;

  const cur = queue[round];

  // Per-round timer
  useEfHx(() => {
    if (done || feedback || paused) return;
    if (time === cfg.dropTime) setActiveIdx(0);
    tickRef.current = setInterval(() => {
      setTime((t) => {
        if (t <= 0.1) {
          clearInterval(tickRef.current);
          // Auto-lock with whatever's currently selected
          autoLock();
          return 0;
        }
        return +(t - 0.1).toFixed(1);
      });
    }, 100);
    return () => clearInterval(tickRef.current);
    // eslint-disable-next-line
  }, [round, done, paused]);

  // Reset timer on new round
  useEfHx(() => {
    if (done || feedback) return;
    setTime(cfg.dropTime);
    setActiveIdx(0);
    // eslint-disable-next-line
  }, [round]);

  function rotate(dir) {
    if (feedback || done) return;
    setActiveIdx((i) => (i + dir + 3) % 3);
  }

  function lock() {
    if (feedback || done) return;
    clearInterval(tickRef.current);
    const locked = cur.stack[activeIdx];
    const correct = locked.face === cur.need.id;
    setResults((r) => [...r, { round, correct, lockedId: locked.id, needId: cur.need.id }]);
    setFeedback({ correct, locked, need: cur.need });
    window.sylAnnounce && window.sylAnnounce(
      correct
        ? `Aligned. ${locked.name} matches ${cur.need.label}. Plus 140 XP.`
        : `Misaligned. ${locked.name} does not serve ${cur.need.label}.`,
      true
    );
    setTimeout(() => {
      setFeedback(null);
      const next = round + 1;
      if (next >= queue.length) finalize();
      else setRound(next);
    }, 1300);
  }

  function autoLock() {
    if (feedback || done) return;
    lock();
  }

  function finalize() {
    if (done) return;
    setDone(true);
    const finalResults = results.length === queue.length ? results
      : [...results, ...(feedback ? [{ correct: feedback.correct }] : [])];
    const correct = finalResults.filter((r) => r.correct).length;
    const total = queue.length;
    const accuracy = correct / total;
    const score = correct * 140 + (accuracy >= 0.75 ? 250 : 0);
    setTimeout(() => onComplete({
      protocol: 'hexsweep',
      score, correct, total,
      integrity: Math.round(accuracy * 100),
      badge: accuracy === 1 ? 'PERFECT SWEEP' : null,
    }), 800);
  }

  // Keyboard: ←/→ rotate, Space/Enter lock
  useEfHx(() => {
    const fn = (e) => {
      if (feedback || done) return;
      if (e.key === 'ArrowLeft')  { e.preventDefault(); rotate(-1); }
      if (e.key === 'ArrowRight') { e.preventDefault(); rotate(1); }
      if (e.key === ' ' || e.key === 'Enter') { e.preventDefault(); lock(); }
    };
    window.addEventListener('keydown', fn);
    return () => window.removeEventListener('keydown', fn);
    // eslint-disable-next-line
  }, [feedback, done, activeIdx]);

  const correctSoFar = results.filter((r) => r.correct).length;

  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(170,255,0,.25)', paddingBottom: 14 }}>
        <div>
          <div className="t-mono" style={{ fontSize: 11, color: 'var(--neon-lime)',
            letterSpacing: '0.18em', marginBottom: 6 }}>
            ◢ INTERLUDE / HEX_SWEEP
          </div>
          <div style={{ fontFamily: 'Orbitron', fontWeight: 800, fontSize: 30,
            letterSpacing: '0.04em', color: 'var(--ink-100)' }}>
            ALIGN THE RESOURCE GRID
          </div>
          <div style={{ fontSize: 12, color: 'var(--ink-60)', marginTop: 6, maxWidth: 720, lineHeight: 1.5 }}>
            A need is broadcasting from the slot below. Rotate the dropping hex stack so the
            matching face locks into place. ← / → to rotate · SPACE to lock.
          </div>
        </div>
        <div style={{ textAlign: 'right' }}>
          <div className="t-mono" style={{ fontSize: 10, color: 'var(--ink-60)', letterSpacing: '0.14em' }}>
            ROUND
          </div>
          <div style={{ fontFamily: 'Orbitron', fontWeight: 800, fontSize: 36,
            color: 'var(--neon-lime)', lineHeight: 1, letterSpacing: '0.04em' }}>
            {Math.min(round + 1, queue.length)}<span style={{ color: 'var(--ink-40)', fontSize: 22 }}>/{queue.length}</span>
          </div>
          <div className="t-mono" style={{ fontSize: 10, color: 'var(--ink-60)',
            letterSpacing: '0.14em', marginTop: 6 }}>
            HITS · <b style={{ color: 'var(--neon-lime)' }}>{correctSoFar}</b>
          </div>
        </div>
      </div>

      {/* Timer bar */}
      <div style={{ height: 4, background: 'rgba(170,255,0,.1)', position: 'relative', overflow: 'hidden' }}>
        <div style={{
          position: 'absolute', left: 0, top: 0, height: '100%',
          width: `${Math.max(0, (time / cfg.dropTime) * 100)}%`,
          background: time < 1.5 ? 'var(--neon-magenta)' : 'var(--neon-lime)',
          boxShadow: `0 0 12px ${time < 1.5 ? 'var(--neon-magenta)' : 'var(--neon-lime)'}`,
          transition: 'width .1s linear, background .2s',
        }} />
      </div>

      {/* Play area */}
      {cur && (
        <div style={{ flex: 1, display: 'grid',
          gridTemplateColumns: '1fr 1.4fr 1fr', gap: 32, alignItems: 'center', minHeight: 0 }}>

          {/* Left: stack preview */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 8, alignItems: 'center' }}>
            <div className="t-mono" style={{ fontSize: 10, color: 'var(--ink-60)',
              letterSpacing: '0.14em', marginBottom: 8 }}>// STACK</div>
            {cur.stack.map((tile, i) => {
              const need = HEX_NEEDS.find((n) => n.id === tile.face);
              const active = i === activeIdx;
              return (
                <div key={tile.id + i} style={{
                  width: 200, padding: '10px 14px',
                  border: `1px solid ${active ? need.accent : 'rgba(255,255,255,.1)'}`,
                  background: active ? `${need.accent}18` : 'rgba(0,0,0,.3)',
                  display: 'flex', alignItems: 'center', gap: 10,
                  opacity: active ? 1 : 0.4,
                  transition: 'all .2s',
                  boxShadow: active ? `0 0 14px ${need.accent}66` : 'none',
                }}>
                  <div style={{
                    width: 26, height: 26,
                    color: need.accent, background: `${need.accent}22`,
                    border: `1px solid ${need.accent}66`,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontFamily: 'Orbitron', fontWeight: 800, fontSize: 14,
                  }}>{need.glyph}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div className="t-mono" style={{ fontSize: 10, letterSpacing: '0.12em',
                      color: active ? need.accent : 'var(--ink-40)' }}>{tile.name}</div>
                  </div>
                  {active && (
                    <div className="t-mono" style={{ fontSize: 9, color: need.accent,
                      letterSpacing: '0.18em' }}>◀▶</div>
                  )}
                </div>
              );
            })}
            <div className="t-mono" style={{ fontSize: 9, color: 'var(--ink-40)',
              letterSpacing: '0.14em', marginTop: 6 }}>
              ← ROTATE → · SPACE LOCK
            </div>
          </div>

          {/* Center: active hex floating above slot */}
          <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 18 }}>
            {(() => {
              const tile = cur.stack[activeIdx];
              const need = HEX_NEEDS.find((n) => n.id === tile.face);
              const isMatch = tile.face === cur.need.id;
              const lockedColor = feedback ? (feedback.correct ? 'var(--neon-lime)' : 'var(--neon-magenta)') : need.accent;
              return (
                <>
                  <Hex glyph={need.glyph} label={tile.name} accent={lockedColor}
                    pulse={!feedback} dropping={!feedback} matched={feedback?.correct} />
                  {/* Drop trail */}
                  <div style={{ height: 18, width: 2,
                    background: `linear-gradient(180deg, ${lockedColor}, transparent)`,
                    boxShadow: `0 0 10px ${lockedColor}`,
                  }} />
                  <Hex glyph={cur.need.glyph} label={cur.need.label} accent={cur.need.accent}
                    isSlot pulse={!feedback} matched={feedback?.correct} />
                </>
              );
            })()}
          </div>

          {/* Right: rotate buttons + lock */}
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <button className="btn btn-ghost" onClick={() => rotate(-1)} disabled={!!feedback}
              aria-label="Rotate stack left (left arrow key)"><span aria-hidden="true">◂ </span>ROTATE L</button>
            <button className="btn btn-ghost" onClick={() => rotate(1)} disabled={!!feedback}
              aria-label="Rotate stack right (right arrow key)">ROTATE R<span aria-hidden="true"> ▸</span></button>
            <button className="btn btn-primary" onClick={lock} disabled={!!feedback}
              aria-label="Lock current face into the need slot (space or enter)"
              style={{ background: 'linear-gradient(180deg, var(--neon-lime), #6bb800)' }}>
              <span aria-hidden="true">◢ </span>LOCK
            </button>
            <div className="panel" style={{ padding: 12, marginTop: 12, gap: 6,
              display: 'flex', flexDirection: 'column', borderColor: `${cur.need.accent}33` }}>
              <div className="t-mono" style={{ fontSize: 9, color: 'var(--ink-60)',
                letterSpacing: '0.14em' }}>// SLOT BROADCAST</div>
              <div style={{ fontFamily: 'Orbitron', fontWeight: 700, fontSize: 14,
                color: cur.need.accent, letterSpacing: '0.04em' }}>
                {cur.need.glyph} {cur.need.label}
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Feedback */}
      {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
              ? `✓ ALIGNED → ${feedback.locked.name} matches ${feedback.need.label}`
              : `✗ MISALIGNED. ${feedback.locked.name} does not serve ${feedback.need.label}.`}
          </span>
          <span style={{ color: 'var(--ink-60)' }}>
            {feedback.correct ? '+ 140 XP' : '+ 0 XP'}
          </span>
        </div>
      )}
    </div>
  );
}

// ── Hex shape ────────────────────────────────────────────────────────────
function Hex({ glyph, label, accent, isSlot, pulse, dropping, matched }) {
  const size = isSlot ? 110 : 90;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 8 }}>
      <div style={{
        width: size, height: size * 1.15, position: 'relative',
        animation: dropping ? 'hexDrop .4s ease-out' : pulse ? 'hexPulse 1.6s ease-in-out infinite' : 'none',
      }}>
        <svg viewBox="0 0 100 115" width={size} height={size * 1.15}
          style={{ position: 'absolute', inset: 0, overflow: 'visible' }}>
          <polygon points="50,4 94,29 94,86 50,111 6,86 6,29"
            fill={isSlot ? `${accent}10` : `${accent}22`}
            stroke={accent}
            strokeWidth={isSlot ? 2 : 3}
            style={{
              filter: matched ? `drop-shadow(0 0 18px ${accent})`
                : `drop-shadow(0 0 8px ${accent}88)`,
              transition: 'filter .3s',
            }}
          />
          {isSlot && (
            <polygon points="50,16 84,33 84,82 50,99 16,82 16,33"
              fill="none" stroke={accent} strokeOpacity="0.3" strokeDasharray="3 4" />
          )}
        </svg>
        <div style={{
          position: 'absolute', inset: 0, display: 'flex',
          alignItems: 'center', justifyContent: 'center',
          fontFamily: 'Orbitron', fontWeight: 800,
          fontSize: isSlot ? 38 : 32, color: accent,
          textShadow: `0 0 12px ${accent}`,
        }}>
          {glyph}
        </div>
      </div>
      <div className="t-mono" style={{ fontSize: 10, color: accent,
        letterSpacing: '0.14em', textAlign: 'center', maxWidth: 140 }}>
        {label}
      </div>
      <style>{`
        @keyframes hexPulse {
          0%, 100% { transform: scale(1); }
          50% { transform: scale(1.05); }
        }
        @keyframes hexDrop {
          0% { transform: translateY(-30px); opacity: 0.4; }
          100% { transform: translateY(0); opacity: 1; }
        }
      `}</style>
    </div>
  );
}

window.HexSweepScreen = HexSweepScreen;
