import { useEffect, useState } from 'react';
import { Link } from '@tanstack/react-router';
import { Scale } from 'lucide-react';
import { PageHeader } from '@/components/ui/PageHeader';
import { Card, CardBody, CardHeader } from '@/components/ui/Card';
import { Term } from '@/components/ui/Term';
import { teamFlag } from '@/lib/teams';
import { kickoffDay, kickoffTime } from '@/lib/format';
import { cn } from '@/lib/cn';
import type { MatchProbs, ScoreboardData, ScoreboardRow } from '@/lib/types';

const pct = (x: number) => `${Math.round(x * 100)}%`;

function ProbTriple({ label, probs, tone }: { label: string; probs: MatchProbs; tone: 'model' | 'market' }) {
  const color = tone === 'model' ? 'bg-accent' : 'bg-gold';
  return (
    <div className="flex items-center gap-2">
      <span className={cn('w-12 shrink-0 text-[10px] font-bold uppercase tracking-wide', tone === 'model' ? 'text-accent' : 'text-gold')}>{label}</span>
      <div className="flex h-2 flex-1 overflow-hidden rounded-full bg-elevated">
        <div className={color} style={{ width: pct(probs.home) }} />
        <div className="bg-line-strong" style={{ width: pct(probs.draw) }} />
        <div className="bg-info" style={{ width: pct(probs.away) }} />
      </div>
      <span className="tnum w-24 shrink-0 text-right text-[11px] text-muted">
        {pct(probs.home)} / {pct(probs.draw)} / {pct(probs.away)}
      </span>
    </div>
  );
}

function Row({ r }: { r: ScoreboardRow }) {
  const closer =
    r.scored && r.scored.marketRps != null
      ? r.scored.modelRps < r.scored.marketRps ? 'model' : r.scored.marketRps < r.scored.modelRps ? 'market' : 'tie'
      : null;
  return (
    <Card className={r.late ? 'opacity-60' : ''}>
      <CardBody className="space-y-2">
        <div className="flex flex-wrap items-center justify-between gap-2 text-sm">
          <Link to="/match/$num" params={{ num: String(r.num) }} className="flex items-center gap-2 font-medium text-ink hover:text-accent">
            <span aria-hidden>{teamFlag(r.home)}</span> {r.home}
            <span className="tnum text-faint">{r.status !== 'scheduled' && r.homeScore != null ? `${r.homeScore}–${r.awayScore}` : 'vs'}</span>
            {r.away} <span aria-hidden>{teamFlag(r.away)}</span>
          </Link>
          <span className="text-[11px] text-faint">
            {r.group ? `Group ${r.group} · ` : ''}{kickoffDay(r.kickoff)} {kickoffTime(r.kickoff)}
            {r.late && ' · snapshot late — excluded from totals'}
          </span>
        </div>
        <ProbTriple label="Model" probs={r.model} tone="model" />
        {r.market ? (
          <ProbTriple label={r.market.provider} probs={r.market.probs} tone="market" />
        ) : (
          <p className="text-[11px] text-faint">no bookmaker line captured before kickoff</p>
        )}
        {r.scored && (
          <div className="flex items-center gap-3 border-t border-line pt-2 text-[11px]">
            <span className="text-faint">result: <span className="font-semibold text-ink">{r.scored.outcome}</span></span>
            <span className="tnum text-muted">model RPS {r.scored.modelRps}</span>
            {r.scored.marketRps != null && <span className="tnum text-muted">market RPS {r.scored.marketRps}</span>}
            {closer && closer !== 'tie' && (
              <span className={cn('ml-auto rounded-full border px-2 py-0.5 font-bold uppercase tracking-wide', closer === 'model' ? 'border-accent/40 bg-accent-glow text-accent' : 'border-gold/40 bg-gold/15 text-gold')}>
                {closer === 'model' ? 'model closer' : 'market closer'}
              </span>
            )}
          </div>
        )}
      </CardBody>
    </Card>
  );
}

export function ScoreboardPage() {
  const [data, setData] = useState<ScoreboardData | null>(null);

  useEffect(() => {
    let alive = true;
    const load = () => fetch('/api/scoreboard').then((r) => r.json()).then((d: ScoreboardData) => alive && setData(d)).catch(() => {});
    void load();
    const id = setInterval(load, 60_000);
    return () => { alive = false; clearInterval(id); };
  }, []);

  const t = data?.totals ?? null;
  const lead = t ? (t.modelRps < t.marketRps ? 'model' : t.marketRps < t.modelRps ? 'market' : 'tie') : null;

  return (
    <div className="space-y-5">
      <PageHeader
        title="Model vs Market"
        subtitle="Our forecast, frozen before kickoff, against the bookmaker's de-vigged line — scored after every match. Lower RPS = closer to what happened."
      />

      <Card>
        <CardHeader className="flex items-center gap-2">
          <Scale size={16} className="text-accent" />
          <span className="font-display font-bold text-ink">Running head-to-head</span>
        </CardHeader>
        <CardBody>
          {t ? (
            <div className="grid grid-cols-3 items-center gap-3 text-center">
              <div>
                <div className={cn('font-display text-3xl font-extrabold', lead === 'model' ? 'text-accent' : 'text-ink')}>{t.modelRps.toFixed(4)}</div>
                <div className="text-[11px] uppercase tracking-wide text-faint">our model · RPS</div>
                <div className="tnum mt-1 text-xs text-muted">closer {t.modelCloser}×</div>
              </div>
              <div className="text-sm text-faint">
                {t.n} match{t.n === 1 ? '' : 'es'} scored
                <div className="mt-1 text-xs">{lead === 'tie' ? 'dead level' : lead === 'model' ? 'model ahead' : 'market ahead'}</div>
              </div>
              <div>
                <div className={cn('font-display text-3xl font-extrabold', lead === 'market' ? 'text-gold' : 'text-ink')}>{t.marketRps.toFixed(4)}</div>
                <div className="text-[11px] uppercase tracking-wide text-faint">bookmaker · RPS</div>
                <div className="tnum mt-1 text-xs text-muted">closer {t.marketCloser}×</div>
              </div>
            </div>
          ) : (
            <p className="py-4 text-center text-sm text-muted">
              The head-to-head starts with the first final whistle — forecasts are frozen before each kickoff and scored when the match ends.
            </p>
          )}
          <p className="mt-3 border-t border-line pt-2 text-xs text-faint">
            Honest rules: both forecasts frozen pre-kickoff; bookmaker margin removed (<Term k="de-vig" />); scored with the{' '}
            <Term k="RPS">Ranked Probability Score</Term>; late snapshots excluded. Beating the market over a small sample is
            noise — watch the gap, not the lead.
          </p>
        </CardBody>
      </Card>

      {data ? (
        <div className="space-y-3">
          {data.rows.length === 0 && (
            <p className="py-8 text-center text-sm text-muted">No frozen forecasts yet — the first snapshots are taken 15 minutes before kickoff.</p>
          )}
          {data.rows.map((r) => <Row key={r.num} r={r} />)}
        </div>
      ) : (
        <div className="h-48 animate-pulse rounded-xl border border-line bg-panel" />
      )}
    </div>
  );
}
