'use client';

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

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

interface Game {
  id: string;
  away: string;
  home: string;
  start_time: string;
  sport: Sport;
  status: 'scheduled' | 'live' | 'final';
  prop_count?: number;
  ab_grade_count?: number;
  injury_note?: string;
}

interface TopGrade {
  player: string;
  stat: string;
  line: number;
  direction: 'over' | 'under';
  sport: Sport;
  grade: string;
  confidence?: number;
}

interface ParlayLegStat {
  player: string;
  stat: string;
  line: number;
  direction: 'over' | 'under';
  sport: Sport;
  grade?: string;
  parlay_count: number;
}

interface RecentScan {
  id: string;
  player_name: string;
  stat: string;
  line: number;
  direction: 'over' | 'under';
  grade: string;
  sport: Sport;
  created_at: string;
}

const SPORT_TABS: Sport[] = ['NBA', 'MLB', 'WNBA'];

const SPORT_COLOR: Record<Sport, string> = {
  NBA: '#E94B3C',
  MLB: '#1E90FF',
  WNBA: '#FFB347',
};

export default function DashboardPage() {
  const router = useRouter();
  const { user, tier, scansRemaining, loading: authLoading } = useAuth();
  const { addLeg, open } = useParlay();

  const [sport, setSport] = useState<Sport>('NBA');
  const [games, setGames] = useState<Game[] | null>(null);
  const [topGrades, setTopGrades] = useState<TopGrade[] | null>(null);
  const [mostParlayed, setMostParlayed] = useState<ParlayLegStat[] | null>(null);
  const [recentScans, setRecentScans] = useState<RecentScan[] | null>(null);

  // Gate
  useEffect(() => {
    if (!authLoading && !user) router.replace('/login?next=/dashboard');
  }, [authLoading, user, router]);

  // Fetch slate when sport changes
  useEffect(() => {
    let cancelled = false;
    setGames(null);
    setTopGrades(null);

    Promise.all([
      fetch(`/api/games/tonight?sport=${sport}`).then((r) => r.json()).catch(() => ({ games: [] })),
      fetch(`/api/props/top-graded?sport=${sport}`).then((r) => r.json()).catch(() => ({ props: [] })),
    ]).then(([gamesData, gradesData]) => {
      if (cancelled) return;
      setGames(Array.isArray(gamesData?.games) ? gamesData.games : []);
      setTopGrades(Array.isArray(gradesData?.props) ? gradesData.props.slice(0, 10) : []);
    });

    return () => {
      cancelled = true;
    };
  }, [sport]);

  // Most parlayed + recent scans don't depend on sport
  useEffect(() => {
    fetch('/api/props/most-parlayed')
      .then((r) => r.json())
      .then((data) => setMostParlayed(Array.isArray(data?.props) ? data.props.slice(0, 5) : []))
      .catch(() => setMostParlayed([]));

    if (user) {
      const token = typeof window !== 'undefined' ? localStorage.getItem('sb-token') : null;
      fetch('/api/user/recent-scans', {
        headers: token ? { Authorization: `Bearer ${token}` } : {},
      })
        .then((r) => r.json())
        .then((data) => setRecentScans(Array.isArray(data?.scans) ? data.scans.slice(0, 5) : []))
        .catch(() => setRecentScans([]));
    }
  }, [user]);

  const gameCountsBySport = useMemo(() => {
    // Updated whenever the sport's slate refreshes. We only know counts for
    // the current sport — others show a dash until clicked.
    return { [sport]: games?.length ?? 0 } as Partial<Record<Sport, number>>;
  }, [sport, games]);

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

  const isFirstTimer = recentScans?.length === 0;
  const slateEmpty = games?.length === 0;

  return (
    <section style={{ maxWidth: 1100, margin: '0 auto', padding: '24px 16px 120px' }}>
      {/* Top welcome strip */}
      <header style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 24, gap: 16, flexWrap: 'wrap' }}>
        <div>
          <h1 style={{ fontSize: 26, fontWeight: 700, letterSpacing: '-0.02em' }}>
            Tonight&apos;s slate
          </h1>
          <p className="mono" style={{ fontSize: 12, color: 'var(--text-tertiary)', letterSpacing: '0.05em', marginTop: 4 }}>
            {new Date().toLocaleDateString([], { weekday: 'long', month: 'short', day: 'numeric' }).toUpperCase()}
          </p>
        </div>
        {tier === 'free' && scansRemaining != null && (
          <div
            className="mono"
            style={{
              padding: '8px 14px',
              borderRadius: 999,
              background: 'var(--bg-surface)',
              border: '1px solid var(--border)',
              fontSize: 12,
              color: scansRemaining <= 1 ? 'var(--grade-c)' : 'var(--text-secondary)',
            }}
          >
            {scansRemaining}/5 READS · MO
          </div>
        )}
      </header>

      {/* Sport tabs */}
      <div role="tablist" aria-label="Sport" style={{ display: 'flex', gap: 4, marginBottom: 32, borderBottom: '1px solid var(--border)' }}>
        {SPORT_TABS.map((s) => {
          const active = s === sport;
          const count = gameCountsBySport[s];
          return (
            <button
              key={s}
              role="tab"
              aria-selected={active}
              onClick={() => setSport(s)}
              style={{
                padding: '12px 20px',
                background: 'transparent',
                border: 'none',
                borderBottom: `2px solid ${active ? SPORT_COLOR[s] : 'transparent'}`,
                color: active ? 'var(--text-primary)' : 'var(--text-secondary)',
                fontFamily: 'inherit',
                fontWeight: active ? 600 : 500,
                fontSize: 14,
                cursor: 'pointer',
                marginBottom: -1,
              }}
            >
              {s}{' '}
              <span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginLeft: 4 }}>
                {active && count != null ? `(${count})` : '·'}
              </span>
            </button>
          );
        })}
      </div>

      {/* Top grades horizontal scroll */}
      <Section
        title="Top grades tonight"
        subtitle="The A-tier picks. Tap to read or add to parlay."
      >
        {topGrades === null ? (
          <SkeletonRow />
        ) : topGrades.length === 0 ? (
          <p style={emptyCopy}>No grades yet. The model is waiting on lines.</p>
        ) : (
          <div
            style={{
              display: 'flex',
              gap: 12,
              overflowX: 'auto',
              padding: '4px 4px 12px',
              scrollSnapType: 'x mandatory',
            }}
          >
            {topGrades.map((g, i) => (
              <button
                key={`${g.player}-${g.stat}-${i}`}
                onClick={() => router.push(`/scan?sport=${g.sport}&player=${encodeURIComponent(g.player)}&stat=${g.stat}&line=${g.line}`)}
                className="surface diagonal-cut surface-hover"
                style={{
                  minWidth: 200,
                  padding: 16,
                  textAlign: 'left',
                  scrollSnapAlign: 'start',
                  cursor: 'pointer',
                  border: '1px solid var(--border)',
                  borderRadius: 16,
                  background: 'var(--bg-surface)',
                  color: 'inherit',
                  fontFamily: 'inherit',
                }}
              >
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 12 }}>
                  <SportPill sport={g.sport} />
                  <GradePill grade={g.grade} />
                </div>
                <h3 style={{ fontSize: 14, fontWeight: 600, marginBottom: 4 }}>{g.player}</h3>
                <p className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize' }}>
                  {g.direction} {g.line} {g.stat.replace(/_/g, ' ')}
                </p>
              </button>
            ))}
          </div>
        )}
      </Section>

      {/* Tonight's games */}
      <Section title={`Tonight's ${sport} games`} subtitle={slateEmpty ? null : `${games?.length ?? 0} games tipping`}>
        {games === null ? (
          <SkeletonRow stacked />
        ) : games.length === 0 ? (
          <div
            className="surface diagonal-cut tex-scan"
            style={{ padding: 32, textAlign: 'center', display: 'grid', gap: 8, justifyItems: 'center' }}
          >
            <p className="lbl" style={{ color: 'var(--grade-c)' }}>NO SLATE</p>
            <h3 style={{ fontSize: 18, fontWeight: 700 }}>No games on the slate tonight.</h3>
            <p style={{ color: 'var(--text-1)', fontSize: 14, maxWidth: 420 }}>
              Check the Ledger to review past grades, or explore the Leaderboard.
            </p>
            <div style={{ display: 'flex', gap: 12, marginTop: 8 }}>
              <a href="/ledger" className="btn-primary" style={{ padding: '10px 18px' }}>View the Ledger →</a>
            </div>
          </div>
        ) : (
          <div style={{ display: 'grid', gap: 12 }}>
            {games.map((g, idx) => (
              <a
                key={g.id}
                href={`/game/${g.id}`}
                className={`surface surface-hover diagonal-cut animate-fade-up stagger-${(idx % 6) + 1}`}
                style={{
                  padding: 20,
                  textDecoration: 'none',
                  color: 'inherit',
                  display: 'grid',
                  gridTemplateColumns: '1fr auto',
                  gap: 12,
                  alignItems: 'center',
                  border: isFirstTimer && idx === 0 ? '1px solid var(--grade-a)' : '1px solid var(--border)',
                  boxShadow: isFirstTimer && idx === 0 ? '0 0 0 4px var(--accent-glow)' : 'none',
                }}
              >
                <div>
                  <div style={{ fontSize: 16, fontWeight: 600, marginBottom: 4 }}>
                    {g.away} @ {g.home}
                  </div>
                  <div className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)' }}>
                    {formatTime(g.start_time)}
                    {g.injury_note ? ` · ${g.injury_note}` : ' · Full squad'}
                    {g.ab_grade_count != null ? ` · ${g.ab_grade_count} A/B grades` : ''}
                  </div>
                </div>
                <div className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', letterSpacing: '0.08em' }}>
                  {g.prop_count ?? '—'} props →
                </div>
              </a>
            ))}
          </div>
        )}
      </Section>

      {/* Most parlayed tonight */}
      <Section title="Most parlayed tonight" subtitle="What other bettors are stacking." right={<span className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)' }}>🔥 TRENDING</span>}>
        {mostParlayed === null ? (
          <SkeletonRow />
        ) : mostParlayed.length === 0 ? (
          <p style={emptyCopy}>No parlays built yet tonight. Be the first.</p>
        ) : (
          <ul style={{ display: 'grid', gap: 8 }}>
            {mostParlayed.map((p, i) => (
              <li key={`${p.player}-${p.stat}-${i}`}
                className="surface"
                style={{
                  padding: 14,
                  display: 'grid',
                  gridTemplateColumns: '1fr auto auto',
                  gap: 12,
                  alignItems: 'center',
                }}
              >
                <div>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>🔥 {p.player}</div>
                  <div className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize' }}>
                    {p.sport} · {p.direction} {p.line} {p.stat.replace(/_/g, ' ')}
                  </div>
                </div>
                {p.grade && <GradePill grade={p.grade} />}
                <button
                  className="btn-ghost"
                  style={{ padding: '6px 12px', fontSize: 12 }}
                  onClick={() => {
                    addLeg({
                      sport: p.sport,
                      player: p.player,
                      stat: p.stat,
                      line: p.line,
                      direction: p.direction,
                      grade: p.grade ?? 'B',
                      confidence: 55,
                    });
                    open();
                  }}
                >
                  + Parlay
                </button>
              </li>
            ))}
          </ul>
        )}
      </Section>

      {/* Recent scans OR first-timer onboarding */}
      <Section title={isFirstTimer ? 'Your first read' : 'Your recent reads'} subtitle={null}>
        {recentScans === null ? (
          <SkeletonRow />
        ) : recentScans.length === 0 ? (
          <div
            className="surface diagonal-cut-strong"
            style={{
              padding: 32,
              textAlign: 'center',
              border: '1px solid var(--accent-light)',
              background: 'var(--bg-elevated)',
            }}
          >
            <p className="mono" style={{ fontSize: 11, fontWeight: 700, letterSpacing: '0.08em', color: 'var(--grade-a)', marginBottom: 12 }}>
              WELCOME TO THE LEDGER
            </p>
            <h3 style={{ fontSize: 20, fontWeight: 700, marginBottom: 8 }}>
              Tonight&apos;s slate is loaded. {games?.length ?? 0} {games?.length === 1 ? 'game' : 'games'} across 3 sports.
            </h3>
            <p style={{ color: 'var(--text-secondary)', fontSize: 14, marginBottom: 20 }}>
              Pick a game and read your first prop — it&apos;s on us.
            </p>
            <a href="/scan" className="btn-primary" style={{ padding: '12px 24px' }}>
              Run a read →
            </a>
          </div>
        ) : (
          <ul style={{ display: 'grid', gap: 8 }}>
            {recentScans.map((s) => (
              <li key={s.id}
                className="surface"
                style={{
                  padding: 14,
                  display: 'grid',
                  gridTemplateColumns: '1fr auto',
                  gap: 12,
                  alignItems: 'center',
                }}
              >
                <div>
                  <div style={{ fontSize: 14, fontWeight: 600 }}>{s.player_name}</div>
                  <div className="mono" style={{ fontSize: 12, color: 'var(--text-secondary)', textTransform: 'capitalize' }}>
                    {s.sport} · {s.direction} {s.line} {s.stat.replace(/_/g, ' ')}
                  </div>
                </div>
                <GradePill grade={s.grade} />
              </li>
            ))}
          </ul>
        )}
      </Section>
    </section>
  );
}

