import { useState, useEffect, useRef } from 'react';
import { useNavigate, useLocation, Navigate } from 'react-router-dom';

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

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 FORFEIT_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',
};

function authHeaders() {
  const token = sessionStorage.getItem('ranked_token');
  return token ? { Authorization: `Bearer ${token}` } : {};
}

function OpponentProgressStrip({ progress, total, name, dced, disconnected }) {
  const items = [];
  for (let qi = 0; qi < total; qi++) {
    const filled = qi < progress;
    items.push(
      <div key={`b-${qi}`} style={{ width: 30, height: 30, borderRadius: '50%', border: `2px solid ${filled ? '#e67e22' : '#ccc'}`, background: filled ? '#e67e22' : '#fff', color: filled ? '#fff' : '#aaa', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 700, fontFamily: 'system-ui,-apple-system,sans-serif', flexShrink: 0, padding: 0, boxSizing: 'border-box', transition: 'background 0.15s, border-color 0.15s' }}>{qi + 1}</div>
    );
    if (qi < total - 1) {
      items.push(
        <div key={`l-${qi}`} style={{ flex: 1, height: 2, minWidth: 2, background: filled ? '#e67e22' : '#ddd' }} />
      );
    }
  }
  return (
    <div style={{ marginTop: 8, padding: '10px 0', display: 'flex', flexDirection: 'column', gap: 6 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <span style={{ fontSize: 11, fontWeight: 700, color: (dced || disconnected) ? '#c62828' : '#e67e22', textTransform: 'uppercase', letterSpacing: '0.05em', fontFamily: 'system-ui,sans-serif' }}>{name}</span>
        {dced && <span style={{ fontSize: 10, fontWeight: 700, color: '#fff', background: '#c62828', borderRadius: 4, padding: '1px 5px', fontFamily: 'system-ui,sans-serif', letterSpacing: '0.04em' }}>DC'd</span>}
        {!dced && disconnected && <span style={{ fontSize: 10, fontWeight: 700, color: '#fff', background: '#e57373', borderRadius: 4, padding: '1px 5px', fontFamily: 'system-ui,sans-serif', letterSpacing: '0.04em' }}>disconnected?</span>}
      </div>
      <div style={{ display: 'flex', alignItems: 'center', flexWrap: 'nowrap', width: '100%', opacity: (dced || disconnected) ? 0.5 : 1 }}>
        {items}
      </div>
    </div>
  );
}

function ProgressStrip({ total, current, answers, onJump }) {
  const items = [];
  for (let qi = 0; qi < total; qi++) {
    const active = qi === current, answered = answers[qi] != null, filled = answered;
    items.push(
      <button key={`b-${qi}`} 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' }}>{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>;
}

function PlayerChip({ name, avatar, reverse }) {
  const pic = avatar
    ? <img src={avatar} alt="" style={{ width: 56, height: 56, borderRadius: '50%', flexShrink: 0 }} referrerPolicy="no-referrer" />
    : <div style={{ width: 56, height: 56, borderRadius: '50%', background: '#1a73e8', color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22, fontWeight: 700, flexShrink: 0 }}>{name?.[0]?.toUpperCase() ?? '?'}</div>;
  const label = <span style={{ fontSize: 17, fontWeight: 700, color: '#222', fontFamily: 'system-ui,sans-serif' }}>{name}</span>;
  return (
    <div style={{ display: 'flex', flexDirection: reverse ? 'row-reverse' : 'row', alignItems: 'center', gap: 12 }}>
      {pic}{label}
    </div>
  );
}

function StageIntro({ grade, myName, myAvatar, opponentName, opponentAvatar, onNext }) {
  const [count, setCount] = useState(5);
  const gradeNum = grade?.replace('G', '') ?? '';

  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => {
        if (c <= 1) { clearInterval(id); onNext(); return 0; }
        return c - 1;
      });
    }, 1000);
    return () => clearInterval(id);
  }, [onNext]);

  return (
    <div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: '#fff', fontFamily: 'system-ui,sans-serif', gap: 28 }}>
      <p style={{ fontSize: 11, color: '#999', letterSpacing: 3, textTransform: 'uppercase', margin: 0 }}>Ranked Match</p>
      <h1 style={{ fontSize: 'clamp(30px,5vw,52px)', fontWeight: 800, color: '#111', margin: 0, textAlign: 'center' }}>EQAO Grade {gradeNum}</h1>
      <div style={{ display: 'flex', alignItems: 'center', gap: 20, flexWrap: 'wrap', justifyContent: 'center' }}>
        <PlayerChip name={myName} avatar={myAvatar} reverse={false} />
        <span style={{ fontSize: 18, fontWeight: 700, color: '#aaa', letterSpacing: 2 }}>vs</span>
        <PlayerChip name={opponentName} avatar={opponentAvatar} reverse={true} />
      </div>
      <p style={{ fontSize: 14, color: '#aaa', margin: 0 }}>First to finish all {STAGE_SIZE} questions wins.</p>
      <div style={{ fontSize: 'clamp(88px,18vw,144px)', fontWeight: 900, color: '#e53935', lineHeight: 1, fontVariantNumeric: 'tabular-nums', minWidth: 120, textAlign: 'center' }}>{count}</div>
    </div>
  );
}

