import { useEffect, useState } from 'react';
import { Sparkles } from 'lucide-react';
import { PageHeader } from '@/components/ui/PageHeader';
import { Card, CardBody, CardHeader } from '@/components/ui/Card';
import { Placeholder } from '@/components/ui/Placeholder';
import { ShotMap } from '@/components/viz/ShotMap';
import { XgRace } from '@/components/viz/XgRace';
import { PassNetwork } from '@/components/viz/PassNetwork';
import { teamFlag } from '@/lib/teams';
import type { StoryViz } from '@/lib/types';

function StatRow({ label, home, away, fmt = (n: number) => String(n) }: {
  label: string; home: number; away: number; fmt?: (n: number) => string;
}) {
  const total = home + away || 1;
  return (
    <div>
      <div className="mb-1 flex items-center justify-between text-sm">
        <span className="tnum font-bold text-accent">{fmt(home)}</span>
        <span className="text-xs uppercase tracking-wide text-faint">{label}</span>
        <span className="tnum font-bold text-info">{fmt(away)}</span>
      </div>
      <div className="flex h-2 overflow-hidden rounded-full bg-elevated">
        <div className="bg-accent" style={{ width: `${(home / total) * 100}%` }} />
        <div className="bg-info" style={{ width: `${(away / total) * 100}%` }} />
      </div>
    </div>
  );
}

export function StoryPage() {
  const [viz, setViz] = useState<StoryViz | null>(null);
  const [failed, setFailed] = useState(false);

  useEffect(() => {
    let alive = true;
    fetch('/data/viz/final-2022.json')
      .then((r) => (r.ok ? r.json() : Promise.reject()))
      .then((d: StoryViz) => alive && setViz(d))
      .catch(() => alive && setFailed(true));
    return () => { alive = false; };
  }, []);

  if (failed) {
    return (
      <div>
        <PageHeader title="Story" subtitle="A data-driven look back." />
        <Placeholder icon={<Sparkles size={28} />}>
          The story dataset isn&apos;t available. Run <code className="text-accent">npm run data:viz</code> to generate it.
        </Placeholder>
      </div>
    );
  }

  if (!viz) {
    return (
      <div>
        <PageHeader title="Story" subtitle="Loading the data story…" />
        <div className="h-96 animate-pulse rounded-xl border border-line bg-panel" />
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <PageHeader
        title="The greatest final ever, in data"
        subtitle={`${viz.competition} · ${viz.stage} · ${viz.date}`}
      />

      {/* hero scoreline */}
      <Card>
        <CardBody className="flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-center">
          <span className="flex items-center gap-2 text-xl font-bold text-ink">
            <span aria-hidden className="text-2xl">{teamFlag(viz.home)}</span> {viz.home}
          </span>
          <span className="tnum text-3xl font-extrabold text-ink">{viz.homeScore} – {viz.awayScore}</span>
          <span className="flex items-center gap-2 text-xl font-bold text-ink">
            {viz.away} <span aria-hidden className="text-2xl">{teamFlag(viz.away)}</span>
          </span>
          <span className="w-full text-sm font-medium text-gold">{viz.result}</span>
        </CardBody>
      </Card>

      <p className="mx-auto max-w-2xl text-center text-sm text-muted">
        Argentina and France traded six goals across 120 minutes — Messi twice, Di María, and a
        Mbappé hat-trick — before penalties. Here&apos;s what the event data says about how it happened.
      </p>

      {/* totals */}
      <Card>
        <CardHeader><span className="font-display font-bold text-ink">By the numbers</span></CardHeader>
        <CardBody className="grid gap-4 sm:grid-cols-2">
          <StatRow label="Expected goals" home={viz.totals.home.xg} away={viz.totals.away.xg} fmt={(n) => n.toFixed(2)} />
          <StatRow label="Shots" home={viz.totals.home.shots} away={viz.totals.away.shots} />
          <StatRow label="Passes" home={viz.totals.home.passes} away={viz.totals.away.passes} />
          <StatRow label="Pass accuracy %" home={viz.totals.home.passAccuracy} away={viz.totals.away.passAccuracy} />
        </CardBody>
      </Card>

      {/* shot map */}
      <Card>
        <CardHeader><span className="font-display font-bold text-ink">Every shot, sized by xG</span></CardHeader>
        <CardBody>
          <ShotMap viz={viz} />
          <p className="mt-3 text-sm text-muted">
            Argentina ({viz.totals.home.xg.toFixed(2)} xG) created the bigger chances; France&apos;s
            comeback was built on a flurry of high-value shots once Mbappé sparked into life. Each
            dot is a shot — bigger means a better chance; filled dots are goals.
          </p>
        </CardBody>
      </Card>

      {/* xG race */}
      <Card>
        <CardHeader><span className="font-display font-bold text-ink">The xG race</span></CardHeader>
        <CardBody>
          <XgRace viz={viz} />
          <p className="mt-3 text-sm text-muted">
            Argentina built a commanding expected-goals lead through 80 minutes — then France&apos;s
            two goals in 97 seconds dragged the line sharply upward. Steep steps are big chances.
          </p>
        </CardBody>
      </Card>

      {/* pass networks */}
      <Card>
        <CardHeader><span className="font-display font-bold text-ink">Passing shape (starting XI)</span></CardHeader>
        <CardBody>
          <div className="grid gap-6 md:grid-cols-2">
            <PassNetwork net={viz.passNetwork.home} team={viz.home} color="var(--app-accent)" />
            <PassNetwork net={viz.passNetwork.away} team={viz.away} color="var(--app-info)" />
          </div>
          <p className="mt-3 text-sm text-muted">
            Each node is a player at their average pass position; links are the completed passes
            between a pair, up to the first substitution. Bigger nodes saw more of the ball.
          </p>
        </CardBody>
      </Card>
    </div>
  );
}
