'use client';

import { useEffect, useState, use } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@/contexts/AuthContext';
import { useParlay } from '@/contexts/ParlayContext';
import GradeCard, { GradePill } from '@/components/GradeCard';
import EmptyState from '@/components/vyndr/EmptyState';

type Sport = 'NBA' | 'MLB' | 'WNBA';

interface Player {
  name: string;
  position?: string;
  injury_status?: 'OUT' | 'DOUBTFUL' | 'QUESTIONABLE' | null;
}

interface GameDetail {
  id: string;
  sport: Sport;
  away: string;
  home: string;
  start_time: string;
  spread?: number;
  spread_favorite?: 'home' | 'away';
  total?: number;
  moneyline_home?: number;
  moneyline_away?: number;
  away_lineup?: Player[];
  home_lineup?: Player[];
  pace?: number;
  pace_rank?: number;
  matchup_notes?: string[];
}

interface PropEntry {
  id: string;
  player: string;
  stat: string;
  line: number;
  direction: 'over' | 'under';
  grade: string;
  projection?: number;
  confidence?: number;
  sample_size?: number;
  factors?: Record<string, string>;
  kill_conditions?: { code: string; reason: string }[];
  reasoning?: string;
  historical_hit_rate?: number;
  alt_lines?: { line: number; grade: string; hit_rate?: number }[];
}

// Session 39 (QA.1) — resolve to sport tokens instead of duplicate literals.
const SPORT_COLOR: Record<Sport, string> = {
  NBA: 'var(--s-nba)',
  MLB: 'var(--s-mlb)',
  WNBA: 'var(--s-wnba)',
};

export default function GamePage({ params }: { params: Promise<{ id: string }> }) {
  const { id } = use(params);
  const router = useRouter();
  const { user, tier, loading: authLoading } = useAuth();
  const { addLeg, open } = useParlay();

  const [game, setGame] = useState<GameDetail | null>(null);
  const [props, setProps] = useState<PropEntry[] | null>(null);
  const [expanded, setExpanded] = useState<string | null>(null);
  const [error, setError] = useState('');

  useEffect(() => {
    if (!authLoading && !user) router.replace(`/login?next=/game/${id}`);
  }, [authLoading, user, id, router]);

  useEffect(() => {
    let cancelled = false;
    setError('');
    Promise.all([
      fetch(`/api/games/${id}`).then((r) => r.json()).catch(() => null),
      fetch(`/api/games/${id}/props`).then((r) => r.json()).catch(() => ({ props: [] })),
    ]).then(([g, p]) => {
      if (cancelled) return;
      if (!g || g.error) {
        setError(g?.error || 'Game not found.');
        return;
      }
      setGame(g);
      setProps(Array.isArray(p?.props) ? p.props : []);
    });
    return () => {
      cancelled = true;
    };
  }, [id]);

  if (authLoading || !user || (!game && !error)) {
    return (
      <section style={{ minHeight: '60vh', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <p className="mono" style={{ color: 'var(--text-tertiary)' }}>Loading game…</p>
      </section>
    );
  }

  if (error) {
    // DS5 (#20) — unified empty/error surface (was a bare heading + link).
    return (
      <EmptyState
        code="GAME NOT FOUND"
        title="That matchup isn't on the board."
        message="It isn't on tonight's slate — maybe the line moved off the board. The Slate has what's live now."
        actions={[{ label: '← Back to the Slate', href: '/dashboard', primary: true }]}
      />
    );
  }

  if (!game) return null;

  return (
    <section style={{ maxWidth: 900, margin: '0 auto', padding: '24px 16px 120px' }}>
      {/* Back nav */}
      <button
        onClick={() => router.push('/dashboard')}
        className="btn-ghost"
        style={{ padding: '6px 12px', fontSize: 12, marginBottom: 16 }}
      >
        ← Slate
      </button>

      {/* Game header */}
      <header
        className="surface diagonal-cut-strong animate-fade-up"
        style={{
          padding: 24,
          marginBottom: 16,
          borderColor: SPORT_COLOR[game.sport],
          background: 'var(--bg-elevated)',
        }}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
          <span
            className="mono"
            style={{
              fontSize: 11,
              fontWeight: 700,
              padding: '2px 10px',
              borderRadius: 999,
              background: `${SPORT_COLOR[game.sport]}1F`,
              color: SPORT_COLOR[game.sport],
              letterSpacing: '0.08em',
            }}
          >
            {game.sport}
          </span>
          <span className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>
            {formatTime(game.start_time)}
          </span>
        </div>
        <h1 style={{ fontSize: 28, fontWeight: 700, letterSpacing: '-0.02em', marginBottom: 12 }}>
          {game.away} <span style={{ color: 'var(--text-tertiary)' }}>@</span> {game.home}
        </h1>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(140px, 1fr))', gap: 8 }}>
          {game.spread != null && (
            <Stat label="Spread" value={`${game.spread_favorite === 'home' ? game.home : game.away} ${game.spread}`} />
          )}
          {game.total != null && <Stat label="Total" value={game.total.toString()} />}
          {game.moneyline_home != null && (
            <Stat label="Moneyline" value={`${game.home} ${formatOdds(game.moneyline_home)} / ${game.away} ${formatOdds(game.moneyline_away ?? 0)}`} />
          )}
        </div>
      </header>

      {/* Starting lineups */}
      {(game.away_lineup?.length || game.home_lineup?.length) && (
        <Card title="Starting lineups">
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16 }}>
            <Lineup teamName={game.away} players={game.away_lineup ?? []} />
            <Lineup teamName={game.home} players={game.home_lineup ?? []} />
          </div>
        </Card>
      )}

      {/* Matchup stats */}
      {game.matchup_notes && game.matchup_notes.length > 0 && (
        <Card title="Key matchup stats">
          <ul style={{ display: 'grid', gap: 8 }}>
            {game.matchup_notes.map((note, i) => (
              <li key={i} style={{ fontSize: 14, color: 'var(--text-secondary)' }}>
                · {note}
              </li>
            ))}
          </ul>
        </Card>
      )}

      {/* Props list */}
      <Card title={`All props for this game`} subtitle={`${props?.length ?? 0} graded`}>
        {props === null ? (
          <p style={{ color: 'var(--text-tertiary)' }}>Loading props…</p>
        ) : props.length === 0 ? (
          <p style={{ color: 'var(--text-secondary)', fontSize: 14 }}>
            No props posted for this game yet. Check back closer to game time.
          </p>
        ) : (
          <ul style={{ display: 'grid', gap: 8 }}>
            {props.map((p) => {
              const isOpen = expanded === p.id;
              return (
                <li key={p.id} className="surface" style={{ overflow: 'hidden' }}>
                  <div
                    style={{
                      padding: 14,
                      display: 'grid',
                      gridTemplateColumns: '1fr auto auto',
                      gap: 12,
                      alignItems: 'center',
                      cursor: 'pointer',
                    }}
                    onClick={() => setExpanded(isOpen ? null : p.id)}
                  >
                    <div>
                      <div style={{ fontSize: 14, fontWeight: 600 }}>{p.player}</div>
                      <div className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize' }}>
                        {p.direction} {p.line} {p.stat.replace(/_/g, ' ')}
                      </div>
                    </div>
                    <GradePill grade={p.grade} />
                    <button
                      onClick={(e) => {
                        e.stopPropagation();
                        addLeg({
                          sport: game.sport,
                          player: p.player,
                          stat: p.stat,
                          line: p.line,
                          direction: p.direction,
                          grade: p.grade,
                          confidence: p.confidence ?? 55,
                        });
                        open();
                      }}
                      className="btn-ghost"
                      style={{ padding: '6px 12px', fontSize: 11 }}
                      aria-label="Add to parlay"
                    >
                      +
                    </button>
                  </div>
                  {isOpen && (
                    <div style={{ padding: 16, borderTop: '1px solid var(--border)' }}>
                      <GradeCard
                        sport={game.sport}
                        player={p.player}
                        stat={p.stat}
                        line={p.line}
                        direction={p.direction}
                        grade={p.grade}
                        projection={p.projection}
                        confidence={p.confidence}
                        sample_size={p.sample_size}
                        factors={p.factors}
                        alt_lines={p.alt_lines}
                        kill_conditions={p.kill_conditions}
                        reasoning={p.reasoning}
                        historical_hit_rate={p.historical_hit_rate}
                        tier={tier}
                        onUpgradeClick={(target) => router.push(`/api/checkout?tier=${target}`)}
                      />
                    </div>
                  )}
                </li>
              );
            })}
          </ul>
        )}
      </Card>

      <div style={{ marginTop: 24 }}>
        <a
          href={`/scan?sport=${game.sport}`}
          className="btn-primary"
          style={{ padding: '12px 24px' }}
        >
          Read a custom prop →
        </a>
      </div>
    </section>
  );
}