function Section({ title, subtitle, right, children }: { title: string; subtitle: string | null; right?: React.ReactNode; children: React.ReactNode }) {
  return (
    <section style={{ marginBottom: 40 }}>
      <header style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 12 }}>
        <div>
          <h2 style={{ fontSize: 16, fontWeight: 700, letterSpacing: '-0.01em' }}>{title}</h2>
          {subtitle && (
            <p className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', letterSpacing: '0.05em', marginTop: 2 }}>
              {subtitle}
            </p>
          )}
        </div>
        {right}
      </header>
      {children}
    </section>
  );
}

function SportPill({ sport }: { sport: Sport }) {
  return (
    <span
      className="mono"
      style={{
        fontSize: 10,
        fontWeight: 700,
        padding: '2px 8px',
        borderRadius: 999,
        background: `${SPORT_COLOR[sport]}1F`,
        color: SPORT_COLOR[sport],
      }}
    >
      {sport}
    </span>
  );
}

function SkeletonRow({ stacked = false }: { stacked?: boolean }) {
  if (stacked) {
    return (
      <div style={{ display: 'grid', gap: 12 }}>
        {[0, 1, 2].map((i) => (
          <div
            key={i}
            style={{
              height: 80,
              borderRadius: 16,
              background: 'linear-gradient(90deg, var(--bg-surface) 0%, var(--bg-surface-hover) 50%, var(--bg-surface) 100%)',
              backgroundSize: '200% 100%',
              animation: 'shimmer 1.5s linear infinite',
            }}
          />
        ))}
      </div>
    );
  }
  return (
    <div style={{ display: 'flex', gap: 12 }}>
      {[0, 1, 2, 3].map((i) => (
        <div
          key={i}
          style={{
            minWidth: 200,
            height: 110,
            borderRadius: 16,
            background: 'linear-gradient(90deg, var(--bg-surface) 0%, var(--bg-surface-hover) 50%, var(--bg-surface) 100%)',
            backgroundSize: '200% 100%',
            animation: 'shimmer 1.5s linear infinite',
          }}
        />
      ))}
    </div>
  );
}

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

const emptyCopy: React.CSSProperties = {
  padding: '24px 16px',
  textAlign: 'center',
  color: 'var(--text-secondary)',
  fontSize: 14,
  background: 'var(--bg-surface)',
  border: '1px solid var(--border)',
  borderRadius: 12,
};
