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

const VALID_GRADES = new Set(['G3', 'G6', 'G9']);
const API = import.meta.env.VITE_API_URL;

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

function getNameFromToken() {
  try {
    const token = sessionStorage.getItem('ranked_token');
    if (!token) return 'You';
    const payload = JSON.parse(atob(token.split('.')[1]));
    return payload.name ?? 'You';
  } catch {
    return 'You';
  }
}

function getAvatarFromToken() {
  try {
    const token = sessionStorage.getItem('ranked_token');
    if (!token) return null;
    const payload = JSON.parse(atob(token.split('.')[1]));
    return payload.picture ?? null;
  } catch {
    return null;
  }
}

function MatchFoundScreen({ myName, myAvatar, opponentName, opponentAvatar, grade, onDone }) {
  const [count, setCount] = useState(5);
  const [phase, setPhase] = useState('intro'); // intro → reveal → countdown

  useEffect(() => {
    const t1 = setTimeout(() => setPhase('reveal'), 400);
    const t2 = setTimeout(() => setPhase('countdown'), 1200);
    return () => { clearTimeout(t1); clearTimeout(t2); };
  }, []);

  useEffect(() => {
    if (phase !== 'countdown') return;
    if (count <= 0) { onDone(); return; }
    const id = setTimeout(() => setCount(c => c - 1), 1000);
    return () => clearTimeout(id);
  }, [count, phase, onDone]);

  const countColor = count <= 1 ? '#ff3b30' : count <= 2 ? '#ff9500' : count <= 3 ? '#ffcc00' : '#4fc3f7';
  const countGlow  = count <= 1 ? '#ff3b3088' : count <= 2 ? '#ff950088' : count <= 3 ? '#ffcc0088' : '#4fc3f788';

  return (
    <div style={{
      minHeight: '100vh', display: 'flex', flexDirection: 'column',
      alignItems: 'center', justifyContent: 'center',
      background: '#07090f',
      fontFamily: "'system-ui',sans-serif", overflow: 'hidden', position: 'relative',
    }}>
      <style>{`
        @keyframes bg-scan {
          0%   { transform: translateY(-100%); opacity: 0.07; }
          100% { transform: translateY(100vh); opacity: 0.03; }
        }
        @keyframes header-drop {
          0%   { transform: translateY(-40px) scaleX(0.6); opacity: 0; letter-spacing: 0.3em; }
          60%  { transform: translateY(4px) scaleX(1.02); opacity: 1; letter-spacing: 0.18em; }
          100% { transform: translateY(0) scaleX(1); opacity: 1; letter-spacing: 0.18em; }
        }
        @keyframes player-slide-left {
          0%   { transform: translateX(-120px); opacity: 0; }
          70%  { transform: translateX(6px); opacity: 1; }
          100% { transform: translateX(0); opacity: 1; }
        }
        @keyframes player-slide-right {
          0%   { transform: translateX(120px); opacity: 0; }
          70%  { transform: translateX(-6px); opacity: 1; }
          100% { transform: translateX(0); opacity: 1; }
        }
        @keyframes vs-slam {
          0%   { transform: scale(3) rotate(-8deg); opacity: 0; }
          55%  { transform: scale(0.92) rotate(1deg); opacity: 1; }
          75%  { transform: scale(1.06) rotate(-0.5deg); }
          100% { transform: scale(1) rotate(0deg); opacity: 1; }
        }
        @keyframes divider-grow {
          0%   { width: 0; opacity: 0; }
          100% { width: 100%; opacity: 1; }
        }
        @keyframes count-slam {
          0%   { transform: scale(2.2); opacity: 0; }
          50%  { transform: scale(0.88); opacity: 1; }
          75%  { transform: scale(1.08); }
          100% { transform: scale(1); opacity: 1; }
        }
        @keyframes ring-pulse {
          0%   { transform: scale(1);   opacity: 0.7; }
          100% { transform: scale(2.2); opacity: 0; }
        }
        @keyframes avatar-glow-blue {
          0%, 100% { box-shadow: 0 0 18px 4px #1a73e8aa, 0 0 0 3px #1a73e8; }
          50%       { box-shadow: 0 0 32px 10px #1a73e8cc, 0 0 0 3px #1a73e8; }
        }
        @keyframes avatar-glow-red {
          0%, 100% { box-shadow: 0 0 18px 4px #ff3b30aa, 0 0 0 3px #ff3b30; }
          50%       { box-shadow: 0 0 32px 10px #ff3b30cc, 0 0 0 3px #ff3b30; }
        }
        @keyframes scan-line {
          0%   { top: 0%; }
          100% { top: 100%; }
        }
        .player-left  { animation: player-slide-left  0.55s cubic-bezier(.22,1,.36,1) 0.9s both; }
        .player-right { animation: player-slide-right 0.55s cubic-bezier(.22,1,.36,1) 0.9s both; }
        .vs-text      { animation: vs-slam 0.5s cubic-bezier(.22,1,.36,1) 1.05s both; }
        .header-text  { animation: header-drop 0.6s cubic-bezier(.22,1,.36,1) 0.1s both; }
        .count-slam   { animation: count-slam 0.3s cubic-bezier(.22,1,.36,1) both; }
        .ring         { animation: ring-pulse 0.7s ease-out both; }
      `}</style>

      {/* Scanline overlay */}
      <div style={{
        position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'hidden', zIndex: 0,
      }}>
        <div style={{
          position: 'absolute', left: 0, right: 0, height: 2,
          background: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.04), transparent)',
          animation: 'scan-line 3s linear infinite',
        }} />
        {/* subtle grid */}
        <div style={{
          position: 'absolute', inset: 0,
          backgroundImage: 'linear-gradient(rgba(255,255,255,0.025) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,0.025) 1px, transparent 1px)',
          backgroundSize: '40px 40px',
        }} />
      </div>

      {/* Header */}
      <div className="header-text" style={{
        fontSize: 13, fontWeight: 800, letterSpacing: '0.18em',
        textTransform: 'uppercase', color: '#4fc3f7',
        marginBottom: 48, zIndex: 1,
        textShadow: '0 0 20px #4fc3f7aa',
      }}>
        Match Found
      </div>

      {/* Players row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 48, zIndex: 1 }}>

        {/* You */}
        <div className="player-left" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
          <div style={{
            width: 100, height: 100, borderRadius: '50%',
            background: myAvatar ? 'transparent' : '#0d2a4a',
            overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center',
            animation: 'avatar-glow-blue 2s ease-in-out infinite',
          }}>
            {myAvatar
              ? <img src={myAvatar} alt={myName} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
              : <span style={{ fontSize: 38, color: '#4fc3f7', fontWeight: 800 }}>{(myName?.[0] ?? '?').toUpperCase()}</span>
            }
          </div>
          <span style={{ fontSize: 15, fontWeight: 700, color: '#e8f4fd', maxWidth: 130, textAlign: 'center', wordBreak: 'break-word', letterSpacing: '0.01em' }}>{myName}</span>
          <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.14em', textTransform: 'uppercase', color: '#1a73e8' }}>You</span>
        </div>

        {/* VS + countdown */}
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 20 }}>
          <span className="vs-text" style={{
            fontSize: 40, fontWeight: 900, color: '#fff',
            letterSpacing: '0.05em',
            textShadow: '0 0 24px rgba(255,255,255,0.25)',
          }}>VS</span>

          {phase === 'countdown' && (
            <div style={{ position: 'relative', width: 80, height: 80, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              {/* pulse rings */}
              <div key={`r1-${count}`} className="ring" style={{
                position: 'absolute', width: 80, height: 80, borderRadius: '50%',
                border: `2px solid ${countColor}`,
              }} />
              <div key={`r2-${count}`} className="ring" style={{
                position: 'absolute', width: 80, height: 80, borderRadius: '50%',
                border: `2px solid ${countColor}`,
                animationDelay: '0.15s',
              }} />
              <div key={count} className="count-slam" style={{
                width: 80, height: 80, borderRadius: '50%',
                background: `radial-gradient(circle at 38% 38%, ${countColor}33, #0a0a1a)`,
                border: `2px solid ${countColor}`,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: 38, fontWeight: 900, color: countColor,
                boxShadow: `0 0 28px ${countGlow}, inset 0 0 12px ${countColor}22`,
                fontVariantNumeric: 'tabular-nums',
              }}>
                {count}
              </div>
            </div>
          )}
        </div>

        {/* Opponent */}
        <div className="player-right" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
          <div style={{
            width: 100, height: 100, borderRadius: '50%',
            background: opponentAvatar ? 'transparent' : '#2a0d0d',
            overflow: 'hidden', display: 'flex', alignItems: 'center', justifyContent: 'center',
            animation: 'avatar-glow-red 2s ease-in-out infinite',
          }}>
            {opponentAvatar
              ? <img src={opponentAvatar} alt={opponentName} style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
              : <span style={{ fontSize: 38, color: '#ff6b6b', fontWeight: 800 }}>{(opponentName?.[0] ?? '?').toUpperCase()}</span>
            }
          </div>
          <span style={{ fontSize: 15, fontWeight: 700, color: '#ffe8e8', maxWidth: 130, textAlign: 'center', wordBreak: 'break-word', letterSpacing: '0.01em' }}>{opponentName}</span>
          <span style={{ fontSize: 10, fontWeight: 700, letterSpacing: '0.14em', textTransform: 'uppercase', color: '#ff3b30' }}>Opponent</span>
        </div>
      </div>

      {/* Divider line */}
      <div style={{
        marginTop: 52, height: 1, zIndex: 1,
        background: 'linear-gradient(90deg, transparent, rgba(255,255,255,0.08), transparent)',
        animation: 'divider-grow 0.6s ease-out 1.4s both',
        width: 340,
      }} />

      {/* Grade tag */}
      <div style={{
        marginTop: 20, fontSize: 11, fontWeight: 700, letterSpacing: '0.15em',
        textTransform: 'uppercase', color: 'rgba(255,255,255,0.2)', zIndex: 1,
        animation: 'header-drop 0.5s ease-out 1.5s both',
      }}>
        Ranked · Grade {grade?.replace('G', '') ?? '?'}
      </div>
    </div>
  );
}