function QuestionScreen({ question: q, qIdx, answers, selected, onSelect, onNext, onBack, onJump, opponentProgress, opponentName, opponentDced, opponentConnected, onForfeit }) {
  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: '#cce8f4', minHeight: '100vh', fontFamily: 'system-ui,-apple-system,sans-serif' }}>
      <div style={{ maxWidth: 760, margin: '0 auto', background: '#fff', minHeight: '100vh', display: 'flex', flexDirection: 'column', boxShadow: '0 0 40px rgba(0,60,120,0.10)' }}>
        <div style={{ borderBottom: '1px solid #e8e8e8', padding: '20px 32px 16px' }}>
          <p style={{ fontSize: 36, fontWeight: 700, color: '#333', margin: '0 0 14px 0', lineHeight: 1 }}>Question {qIdx + 1} of {STAGE_SIZE}</p>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <span style={{ fontSize: 11, fontWeight: 700, color: '#1a73e8', textTransform: 'uppercase', letterSpacing: '0.05em', fontFamily: 'system-ui,sans-serif' }}>You</span>
            <div style={{ flex: 1 }}><ProgressStrip total={STAGE_SIZE} current={qIdx} answers={answers} onJump={onJump} /></div>
          </div>
          <OpponentProgressStrip progress={opponentProgress} total={STAGE_SIZE} name={opponentName} dced={opponentDced} disconnected={!opponentConnected && !opponentDced} />
        </div>
        <div style={{ flex: 1, padding: '28px 32px 24px' }}>
          <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;
              return (
                <button key={i} onClick={() => onSelect(i)} style={{ minHeight: 64, padding: '18px 24px', background: sel ? '#e8f0fe' : '#f7f8fa', border: `2px solid ${sel ? '#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' }}>
                  <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={FORFEIT_BTN} onClick={onForfeit}>Forfeit</button>
          <div style={{ display: 'flex', gap: 14 }}>
            {qIdx > 0 && <button style={NAV_BTN} onClick={onBack}>‹ Back</button>}
            {qIdx === STAGE_SIZE - 1 ? (
              <button style={{ padding: '14px 40px', borderRadius: 999, fontSize: 17, fontWeight: 700, cursor: 'pointer', border: 'none', fontFamily: 'system-ui,sans-serif', background: '#ff69b4', color: '#000', boxShadow: '0 0 6px #ff69b4aa' }} onClick={onNext}>Submit ★</button>
            ) : (
              <button style={NAV_BTN} onClick={onNext}>Next ›</button>
            )}
          </div>
        </div>
      </div>
    </div>
  );
}

function DefeatOverlay({ opponentName, onViewResults }) {
  return (
    <div style={{ position: 'fixed', top: 0, left: 0, right: 0, bottom: 0, background: 'rgba(0,0,0,0.55)', display: 'flex', alignItems: 'center', justifyContent: 'center', zIndex: 2000 }}>
      <div style={{ background: '#fff', borderRadius: 16, padding: '40px 48px', textAlign: 'center', maxWidth: 380, width: '90%', fontFamily: 'system-ui,sans-serif', boxShadow: '0 8px 32px rgba(0,0,0,0.2)' }}>
        <div style={{ fontSize: 64, marginBottom: 12 }}>💀</div>
        <h1 style={{ fontSize: 32, fontWeight: 800, color: '#c62828', margin: '0 0 8px' }}>Defeated!</h1>
        <p style={{ fontSize: 16, color: '#555', margin: '0 0 24px', lineHeight: 1.5 }}>{opponentName} finished before you.</p>
        <button onClick={onViewResults} style={{ padding: '12px 36px', fontSize: 16, fontWeight: 600, background: '#1a73e8', color: '#fff', border: 'none', borderRadius: 999, cursor: 'pointer', fontFamily: 'system-ui,sans-serif' }}>See Results</button>
      </div>
    </div>
  );
}

function WaitingScreen({ opponentName, opponentProgress, opponentDced, opponentConnected, onForfeit }) {
  return (
    <div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: '#fff', fontFamily: 'system-ui,sans-serif', gap: 24 }}>
      {opponentDced
        ? <div style={{ fontSize: 48 }}>🔌</div>
        : <div style={{ width: 48, height: 48, borderRadius: '50%', border: '3px solid #e0e0e0', borderTopColor: '#ff69b4', animation: 'spin 0.6s linear infinite' }} />
      }
      <h2 style={{ fontSize: 22, fontWeight: 600, color: opponentDced ? '#c62828' : '#333', margin: 0 }}>
        {opponentDced ? `${opponentName} disconnected!` : `Waiting for ${opponentName}...`}
      </h2>
      <p style={{ fontSize: 15, color: '#888', margin: 0 }}>
        {opponentDced ? 'Awarding victory...' : 'You finished! Now waiting for your opponent to complete.'}
      </p>
      <div style={{ width: '100%', maxWidth: 480, marginTop: 8 }}>
        <OpponentProgressStrip progress={opponentProgress} total={STAGE_SIZE} name={opponentName} dced={opponentDced} disconnected={!opponentConnected && !opponentDced} />
      </div>
      <button onClick={onForfeit} style={{ marginTop: 16, ...FORFEIT_BTN }}>Forfeit & Leave</button>
      <style>{`@keyframes spin { to { transform: rotate(360deg); } }`}</style>
    </div>
  );
}

function CompleteScreen({ won, opponentName, duration, eloChange, opponentDced, youDced, onDashboard }) {
  const subtitle = opponentDced && won
    ? `${opponentName} disconnected. Victory by default.`
    : youDced && !won
      ? `You disconnected. ${opponentName} wins.`
      : won
        ? `You beat ${opponentName}! Well played.`
        : `${opponentName} beat you. Better luck next time.`;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', minHeight: '100vh', background: '#fff', fontFamily: 'system-ui,sans-serif' }}>
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '40px 32px', textAlign: 'center', gap: 20 }}>
        <div style={{ fontSize: 72 }}>{won ? (opponentDced ? '🔌' : '🏆') : '💀'}</div>
        <h1 style={{ fontSize: 36, fontWeight: 800, color: won ? '#1b8a2d' : '#c62828', margin: 0 }}>{won ? 'Victory!' : 'Defeated!'}</h1>
        <p style={{ fontSize: 17, color: '#555', maxWidth: 400, margin: 0 }}>{subtitle}</p>
        {duration > 0 && (
          <div style={{ padding: '14px 40px', background: won ? '#f0faf0' : '#fef0f0', border: `2px solid ${won ? '#a5d6a7' : '#ef9a9a'}`, borderRadius: 12, fontSize: 24, fontWeight: 700, color: won ? '#1b8a2d' : '#c62828' }}>
            ⏱ {Math.floor(duration / 1000 / 60)}:{String(Math.floor(duration / 1000) % 60).padStart(2, '0')}
          </div>
        )}
        {eloChange !== 0 && <div style={{ padding: '10px 24px', borderRadius: 8, fontSize: 18, fontWeight: 700, fontFamily: 'system-ui,sans-serif', color: eloChange > 0 ? '#1b8a2d' : '#c62828' }}>ELO {eloChange > 0 ? '+' : ''}{eloChange}</div>}
        <button onClick={onDashboard} style={{ padding: '13px 40px', background: '#1a73e8', color: '#fff', border: 'none', borderRadius: 999, fontSize: 16, fontWeight: 600, cursor: 'pointer', fontFamily: 'system-ui,sans-serif' }}>Back to Dashboard</button>
      </div>
    </div>
  );
}

export default function RankedGame() {
  const navigate = useNavigate();
  const { state } = useLocation();

  if (!state || !state.gameId || !state.questions) {
    return <Navigate to="/dashboard" replace />;
  }

  const { gameId, questions: initialQuestions, opponentName: initOppName, opponentAvatar: initOppAvatar, myName: initMyName, myAvatar: initMyAvatar, grade } = state;

  const [phase, setPhase] = useState('intro');
  const [questions] = useState(initialQuestions);
  const [qIdx, setQIdx] = useState(0);
  const [answers, setAnswers] = useState({});
  const [selected, setSelected] = useState(null);
  const [opponentProgress, setOpponentProgress] = useState(0);
  const [opponentName] = useState(initOppName);
  const [opponentAvatar] = useState(initOppAvatar);
  const [playerWon, setPlayerWon] = useState(null);
  const [showDefeatOverlay, setShowDefeatOverlay] = useState(false);
  const [startTime] = useState(() => Date.now());
  const [duration, setDuration] = useState(0);
  const [eloChange, setEloChange] = useState(0);
  const [opponentDced, setOpponentDced] = useState(false);
  const [youDced, setYouDced] = useState(false);
  const [opponentConnected, setOpponentConnected] = useState(true);

  const pollRef = useRef(null);
  const completedRef = useRef(false);
  const submittedRef = useRef(false);

  useEffect(() => {
    return () => clearInterval(pollRef.current);
  }, []);

  function submitProgress(currentQuestion, correctAnswers, finished, timeSpentMs) {
    fetch(`${API}/game/progress`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', ...authHeaders() },
      body: JSON.stringify({ gameId, currentQuestion, correctAnswers, finished, timeSpentMs }),
    }).catch(() => {});
  }

  function pollGameStatus() {
    pollRef.current = setInterval(() => {
      if (completedRef.current) { clearInterval(pollRef.current); return; }

      fetch(`${API}/game/status/${gameId}`, { headers: authHeaders() })
        .then(r => r.json())
        .then(data => {
          if (data.opponentDced) setOpponentDced(true);
          if (data.youDced) setYouDced(true);
          if (data.opponentConnected === false) setOpponentConnected(false);
          else if (data.opponentConnected === true && !data.opponentDced) setOpponentConnected(true);
          if (data.status === 'completed') {
            clearInterval(pollRef.current);
            const you = data.players.you;
            const won = data.youWon === true;
            completedRef.current = true;
            setDuration(you.timeSpentMs || (Date.now() - startTime));
            setEloChange(you.eloChange || 0);
            setPlayerWon(won);
            if (won) {
              setPhase('complete');
            } else {
              setShowDefeatOverlay(true);
            }
          } else {
            const opp = data.players.opponent;
            setOpponentProgress(opp.currentQuestion + 1);
          }
        })
        .catch(() => {});
    }, 1000);
  }

  function handleNext() {
    const newAnswers = { ...answers, [qIdx]: selected };
    setAnswers(newAnswers);

    const correctCount = questions.filter((q, i) => newAnswers[i] === q.correct).length;
    const elapsed = Date.now() - startTime;

    if (qIdx < STAGE_SIZE - 1) {
      submitProgress(qIdx + 1, correctCount, false);
      const next = qIdx + 1;
      setQIdx(next);
      setSelected(newAnswers[next] ?? null);
    } else {
      submittedRef.current = true;
      submitProgress(STAGE_SIZE, correctCount, true, elapsed);
      setPhase('waiting');
    }
  }

  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);
  }

  async function handleForfeit() {
    if (!window.confirm('Are you sure you want to forfeit? This counts as a loss.')) return;
    clearInterval(pollRef.current);
    completedRef.current = true;
    try {
      await fetch(`${API}/game/forfeit`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json', ...authHeaders() },
        body: JSON.stringify({ gameId }),
      });
    } catch {}
    navigate('/dashboard');
  }

  if (phase === 'intro')
    return <StageIntro grade={grade} myName={initMyName} myAvatar={initMyAvatar} opponentName={opponentName} opponentAvatar={opponentAvatar} onNext={() => { setPhase('question'); pollGameStatus(); }} />;

  if (phase === 'question')
    return (
      <>
        <QuestionScreen
          question={questions[qIdx]} qIdx={qIdx} answers={answers} selected={selected}
          onSelect={setSelected} onNext={handleNext} onBack={handleBack} onJump={handleJump}
          opponentProgress={opponentProgress} opponentName={opponentName}
          opponentDced={opponentDced} opponentConnected={opponentConnected}
          onForfeit={handleForfeit}
        />
        {showDefeatOverlay && (
          <DefeatOverlay opponentName={opponentName} onViewResults={() => { setShowDefeatOverlay(false); setPhase('complete'); }} />
        )}
      </>
    );

  if (phase === 'waiting')
    return (
      <>
        <WaitingScreen opponentName={opponentName} opponentProgress={opponentProgress} opponentDced={opponentDced} opponentConnected={opponentConnected} onForfeit={handleForfeit} />
        {showDefeatOverlay && (
          <DefeatOverlay opponentName={opponentName} onViewResults={() => { setShowDefeatOverlay(false); setPhase('complete'); }} />
        )}
      </>
    );

  if (phase === 'complete')
    return (
      <CompleteScreen
        won={playerWon} opponentName={opponentName} duration={duration}
        eloChange={eloChange} opponentDced={opponentDced} youDced={youDced} onDashboard={() => navigate('/dashboard')}
      />
    );

  return null;
}
