'use client';

import { useCallback, useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import SportSelector, { SoccerLeague, SportSelection } from '@/components/SportSelector';
import SoccerGradeResult, { SoccerGradeResultProps } from '@/components/SoccerGradeResult';
import { useAuth } from '@/contexts/AuthContext';

/**
 * /soccer — live soccer odds feed.
 *
 * Shows match cards for the selected league (defaults to World Cup
 * 2026). Each match expands to reveal player props grouped by stat
 * type. Clicking a prop hands it off to /scan for grading.
 *
 * Data path: this page → /api/odds/soccer/:league → Express
 * /api/odds/soccer/:league → odds-api. The Express route falls back
 * to cache when the API quota is low; the response carries `source:
 * 'cache' | 'live'` so we can tag the freshness.
 */

interface NormalizedProp {
  player: string;
  stat_type: string;
  line: number;
  direction: 'over' | 'under';
  book: string;
  odds: number;
  game_time?: string;
  home_team?: string;
  away_team?: string;
  fetched_at?: string;
}

interface GroupedProp {
  player: string;
  stat_type: string;
  line: number;
  game_time?: string;
  home_team?: string;
  away_team?: string;
  // best line per direction across books
  over?: { book: string; odds: number };
  under?: { book: string; odds: number };
}

interface OddsResponse {
  sport: string;
  updated_at?: string;
  source?: string;
  quota_remaining?: number;
  props: GroupedProp[];
  message?: string;
  error?: string;
}

// Group a flat props array by (player, stat_type, line) so each row
// represents a SINGLE prop with both directions next to each other.
// The Express response already does some grouping but ships per-direction
// rows — collapse them.
function groupProps(props: GroupedProp[]): GroupedProp[] {
  return props || [];
}

// Group props under their match for the card layout.
function groupByMatch(props: GroupedProp[]) {
  const matches = new Map<string, { home: string; away: string; time?: string; propsByStatType: Map<string, GroupedProp[]> }>();
  for (const p of props) {
    const home = p.home_team || '?';
    const away = p.away_team || '?';
    const key = `${home}__${away}__${p.game_time || ''}`;
    if (!matches.has(key)) {
      matches.set(key, { home, away, time: p.game_time, propsByStatType: new Map() });
    }
    const m = matches.get(key)!;
    const list = m.propsByStatType.get(p.stat_type) || [];
    list.push(p);
    m.propsByStatType.set(p.stat_type, list);
  }
  return Array.from(matches.values());
}

const STAT_LABELS: Record<string, string> = {
  goals: 'Anytime / Total Goals',
  shots_on_target: 'Shots on Target',
  shots: 'Total Shots',
  tackles: 'Tackles',
  cards: 'Cards',
  corners: 'Corners',
  saves: 'Saves',
  goals_conceded: 'Goals Conceded',
  passes: 'Passes',
  clean_sheet: 'Clean Sheet',
  assists: 'Assists',
};

function formatTime(iso?: string) {
  if (!iso) return '';
  try {
    const d = new Date(iso);
    return d.toLocaleString(undefined, {
      weekday: 'short', hour: 'numeric', minute: '2-digit',
    });
  } catch {
    return iso;
  }
}

export default function SoccerOddsPage() {
  const router = useRouter();
  const { session } = useAuth();
  const [selection, setSelection] = useState<SportSelection>({ sport: 'Soccer', league: 'wc' });
  const [data, setData] = useState<OddsResponse | null>(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [expanded, setExpanded] = useState<Set<string>>(new Set());

  const [scanning, setScanning] = useState(false);
  const [scanResult, setScanResult] = useState<SoccerGradeResultProps | null>(null);
  const [scanError, setScanError] = useState<string | null>(null);

  const league: SoccerLeague = selection.league || 'wc';

  // Redirect non-Soccer sport selections back to /scan — that page
  // owns NBA/MLB/WNBA. Soccer is the only one this page serves.
  useEffect(() => {
    if (selection.sport !== 'Soccer') {
      router.push('/scan');
    }
  }, [selection.sport, router]);

  async function gradeProp(player: string, stat_type: string, lineVal: number) {
    setScanError(null);
    setScanResult(null);
    setScanning(true);
    try {
      const res = await fetch('/api/scan', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          ...(session?.access_token ? { Authorization: `Bearer ${session.access_token}` } : {}),
        },
        body: JSON.stringify({
          sport: 'Soccer',
          player,
          stat: stat_type,
          line: lineVal,
          direction: 'over',
          book: 'draftkings',
        }),
      });
      const body = (await res.json().catch(() => ({}))) as Record<string, unknown> & { error?: string };
      if (!res.ok) {
        setScanError(body.error || 'The engine hit a wall. Try that read again.');
        setScanning(false);
        return;
      }
      const result: SoccerGradeResultProps = {
        player,
        stat_type,
        line: lineVal,
        direction: 'over',
        league,
        grade: String(body.grade || 'C'),
        confidence: typeof body.confidence === 'number' ? body.confidence : undefined,
        edge_pct: typeof body.edge_pct === 'number' ? body.edge_pct : undefined,
        reasoning: (body.reasoning as SoccerGradeResultProps['reasoning']) || undefined,
        kill_conditions_triggered: (body.kill_conditions_triggered as SoccerGradeResultProps['kill_conditions_triggered']) || [],
        tier_gated: !!body.tier_gated,
        upgrade_hint: typeof body.upgrade_hint === 'string' ? body.upgrade_hint : undefined,
        onUpgradeClick: () => router.push('/#pricing'),
        onClose: () => setScanResult(null),
      };
      setScanResult(result);
    } catch {
      setScanError('Network error. Try again.');
    } finally {
      setScanning(false);
    }
  }

  const fetchOdds = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const res = await fetch(`/api/odds/soccer/${league}`, { cache: 'no-store' });
      const body = (await res.json().catch(() => ({}))) as OddsResponse;
      if (!res.ok) {
        setError(body.error || 'Couldn’t load odds. Try again.');
        setData(null);
      } else {
        setData(body);
      }
    } catch {
      setError('Network error. Try again.');
      setData(null);
    } finally {
      setLoading(false);
    }
  }, [league]);

  useEffect(() => {
    fetchOdds();
  }, [fetchOdds]);

  const matches = data ? groupByMatch(groupProps(data.props)) : [];

  return (
    <main style={{ minHeight: '100vh', padding: '24px 16px 80px' }}>
      <div style={{ maxWidth: 1100, margin: '0 auto' }}>
        <header style={{ marginBottom: 24 }}>
          <h1 style={{ fontSize: 'clamp(24px, 3vw, 36px)', fontWeight: 700, letterSpacing: '-0.02em', marginBottom: 8 }}>
            Soccer odds
          </h1>
          <p style={{ color: 'var(--text-secondary)', fontSize: 14 }}>
            Live odds across our launch leagues. Click any prop to grade it through the VYNDR engine.
          </p>
        </header>

        <div style={{ marginBottom: 20 }}>
          <SportSelector
            initialSport="Soccer"
            initialLeague={league}
            onChange={(sel) => setSelection(sel)}
          />
        </div>

        {data?.source && (
          <p
            className="mono"
            style={{
              fontSize: 11,
              color: 'var(--text-tertiary)',
              marginBottom: 16,
              letterSpacing: '0.06em',
              textTransform: 'uppercase',
            }}
          >
            {data.updated_at ? `Updated ${formatTime(data.updated_at)} · ` : ''}
            source: {data.source}
            {typeof data.quota_remaining === 'number' ? ` · quota: ${data.quota_remaining}` : ''}
          </p>
        )}

        {loading && (
          <div style={{ padding: 40, textAlign: 'center', color: 'var(--text-tertiary)' }}>Loading odds…</div>
        )}

        {error && (
          <div
            role="alert"
            style={{
              padding: 16,
              border: '1px solid var(--grade-d, #ff5a5a)',
              color: 'var(--grade-d, #ff5a5a)',
              borderRadius: 8,
              marginBottom: 20,
            }}
          >
            {error}
          </div>
        )}

        {scanError && (
          <div
            role="alert"
            style={{
              padding: 12,
              border: '1px solid var(--grade-d, #ff5a5a)',
              color: 'var(--grade-d, #ff5a5a)',
              borderRadius: 6,
              marginBottom: 16,
              fontSize: 13,
            }}
          >
            {scanError}
          </div>
        )}

        {scanResult && (
          <SoccerGradeResult {...scanResult} />
        )}

        {!loading && !error && matches.length === 0 && (
          <div
            className="surface"
            style={{
              padding: 32,
              border: '1px solid var(--border)',
              borderRadius: 8,
              textAlign: 'center',
              color: 'var(--text-secondary)',
            }}
          >
            No live matches with props in this league right now.
            {league !== 'wc' && (
              <p style={{ fontSize: 13, marginTop: 8, color: 'var(--text-tertiary)' }}>
                Off-season or between matchdays — World Cup props are running through July 19, 2026.
              </p>
            )}
          </div>
        )}

        <div style={{ display: 'grid', gap: 16 }}>
          {matches.map((m, idx) => {
            const matchKey = `${m.home}-${m.away}-${idx}`;
            const isOpen = expanded.has(matchKey);
            return (
              <article
                key={matchKey}
                className="surface diagonal-cut"
                style={{
                  padding: 20,
                  border: '1px solid var(--border)',
                  background: 'var(--bg-surface)',
                  borderRadius: 8,
                }}
              >
                <button
                  type="button"
                  onClick={() => {
                    const next = new Set(expanded);
                    if (next.has(matchKey)) next.delete(matchKey);
                    else next.add(matchKey);
                    setExpanded(next);
                  }}
                  style={{
                    width: '100%',
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    background: 'transparent',
                    border: 0,
                    cursor: 'pointer',
                    color: 'inherit',
                    padding: 0,
                    textAlign: 'left',
                  }}
                >
                  <div>
                    <div style={{ fontSize: 18, fontWeight: 700, letterSpacing: '-0.01em' }}>
                      {m.away} <span style={{ color: 'var(--text-tertiary)' }}>vs</span> {m.home}
                    </div>
                    <div className="mono" style={{ fontSize: 11, color: 'var(--text-tertiary)', marginTop: 4, letterSpacing: '0.06em' }}>
                      {formatTime(m.time)} · {m.propsByStatType.size} stat type(s)
                    </div>
                  </div>
                  <span style={{ color: 'var(--text-secondary)', fontSize: 14 }}>{isOpen ? '−' : '+'}</span>
                </button>

                {isOpen && (
                  <div style={{ marginTop: 16, display: 'grid', gap: 12 }}>
                    {Array.from(m.propsByStatType.entries()).map(([statType, list]) => (
                      <section key={statType}>
                        <h3
                          className="mono"
                          style={{
                            fontSize: 11,
                            color: 'var(--grade-a)',
                            letterSpacing: '0.08em',
                            textTransform: 'uppercase',
                            marginBottom: 8,
                          }}
                        >
                          {STAT_LABELS[statType] || statType}
                        </h3>
                        <ul style={{ display: 'grid', gap: 6 }}>
                          {list.slice(0, 8).map((p, j) => (
                            <li
                              key={`${p.player}-${p.line}-${j}`}
                              style={{
                                display: 'flex',
                                justifyContent: 'space-between',
                                alignItems: 'center',
                                padding: '8px 12px',
                                border: '1px solid var(--border)',
                                borderRadius: 6,
                                background: 'var(--bg-elevated)',
                                fontSize: 14,
                              }}
                            >
                              <span style={{ fontWeight: 600 }}>{p.player}</span>
                              <span className="mono" style={{ color: 'var(--text-secondary)', fontSize: 13 }}>
                                {p.line.toFixed(1)}
                              </span>
                              <button
                                type="button"
                                onClick={() => gradeProp(p.player, statType, p.line)}
                                disabled={scanning}
                                className="btn-ghost"
                                style={{
                                  padding: '4px 12px',
                                  fontSize: 12,
                                  cursor: scanning ? 'not-allowed' : 'pointer',
                                  opacity: scanning ? 0.6 : 1,
                                }}
                              >
                                {scanning ? '…' : 'Grade'}
                              </button>
                            </li>
                          ))}
                        </ul>
                      </section>
                    ))}
                  </div>
                )}
              </article>
            );
          })}
        </div>
      </div>
    </main>
  );
}
