import { useState, useEffect, useRef } from 'react';
import treeBg from '../assets/tree_bg_svg.svg';
import { useNavigate, useLocation } from 'react-router-dom';

const API = import.meta.env.VITE_API_URL;
const STAGE_SIZE = 11;

function fmtDuration(ms) {
  const s = Math.floor(ms / 1000);
  return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
}

function GlobalStyles() {
  return (
    <style>{`
      @keyframes questionEnter { from{opacity:0;transform:translateX(20px)} to{opacity:1;transform:translateX(0)} }
      @keyframes answerPulse { 0%{transform:scale(1)} 50%{transform:scale(0.97)} 100%{transform:scale(1)} }
      @keyframes submitGlow { from{box-shadow:0 0 8px #ff69b4aa} to{box-shadow:0 0 22px #ff69b4,0 0 40px #ff69b466} }
      @keyframes bubblePop { 0%{transform:scale(0.7)} 70%{transform:scale(1.1)} 100%{transform:scale(1)} }
      @keyframes titleFadeDown { from{opacity:0;transform:translateY(-16px)} to{opacity:1;transform:translateY(0)} }
      @keyframes statsFadeUp { from{opacity:0;transform:translateY(12px)} to{opacity:1;transform:translateY(0)} }
      @keyframes spin { to{transform:rotate(360deg);} }
    `}</style>
  );
}

// ── ProgressStrip ──────────────────────────────────────────────
function ProgressStrip({ total, current, answers, onJump }) {
  const [fillCounts, setFillCounts] = useState({});
  const prevAnswersRef = useRef({});

  useEffect(() => {
    const updates = {};
    for (let qi = 0; qi < total; qi++) {
      if (answers[qi] != null && prevAnswersRef.current[qi] == null) updates[qi] = true;
    }
    if (Object.keys(updates).length > 0) {
      setFillCounts(prev => {
        const next = { ...prev };
        for (const qi of Object.keys(updates)) next[Number(qi)] = (prev[Number(qi)] || 0) + 1;
        return next;
      });
    }
    prevAnswersRef.current = answers;
  }, [answers, total]);

  const items = [];
  for (let qi = 0; qi < total; qi++) {
    const active = qi === current;
    const filled = answers[qi] != null;
    const popCount = fillCounts[qi] || 0;
    items.push(
      <button
        key={`b-${qi}-${popCount}`}
        onClick={() => onJump && onJump(qi)}
        style={{
          width: 36, height: 36, borderRadius: '50%',
          border: `2px solid ${filled || active ? '#1a73e8' : '#ccc'}`,
          background: filled ? '#1a73e8' : active ? '#e8f0fe' : '#fff',
          color: filled ? '#fff' : active ? '#1a73e8' : '#aaa',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontSize: 13, fontWeight: 700, fontFamily: 'system-ui,-apple-system,sans-serif',
          flexShrink: 0, cursor: 'pointer', padding: 0, boxSizing: 'border-box',
          transition: 'background 0.15s, border-color 0.15s',
          animation: popCount > 0 ? 'bubblePop 0.25s ease-out' : 'none',
        }}
      >
        {qi + 1}
      </button>
    );
    if (qi < total - 1) {
      items.push(
        <div
          key={`l-${qi}`}
          style={{ flex: 1, height: 3, minWidth: 2, background: answers[qi] != null ? '#1a73e8' : '#ddd' }}
        />
      );
    }
  }
  return (
    <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'nowrap', width: '100%' }}>
      {items}
    </div>
  );
}

const BTN = {
  padding: '8px 22px', borderRadius: 999, fontFamily: 'system-ui,sans-serif',
  fontSize: 14, fontWeight: 600, cursor: 'pointer',
  border: '1px solid #b6d8f5', background: '#e8f4fd', color: '#1a73e8',
};

