import { scaleLinear } from 'd3-scale';
import { teamFlag } from '@/lib/teams';
import type { StoryViz, XgPoint } from '@/lib/types';

const W = 640;
const H = 280;
const M = { top: 16, right: 16, bottom: 28, left: 34 };

/** stepAfter path: hold the level, jump at each shot. */
function stepPath(points: XgPoint[], sx: (m: number) => number, sy: (c: number) => number): string {
  return points
    .map((p, i) => {
      const x = sx(p.minute);
      const y = sy(p.cum);
      if (i === 0) return `M ${x} ${y}`;
      const prevY = sy(points[i - 1]!.cum);
      return `L ${x} ${prevY} L ${x} ${y}`;
    })
    .join(' ');
}

function cumAt(race: XgPoint[], minute: number): number {
  let cum = 0;
  for (const p of race) if (p.minute <= minute) cum = p.cum;
  return cum;
}

/** Cumulative expected-goals "race" — the story of momentum, with goals marked. */
export function XgRace({ viz }: { viz: StoryViz }) {
  const last = (r: XgPoint[]) => r[r.length - 1]?.minute ?? 90;
  const maxMin = Math.max(last(viz.xgRace.home), last(viz.xgRace.away), 90);
  const maxXg = Math.max(viz.totals.home.xg, viz.totals.away.xg) * 1.08;

  const sx = scaleLinear().domain([0, maxMin]).range([M.left, W - M.right]);
  const sy = scaleLinear().domain([0, maxXg]).range([H - M.bottom, M.top]);

  const homeColor = 'var(--app-accent)';
  const awayColor = 'var(--app-info)';
  const xTicks = [0, 30, 45, 60, 90, maxMin > 105 ? 120 : maxMin].filter((t, i, a) => a.indexOf(t) === i && t <= maxMin);
  const yTicks = sy.ticks(4);

  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} className="w-full">
        {/* gridlines + y axis */}
        {yTicks.map((t) => (
          <g key={t}>
            <line x1={M.left} x2={W - M.right} y1={sy(t)} y2={sy(t)} stroke="var(--app-line)" strokeDasharray="3 3" strokeWidth={0.5} />
            <text x={M.left - 6} y={sy(t) + 3} textAnchor="end" fontSize="10" fill="var(--app-faint)">{t.toFixed(1)}</text>
          </g>
        ))}
        {/* x ticks */}
        {xTicks.map((t) => (
          <text key={t} x={sx(t)} y={H - 10} textAnchor="middle" fontSize="10" fill="var(--app-faint)">{t}&apos;</text>
        ))}
        {/* full-time line */}
        <line x1={sx(90)} x2={sx(90)} y1={M.top} y2={H - M.bottom} stroke="var(--app-line-strong)" strokeWidth={0.5} opacity={0.5} />

        {/* race lines */}
        <path d={stepPath(viz.xgRace.away, sx, sy)} fill="none" stroke={awayColor} strokeWidth={2} />
        <path d={stepPath(viz.xgRace.home, sx, sy)} fill="none" stroke={homeColor} strokeWidth={2} />

        {/* goal markers */}
        {viz.goals.map((g, i) => {
          const isHome = g.team === viz.home;
          const race = isHome ? viz.xgRace.home : viz.xgRace.away;
          return (
            <g key={i}>
              <circle cx={sx(g.minute)} cy={sy(cumAt(race, g.minute))} r={3} fill={isHome ? homeColor : awayColor} stroke="var(--app-surface)" strokeWidth={1}>
                <title>{`${g.player} ${g.minute}' (xG ${g.xg.toFixed(2)})`}</title>
              </circle>
            </g>
          );
        })}
      </svg>
      <div className="mt-1 flex items-center justify-center gap-5 text-sm">
        <span className="flex items-center gap-1.5">
          <span className="h-2.5 w-4 rounded bg-accent" /> {teamFlag(viz.home)} {viz.home}
          <span className="tnum font-bold text-ink">{viz.totals.home.xg.toFixed(2)}</span>
        </span>
        <span className="flex items-center gap-1.5">
          <span className="h-2.5 w-4 rounded bg-info" /> {teamFlag(viz.away)} {viz.away}
          <span className="tnum font-bold text-ink">{viz.totals.away.xg.toFixed(2)}</span>
        </span>
        <span className="text-xs text-faint">cumulative xG · dots = goals</span>
      </div>
    </div>
  );
}