const QUEUE_DIAMONDS = [
  { left: '8%',  top: '15%', size: 10, dur: '12s', delay: '0s'   },
  { left: '22%', top: '68%', size: 7,  dur: '15s', delay: '2s'   },
  { left: '52%', top: '20%', size: 13, dur: '11s', delay: '1s'   },
  { left: '68%', top: '72%', size: 9,  dur: '14s', delay: '3s'   },
  { left: '84%', top: '35%', size: 11, dur: '13s', delay: '0.5s' },
  { left: '40%', top: '82%', size: 8,  dur: '10s', delay: '4s'   },
];

function FindingScreen({ elapsed, grade, onBack }) {
  const [dots, setDots] = useState('');
  const [playersOnline, setPlayersOnline] = useState(null);

  useEffect(() => {
    const t = setInterval(() => setDots(d => d.length >= 3 ? '' : d + '.'), 400);
    return () => clearInterval(t);
  }, []);

  useEffect(() => {
    const fetchCount = () => {
      fetch(`${API}/online-count`)
        .then(r => r.json())
        .then(d => setPlayersOnline(d.online ?? 0))
        .catch(() => {});
    };
    fetchCount();
    const t = setInterval(fetchCount, 30000);
    return () => clearInterval(t);
  }, []);

  const minutes = Math.floor(elapsed / 60);
  const seconds = elapsed % 60;
  const gradeNum = grade?.replace('G', '') ?? '?';

  return (
    <div style={{ minHeight: '100vh', position: 'relative', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', fontFamily: 'system-ui,sans-serif', overflow: 'hidden' }}>
      <style>{`
        @keyframes spinCW  { to { transform: rotate(360deg);  } }
        @keyframes spinCCW { to { transform: rotate(-360deg); } }
      `}</style>

      {/* Arena background */}
      <div className="arena-bg">
        <div className="arena-grain" />
        <div className="arena-shapes">
          {QUEUE_DIAMONDS.map((d, i) => (
            <div
              key={i}
              className="shape shape--diamond"
              style={{
                left: d.left, top: d.top,
                width: d.size, height: d.size,
                animationDuration: d.dur, animationDelay: d.delay,
                opacity: 0.35,
              }}
            />
          ))}
        </div>
      </div>

      {/* Content */}
      <div style={{ position: 'relative', zIndex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 24 }}>

        {/* Two counter-rotating rings */}
        <div style={{ position: 'relative', width: 80, height: 80 }}>
          <div style={{
            position: 'absolute', inset: 0, borderRadius: '50%',
            border: '3.5px solid rgba(245,197,24,0.12)',
            borderTopColor: '#f5c518', borderRightColor: 'rgba(245,197,24,0.45)',
            animation: 'spinCW 1.2s linear infinite',
          }} />
          <div style={{
            position: 'absolute', inset: 13, borderRadius: '50%',
            border: '3px solid rgba(79,195,247,0.12)',
            borderTopColor: '#4fc3f7', borderLeftColor: 'rgba(79,195,247,0.45)',
            animation: 'spinCCW 0.85s linear infinite',
          }} />
          <div style={{
            position: 'absolute', top: '50%', left: '50%',
            transform: 'translate(-50%,-50%)',
            width: 7, height: 7, borderRadius: '50%',
            background: '#f5c518',
            boxShadow: '0 0 10px rgba(245,197,24,0.9)',
          }} />
        </div>

        {/* Grade label */}
        <p style={{
          fontSize: 11, fontWeight: 700, letterSpacing: '0.22em',
          textTransform: 'uppercase', color: 'rgba(245,197,24,0.45)',
          margin: 0,
        }}>
          Grade {gradeNum} · Ranked
        </p>

        {/* Heading */}
        <h2 style={{ fontSize: 22, fontWeight: 700, color: '#eceef8', margin: 0, letterSpacing: '0.01em' }}>
          Searching for opponent{dots}
        </h2>

        {/* Players online */}
        <p style={{
          fontSize: 13, color: 'rgba(245,197,24,0.55)',
          margin: 0, letterSpacing: '0.04em',
        }}>
          {playersOnline !== null ? `${playersOnline.toLocaleString()} ${playersOnline === 1 ? 'player' : 'players'} online` : 'finding players...'}
        </p>

        {/* Elapsed timer — large gold */}
        <div style={{
          fontSize: 48, fontWeight: 700,
          color: '#f5c518', fontFamily: 'monospace',
          letterSpacing: '0.06em', lineHeight: 1,
          textShadow: '0 0 28px rgba(245,197,24,0.35)',
        }}>
          {String(minutes).padStart(2, '0')}:{String(seconds).padStart(2, '0')}
        </div>

        {/* Back button */}
        <button
          onClick={onBack}
          style={{
            marginTop: 8, padding: '10px 32px',
            fontSize: 14, fontWeight: 600,
            background: 'rgba(255,255,255,0.05)',
            color: 'rgba(255,255,255,0.45)',
            border: '1px solid rgba(255,255,255,0.12)',
            borderRadius: 999, cursor: 'pointer',
            fontFamily: 'system-ui,sans-serif',
            transition: 'background 0.15s, border-color 0.15s, color 0.15s',
          }}
          onMouseEnter={e => {
            e.currentTarget.style.background = 'rgba(255,255,255,0.09)';
            e.currentTarget.style.borderColor = 'rgba(255,255,255,0.25)';
            e.currentTarget.style.color = 'rgba(255,255,255,0.75)';
          }}
          onMouseLeave={e => {
            e.currentTarget.style.background = 'rgba(255,255,255,0.05)';
            e.currentTarget.style.borderColor = 'rgba(255,255,255,0.12)';
            e.currentTarget.style.color = 'rgba(255,255,255,0.45)';
          }}
        >
          ‹ Back to Dashboard
        </button>
      </div>
    </div>
  );
}

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

  const [myName, setMyName] = useState(() => getNameFromToken());
  const [myAvatar, setMyAvatar] = useState(() => getAvatarFromToken());
  const [queueElapsed, setQueueElapsed] = useState(0);
  const [matchData, setMatchData] = useState(null);

  const pollRef = useRef(null);
  const joinedRef = useRef(false);
  const completedRef = useRef(false);
  const leaveTimerRef = useRef(null);
  const leavingRef = useRef(false);

  // Elapsed timer — stop once matched
  useEffect(() => {
    if (matchData) return;
    const id = setInterval(() => setQueueElapsed(e => e + 1), 1000);
    return () => clearInterval(id);
  }, [matchData]);

  // Fetch own user info
  useEffect(() => {
    fetch(`${API}/auth/me`, { headers: authHeaders() })
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (!data) return;
        setMyName(data.username ?? data.displayName ?? 'You');
        setMyAvatar(data.avatarUrl ?? null);
      })
      .catch(() => {});
  }, []);

  // Join queue on mount
  useEffect(() => {
    // Cancel any pending leave from a previous mount (handles StrictMode double-invoke)
    if (leaveTimerRef.current) {
      clearTimeout(leaveTimerRef.current);
      leaveTimerRef.current = null;
    }
    // Reset leaving flag so callbacks work on this mount
    leavingRef.current = false;
    joinedRef.current = false;
    completedRef.current = false;

    fetch(`${API}/queue/join`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', ...authHeaders() },
      body: JSON.stringify({ grade }),
    })
      .then(r => {
        if (r.status === 401) { sessionStorage.removeItem('ranked_token'); navigate('/'); return null; }
        return r.json();
      })
      .then(data => {
        if (!data || leavingRef.current) return;
        joinedRef.current = true;
        if (data.status === 'waiting') {
          pollQueue();
        } else if (data.status === 'matched') {
          fetchMatchData();
        }
      })
      .catch(() => {});

    return () => {
      leavingRef.current = true;
      clearInterval(pollRef.current);
      if (joinedRef.current && !completedRef.current) {
        leaveTimerRef.current = setTimeout(() => {
          fetch(`${API}/queue/leave`, { method: 'DELETE', headers: authHeaders() }).catch(() => {});
        }, 0);
      }
    };
  }, [grade, navigate]);

  function pollQueue() {
    pollRef.current = setInterval(() => {
      fetch(`${API}/queue/status`, { headers: authHeaders() })
        .then(r => {
          if (r.status === 401) { sessionStorage.removeItem('ranked_token'); navigate('/'); return null; }
          return r.json();
        })
        .then(data => {
          if (!data || leavingRef.current) return;
          if (data.status === 'matched') {
            clearInterval(pollRef.current);
            showMatchup(data);
          } else if (data.status === 'not_in_queue') {
            clearInterval(pollRef.current);
            fetch(`${API}/queue/join`, {
              method: 'POST',
              headers: { 'Content-Type': 'application/json', ...authHeaders() },
              body: JSON.stringify({ grade }),
            })
              .then(r => {
                if (r.status === 401) { sessionStorage.removeItem('ranked_token'); navigate('/'); return null; }
                return r.json();
              })
              .then(d => {
                if (!d || leavingRef.current) return;
                if (d.status === 'waiting') pollQueue();
                else if (d.status === 'matched') showMatchup(d);
              })
              .catch(() => {});
          }
        })
        .catch(() => {});
    }, 1000);
  }

  function fetchMatchData() {
    fetch(`${API}/queue/status`, { headers: authHeaders() })
      .then(r => r.json())
      .then(data => {
        if (!leavingRef.current && data.status === 'matched') {
          showMatchup(data);
        }
      })
      .catch(() => {});
  }

  function showMatchup(data) {
    clearInterval(pollRef.current);
    completedRef.current = true;
    setMatchData(data);
  }

  const goToGame = useCallback(() => {
    navigate('/ranked-game', {
      state: {
        gameId: matchData.gameId,
        questions: matchData.questions,
        opponentName: matchData.opponent.username ?? matchData.opponent.displayName,
        opponentAvatar: matchData.opponent.avatarUrl,
        myName,
        myAvatar,
        grade,
      },
    });
  }, [matchData, myName, myAvatar, grade, navigate]);

  if (!VALID_GRADES.has(grade)) return <Navigate to="/dashboard" replace />;

  if (matchData) {
    return (
      <MatchFoundScreen
        myName={myName}
        myAvatar={myAvatar}
        opponentName={matchData.opponent.username ?? matchData.opponent.displayName}
        opponentAvatar={matchData.opponent.avatarUrl}
        grade={grade}
        onDone={goToGame}
      />
    );
  }

  return <FindingScreen elapsed={queueElapsed} grade={grade} onBack={() => navigate('/dashboard')} />;
}