const NAV_BTN = {
  padding: '14px 40px', borderRadius: 999, fontFamily: 'system-ui,sans-serif',
  fontSize: 17, fontWeight: 600, cursor: 'pointer',
  border: '1.5px solid #b6d8f5', background: '#e8f4fd', color: '#1a73e8',
};

const QUIT_BTN = {
  padding: '14px 28px', borderRadius: 999, fontFamily: 'system-ui,sans-serif',
  fontSize: 14, fontWeight: 600, cursor: 'pointer',
  border: '1.5px solid #e57373', background: '#fff', color: '#c62828',
};

const WRAP = { display: 'flex', flexDirection: 'column', minHeight: '100vh', background: '#fff', fontFamily: 'system-ui,sans-serif' };

// ── Screens ────────────────────────────────────────────────────

function StageIntro({ stage, onNext }) {
  return (
    <div style={{ display: 'flex', minHeight: '100vh', background: '#fff', fontFamily: 'system-ui,sans-serif' }}>
      <div style={{ width: '50%', flexShrink: 0, overflow: 'hidden' }}>
        <img src={treeBg} alt="" aria-hidden="true" style={{ width: '100%', height: '100vh', objectFit: 'cover', objectPosition: 'center', display: 'block' }} />
      </div>
      <div style={{ width: '50%', display: 'flex', flexDirection: 'column', padding: '60px 48px', justifyContent: 'space-between' }}>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 22 }}>
          <p style={{ fontSize: 11, color: '#999', letterSpacing: 3, textTransform: 'uppercase', margin: 0 }}>Mathematics — Stage {stage}</p>
          <h1 style={{ fontSize: 'clamp(28px,3.5vw,42px)', fontWeight: 700, color: '#111', lineHeight: 1.35, margin: 0 }}>
            You are ready to begin Stage {stage} in Mathematics.
          </h1>
          <p style={{ fontSize: 'clamp(17px,2vw,22px)', color: '#555', margin: 0 }}>Answer the next {STAGE_SIZE} questions to complete this stage.</p>
        </div>
        <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 40, marginRight: 32 }}>
          <button onClick={onNext} style={{ ...BTN, padding: '18px 48px', fontSize: 22, borderRadius: 10 }}>Next ›</button>
        </div>
      </div>
    </div>
  );
}