function Card({ title, subtitle, children }: { title: string; subtitle?: string; children: React.ReactNode }) {
  return (
    <section className="surface diagonal-cut animate-fade-up" style={{ padding: 20, marginBottom: 16 }}>
      <header style={{ marginBottom: 12, display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
        <h2 style={{ fontSize: 14, fontWeight: 700, letterSpacing: '-0.01em' }}>{title}</h2>
        {subtitle && (
          <span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>{subtitle}</span>
        )}
      </header>
      {children}
    </section>
  );
}

function Stat({ label, value }: { label: string; value: string }) {
  return (
    <div style={{ padding: '10px 14px', background: 'var(--bg-surface)', borderRadius: 10, border: '1px solid var(--border)' }}>
      <div className="mono" style={{ fontSize: 10, color: 'var(--text-tertiary)', letterSpacing: '0.08em' }}>
        {label.toUpperCase()}
      </div>
      <div className="mono" style={{ fontSize: 13, fontWeight: 700, marginTop: 4 }}>
        {value}
      </div>
    </div>
  );
}

function Lineup({ teamName, players }: { teamName: string; players: Player[] }) {
  return (
    <div>
      <div className="mono" style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-tertiary)', marginBottom: 8 }}>
        {teamName.toUpperCase()}
      </div>
      <ul style={{ display: 'grid', gap: 6 }}>
        {players.map((p) => (
          <li key={p.name} style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, gap: 8 }}>
            <span>{p.name}</span>
            <span className="mono" style={{
              fontSize: 11,
              color: p.injury_status === 'OUT' ? 'var(--grade-d)' : p.injury_status ? 'var(--grade-c)' : 'var(--text-tertiary)',
            }}>
              {p.injury_status ? `${p.injury_status === 'OUT' ? '❌' : '⚠'} ${p.injury_status}` : p.position}
            </span>
          </li>
        ))}
      </ul>
    </div>
  );
}

function formatTime(iso: string): string {
  try {
    return new Date(iso).toLocaleString([], { weekday: 'short', hour: 'numeric', minute: '2-digit', timeZoneName: 'short' });
  } catch {
    return iso;
  }
}

function formatOdds(odds: number): string {
  if (!odds) return '—';
  return odds > 0 ? `+${odds}` : `${odds}`;
}