function QuestionScreen({ question: q, qIdx, answers, selected, onSelect, onNext, onBack, onJump, onQuit, grade }) {
  const [pulsingIdx, setPulsingIdx] = useState(null);
  const [hoverIdx,   setHoverIdx]   = useState(null);

  useEffect(() => {
    const handler = (e) => {
      const i = +e.key - 1;
      if (i >= 0 && i < q.choices.length) { onSelect(i); return; }
      if ((e.key === 'Enter' || e.key === 'ArrowRight') && qIdx < STAGE_SIZE - 1) onNext();
      if (e.key === 'ArrowLeft' && qIdx > 0) onBack();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [q.choices.length, qIdx, onSelect, onNext, onBack]);

  return (
    <div style={{ background: '#07080f', minHeight: '100vh', fontFamily: 'system-ui,-apple-system,sans-serif' }}>
      <div className="arena-bg"><div className="arena-grain" /></div>
      <div style={{ maxWidth: 760, margin: '0 auto', background: '#fff', minHeight: '100vh', display: 'flex', flexDirection: 'column', position: 'relative', zIndex: 1, borderTop: '3px solid #1a73e8', boxShadow: '0 0 60px rgba(26,115,232,0.08), 0 0 40px rgba(0,60,120,0.10)' }}>
        <div style={{ borderBottom: '1px solid #e8e8e8', padding: '24px 32px 20px' }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, margin: '0 0 20px 0' }}>
            <p style={{ fontSize: 36, fontWeight: 700, color: '#333', margin: 0, lineHeight: 1, fontFamily: "'Barlow Condensed', system-ui, sans-serif", letterSpacing: '0.01em' }}>
              Question {qIdx + 1} of {STAGE_SIZE}
            </p>
            {grade && (
              <span style={{ fontSize: 11, fontWeight: 700, padding: '3px 8px', borderRadius: 4, background: 'rgba(26,115,232,0.08)', border: '1px solid rgba(26,115,232,0.25)', color: '#1a73e8', letterSpacing: '0.06em', fontFamily: 'system-ui,sans-serif', flexShrink: 0 }}>
                {grade}
              </span>
            )}
          </div>
          <ProgressStrip total={STAGE_SIZE} current={qIdx} answers={answers} onJump={onJump} />
        </div>

        <div key={qIdx} style={{ flex: 1, padding: '28px 32px 24px', animation: 'questionEnter 0.2s ease-out' }}>
          <p style={{ fontSize: 24, color: '#111', lineHeight: 1.7, whiteSpace: 'pre-line', fontWeight: 500, margin: '0 0 28px 0' }}>
            {q.question}
          </p>
          <div style={q.layout === 'grid'
            ? { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }
            : { display: 'flex', flexDirection: 'column', gap: 12 }
          }>
            {q.choices.map((choice, i) => {
              const sel = selected === i;
              const hov = hoverIdx === i && !sel;
              return (
                <button
                  key={i}
                  onClick={() => {
                    onSelect(i);
                    setPulsingIdx(i);
                    setTimeout(() => setPulsingIdx(p => p === i ? null : p), 150);
                  }}
                  onMouseEnter={() => setHoverIdx(i)}
                  onMouseLeave={() => setHoverIdx(null)}
                  style={{
                    minHeight: 64, padding: '18px 24px',
                    background: sel ? '#e8f0fe' : hov ? '#eef2ff' : '#f7f8fa',
                    border: `2px solid ${sel ? '#1a73e8' : hov ? '#1a73e8' : '#e0e0e0'}`,
                    borderRadius: 12, fontSize: 20,
                    color: sel ? '#1a73e8' : '#222',
                    textAlign: 'left', cursor: 'pointer',
                    fontWeight: sel ? 600 : 400,
                    fontFamily: 'system-ui,-apple-system,sans-serif', lineHeight: 1.45,
                    transition: 'background 0.12s, border-color 0.12s',
                    animation: pulsingIdx === i ? 'answerPulse 0.15s ease-out' : 'none',
                  }}
                >
                  <span style={{ fontSize: 14, fontWeight: 700, color: sel ? '#1a73e8' : '#aaa', marginRight: 20, opacity: 0.7 }}>
                    {i + 1}
                  </span>
                  {choice}
                </button>
              );
            })}
          </div>
        </div>

        <div style={{ borderTop: '1px solid #e0e0e0', boxShadow: '0 -2px 8px rgba(0,0,0,0.06)', padding: '16px 32px', display: 'flex', justifyContent: 'space-between', gap: 14 }}>
          <button style={QUIT_BTN} onClick={onQuit}>Quit</button>
          <div style={{ display: 'flex', gap: 14 }}>
            {qIdx > 0 && <button className="quiz-nav-btn" style={NAV_BTN} onClick={onBack}>‹ Back</button>}
            {qIdx === STAGE_SIZE - 1 ? (
              <button
                className="quiz-nav-btn"
                style={{ padding: '14px 40px', borderRadius: 999, fontSize: 17, fontWeight: 700, cursor: 'pointer', border: 'none', fontFamily: 'system-ui,sans-serif', background: '#ff69b4', color: '#000', animation: 'submitGlow 1.5s ease-in-out infinite alternate' }}
                onClick={onNext}
              >
                Submit ★
              </button>
            ) : (
              <button className="quiz-nav-btn" style={NAV_BTN} onClick={onNext}>Next ›</button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function StageResult({ stage, wrongCount, questions, answers: initialAnswers, onRetry, onNext }) {
  const [viewIdx, setViewIdx] = useState(0);
  const [localAnswers, setLocalAnswers] = useState(initialAnswers);

  const q            = questions[viewIdx];
  const storedAnswer = localAnswers[viewIdx] ?? null;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', minHeight: '100vh', background: '#fff', fontFamily: 'system-ui,-apple-system,sans-serif' }}>
      <div style={{ padding: '28px 40px 0' }}>
        <h2 style={{ fontSize: 22, fontWeight: 700, color: '#111', margin: 0 }}>Mathematics</h2>
        <hr style={{ border: 'none', borderTop: '1px solid #e0e0e0', margin: '16px 0 0' }} />
      </div>

      {wrongCount > 0 && (
        <div style={{ padding: '18px 40px 0' }}>
          <p style={{ fontSize: 15, fontWeight: 600, color: '#b00020', margin: 0 }}>
            {wrongCount} question{wrongCount > 1 ? 's' : ''} were incorrect.
          </p>
        </div>
      )}

      <div style={{ display: 'flex', flex: 1, padding: '24px 40px 100px', gap: 40 }}>
        <div style={{ width: '40%', display: 'flex', flexDirection: 'column', gap: 18 }}>
          <p style={{ fontSize: 18, color: '#111', lineHeight: 1.75, whiteSpace: 'pre-line', fontWeight: 500, margin: 0 }}>{q.question}</p>
          <div style={q.layout === 'grid'
            ? { display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }
            : { display: 'flex', flexDirection: 'column', gap: 10 }
          }>
            {q.choices.map((choice, i) => {
              const sel = storedAnswer === i;
              return (
                <button
                  key={i}
                  onClick={() => setLocalAnswers(prev => ({ ...prev, [viewIdx]: i }))}
                  style={{
                    minHeight: 52, padding: '13px 18px',
                    background: sel ? '#e8f0fe' : '#f7f8fa',
                    border: `2px solid ${sel ? '#1a73e8' : '#e0e0e0'}`,
                    borderRadius: 10, fontSize: 15,
                    color: sel ? '#1a73e8' : '#222',
                    textAlign: 'left', cursor: 'pointer',
                    fontWeight: sel ? 600 : 400,
                    fontFamily: 'system-ui,-apple-system,sans-serif', lineHeight: 1.45,
                    transition: 'background 0.12s, border-color 0.12s',
                  }}
                >
                  <span style={{ fontSize: 12, fontWeight: 700, color: sel ? '#1a73e8' : '#aaa', marginRight: 14, opacity: 0.7 }}>{i + 1}</span>
                  {choice}
                </button>
              );
            })}
          </div>
          <div style={{ background: '#f5f5f5', borderRadius: 8, padding: '10px 16px', fontSize: 13, color: '#666' }}>
            Your answer: {storedAnswer !== null ? q.choices[storedAnswer] : '—'}
          </div>
        </div>

        <div style={{ width: '60%', display: 'flex', flexDirection: 'column', gap: 20 }}>
          <h3 style={{ fontSize: 20, fontWeight: 700, color: '#111', margin: 0 }}>Stage {stage}</h3>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
            {questions.map((_, qi) => {
              const active = qi === viewIdx;
              return (
                <button
                  key={qi}
                  onClick={() => setViewIdx(qi)}
                  style={{
                    padding: '10px 14px',
                    background: active ? '#1a73e8' : '#fff',
                    color: active ? '#fff' : '#1a73e8',
                    border: active ? '2px solid #1a73e8' : '1.5px solid #1a73e8',
                    borderRadius: 8, fontSize: 14, fontWeight: 600,
                    cursor: 'pointer', fontFamily: 'system-ui,-apple-system,sans-serif',
                  }}
                >
                  Question {qi + 1}
                </button>
              );
            })}
          </div>
        </div>
      </div>

      <div style={{ position: 'fixed', bottom: 0, left: 0, right: 0, height: 72, display: 'flex', alignItems: 'center', justifyContent: 'flex-end', padding: '0 40px', background: '#fff', borderTop: '1px solid #e0e0e0', boxShadow: '0 -2px 8px rgba(0,0,0,0.06)', zIndex: 100 }}>
        {wrongCount === 0
          ? <button style={NAV_BTN} onClick={onNext}>Continue ›</button>
          : <button style={NAV_BTN} onClick={onRetry}>Try Again</button>
        }
      </div>
    </div>
  );
}

function CompleteScreen({ duration, isNewBest, onDashboard }) {
  return (
    <div style={{
      minHeight: '100vh',
      background: 'radial-gradient(ellipse at 50% 0%, rgba(245,197,24,0.12) 0%, transparent 60%), #07080f',
      display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'system-ui,sans-serif', position: 'relative', overflow: 'hidden',
    }}>
      <div style={{ width: '100%', maxWidth: 480, padding: '0 24px', textAlign: 'center', boxSizing: 'border-box' }}>
        <div style={{
          fontSize: 11, fontWeight: 700, letterSpacing: '0.3em', textTransform: 'uppercase',
          color: 'rgba(245,197,24,0.45)', marginBottom: 16,
        }}>
          Mathematics
        </div>
        <div style={{
          fontSize: 'clamp(64px, 10vw, 96px)', fontWeight: 900,
          color: '#f5c518', letterSpacing: '0.05em', lineHeight: 1,
          fontFamily: '"Russo One", system-ui, sans-serif',
          animation: 'titleFadeDown 0.5s ease-out both',
        }}>
          COMPLETE
        </div>
        <div style={{ width: 80, height: 2, background: '#f5c518', margin: '16px auto 24px' }} />
        <div style={{
          fontSize: 'clamp(36px, 6vw, 56px)', fontWeight: 700, color: '#fff',
          fontFamily: 'monospace', letterSpacing: '0.08em',
          animation: 'statsFadeUp 0.4s ease-out 0.3s both',
        }}>
          {fmtDuration(duration)}
        </div>
        {isNewBest && (
          <div style={{
            display: 'inline-block', marginTop: 16,
            padding: '8px 24px',
            background: 'rgba(245,197,24,0.12)',
            border: '1.5px solid rgba(245,197,24,0.5)',
            borderRadius: 999, fontSize: 14, fontWeight: 700,
            color: '#f5c518', letterSpacing: '0.06em', textTransform: 'uppercase',
            boxShadow: '0 0 12px rgba(245,197,24,0.35)',
            animation: 'statsFadeUp 0.4s ease-out 0.45s both',
          }}>
            New Personal Best!
          </div>
        )}
        <div style={{ marginTop: 32, animation: 'statsFadeUp 0.4s ease-out 0.55s both' }}>
          <button
            onClick={onDashboard}
            style={{
              padding: '14px 48px', borderRadius: 6, fontSize: 15, fontWeight: 700,
              letterSpacing: '0.08em', textTransform: 'uppercase', cursor: 'pointer',
              border: '1px solid rgba(245,197,24,0.5)',
              background: 'rgba(245,197,24,0.1)', color: '#f5c518',
              fontFamily: 'system-ui,sans-serif',
            }}
            onMouseEnter={e => { e.currentTarget.style.background = 'rgba(245,197,24,0.2)'; e.currentTarget.style.borderColor = '#f5c518'; }}
            onMouseLeave={e => { e.currentTarget.style.background = 'rgba(245,197,24,0.1)'; e.currentTarget.style.borderColor = 'rgba(245,197,24,0.5)'; }}
          >
            Back to Dashboard
          </button>
        </div>
      </div>
    </div>
  );
}

// ── Game Controller ────────────────────────────────────────────

export default function Game() {
  const navigate = useNavigate();
  const { state } = useLocation();
  const grade = state?.grade ?? null;

  if (!state) {
    navigate('/dashboard', { replace: true });
    return null;
  }

  const [phase,      setPhase]      = useState('loading');
  const [stage,      setStage]      = useState(1);
  const [questions,  setQuestions]  = useState([]);
  const [qIdx,       setQIdx]       = useState(0);
  const [answers,    setAnswers]    = useState({});
  const [selected,   setSelected]   = useState(null);
  const [wrongCount,      setWrongCount]      = useState(0);
  const [duration,        setDuration]        = useState(0);
  const [elapsed,         setElapsed]         = useState(0);
  const [fetchError,      setFetchError]      = useState(false);
  const [isNewBest, setIsNewBest] = useState(false);
  const [stageFlash, setStageFlash] = useState(false);

  const timerStartRef = useRef(null);
  const intervalRef   = useRef(null);
  const stagedQsRef   = useRef({ 1: [], 2: [] });
  const sessionIdRef  = useRef(null);
  const s1CorrectRef  = useRef(0);

  // Fetch both stages in parallel while the user reads the intro screen
  useEffect(() => {
    if (!grade) { navigate('/dashboard', { replace: true }); return; }
    const token = sessionStorage.getItem('ranked_token');
    const headers = { Authorization: `Bearer ${token}` };
    Promise.all([
      fetch(`${API}/questions?grade=${grade}`, { headers }).then(r => r.json()),
      fetch(`${API}/questions?grade=${grade}`, { headers }).then(r => r.json()),
    ]).then(([s1, s2]) => {
      stagedQsRef.current = { 1: s1, 2: s2 };
      setQuestions(s1);
      setPhase('intro');
    }).catch(() => setFetchError(true));
  }, [grade, navigate]);

  useEffect(() => () => clearInterval(intervalRef.current), []);

  function startTimer() {
    timerStartRef.current = Date.now();
    intervalRef.current = setInterval(() => setElapsed(Date.now() - timerStartRef.current), 500);
  }

  function stopTimer() {
    clearInterval(intervalRef.current);
    intervalRef.current = null;
    return timerStartRef.current ? Date.now() - timerStartRef.current : 0;
  }

  if (!grade) return null;

  if (fetchError) return (
    <div style={{ ...WRAP, alignItems: 'center', justifyContent: 'center', gap: 16, textAlign: 'center' }}>
      <p style={{ fontSize: 18, color: '#555' }}>Failed to load questions.</p>
      <button onClick={() => navigate('/dashboard')} style={{ ...BTN, padding: '12px 32px' }}>Go back</button>
    </div>
  );

  function loadStage(s) {
    setQuestions(stagedQsRef.current[s]);
    setStage(s);
    setQIdx(0);
    setAnswers({});
    setSelected(null);
    setPhase('intro');
  }

  function startSession() {
    const token = sessionStorage.getItem('ranked_token');
    fetch(`${API}/session/start`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
      body: JSON.stringify({ grade, subject: 'MATH' }),
    }).then(r => r.json()).then(d => { sessionIdRef.current = d.sessionId ?? null; }).catch(() => {});
  }

  function endSession(totalCorrect) {
    if (!sessionIdRef.current) return;
    const token = sessionStorage.getItem('ranked_token');
    fetch(`${API}/session/complete`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
      body: JSON.stringify({ sessionId: sessionIdRef.current, correctAnswers: totalCorrect, totalQuestions: STAGE_SIZE * 2 }),
    }).catch(() => {});
  }

  function handleNext() {
    const newAnswers = { ...answers, [qIdx]: selected };
    setAnswers(newAnswers);
    if (qIdx < STAGE_SIZE - 1) {
      const next = qIdx + 1;
      setQIdx(next);
      setSelected(newAnswers[next] ?? null);
    } else {
      const wrong = questions.filter((q, i) => newAnswers[i] !== q.correct).length;
      setWrongCount(wrong);
      setPhase('result');
    }
  }

  function handleBack() {
    const newAnswers = selected !== null ? { ...answers, [qIdx]: selected } : answers;
    setAnswers(newAnswers);
    const prev = qIdx - 1;
    setQIdx(prev);
    setSelected(newAnswers[prev] ?? null);
  }

  function handleJump(targetIdx) {
    const newAnswers = selected !== null ? { ...answers, [qIdx]: selected } : answers;
    setAnswers(newAnswers);
    setQIdx(targetIdx);
    setSelected(newAnswers[targetIdx] ?? null);
  }

  function handleRetry() {
    setQIdx(0);
    setSelected(answers[0] ?? null);
    setPhase('question');
  }

  function handleQuit() {
    if (!window.confirm('Are you sure you want to quit? Your progress will be lost.')) return;
    stopTimer();
    navigate('/dashboard');
  }

  async function handleResultNext() {
    if (stage === 1) {
      s1CorrectRef.current = STAGE_SIZE - wrongCount;
      setStageFlash(true);
      setTimeout(() => {
        setStageFlash(false);
        loadStage(2);
      }, 800);
    } else {
      endSession(s1CorrectRef.current + (STAGE_SIZE - wrongCount));
      const token = sessionStorage.getItem('ranked_token');
      const timeMs = timerStartRef.current ? Date.now() - timerStartRef.current : 0;
      stopTimer();
      console.log('Submitting best time:', grade, timeMs);
      let isNewBest = false;
      try {
        const res = await fetch(`${API}/me/best-time`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
          body: JSON.stringify({ grade, timeMs }),
        });
        const data = await res.json();
        isNewBest = data.updated === true;
      } catch (e) {
        console.error('Failed to record best time:', e);
      }
      setDuration(timeMs);
      setIsNewBest(isNewBest);
      setPhase('complete');
    }
  }

  const timerRunning = timerStartRef.current !== null && phase !== 'complete';
  const timerSecs    = Math.floor(elapsed / 1000);
  const timerDisplay = `${String(Math.floor(timerSecs / 60)).padStart(2, '0')}:${String(timerSecs % 60).padStart(2, '0')}`;

  function renderPhase() {
    if (phase === 'loading') return (
      <div style={{ ...WRAP, alignItems: 'center', justifyContent: 'center' }}>
        <div style={{ width: 40, height: 40, borderRadius: '50%', border: '3px solid #e0e0e0', borderTopColor: '#1a73e8', animation: 'spin 0.8s linear infinite' }} />
      </div>
    );
    if (phase === 'intro')    return <StageIntro stage={stage} onNext={() => { if (stage === 1) { startTimer(); startSession(); } setPhase('question'); }} />;
    if (phase === 'question') return <QuestionScreen question={questions[qIdx]} qIdx={qIdx} answers={answers} selected={selected} onSelect={setSelected} onNext={handleNext} onBack={handleBack} onJump={handleJump} onQuit={handleQuit} grade={grade} />;
    if (phase === 'result')   return <StageResult stage={stage} wrongCount={wrongCount} questions={questions} answers={answers} onRetry={handleRetry} onNext={handleResultNext} />;
    if (phase === 'complete') return <CompleteScreen duration={duration} isNewBest={isNewBest} onDashboard={() => navigate('/dashboard')} />;
    return null;
  }

  return (
    <>
      <GlobalStyles />
      {timerRunning && (
        <div style={{
          position: 'fixed', top: 18, right: 24, zIndex: 200,
          background: 'rgba(26,115,232,0.92)', color: '#fff',
          fontFamily: 'system-ui,-apple-system,sans-serif',
          fontSize: 15, fontWeight: 700, letterSpacing: '0.08em',
          padding: '6px 14px', borderRadius: 999,
          boxShadow: '0 2px 12px rgba(26,115,232,0.35)',
          userSelect: 'none',
        }}>
          ⏱ {timerDisplay}
        </div>
      )}
      {renderPhase()}
      {stageFlash && (
        <div style={{
          position: 'fixed', inset: 0, zIndex: 9999,
          background: '#07080f',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <div style={{
            fontSize: 'clamp(28px, 5vw, 48px)', fontWeight: 900, color: '#f5c518',
            fontFamily: '"Russo One", system-ui, sans-serif',
            letterSpacing: '0.05em',
          }}>
            Stage 1 Complete.
          </div>
        </div>
      )}
    </>
  );
}
