import { useMemo } from 'react';
import { deVig } from '@/lib/odds';
import { useT } from '@/lib/i18n';
import type { MatchProbs, OddsPoint } from '@/lib/types';

/** Bookmaker line movement (de-vigged) vs the model's pre-match probabilities.
 *  Market = solid lines drifting toward kickoff; model = dashed references.
 *  Benchmark only — the model never sees these numbers. */
export function OddsMovement({ history, model, kickoff }: {
  history: OddsPoint[];
  model: MatchProbs;
  kickoff: string;
}) {
  const t = useT();
  const W = 600;
  const H = 200;
  const PAD = { l: 30, r: 8, t: 8, b: 20 };

  const data = useMemo(() => {
    const koT = new Date(kickoff).getTime();
    const pts = history
      .map((h) => ({ at: h.captured_at, probs: deVig(h.home_ml, h.draw_ml, h.away_ml) }))
      .filter((p): p is { at: number; probs: MatchProbs } => p.probs != null && p.at <= koT)
      .sort((a, b) => a.at - b.at);
    if (pts.length < 2) return null;

    const firstAt = pts[0]!.at;
    const span = Math.max(1, koT - firstAt);
    const x = (at: number) => PAD.l + ((at - firstAt) / span) * (W - PAD.l - PAD.r);
    const maxP = Math.min(1, Math.max(...pts.flatMap((p) => [p.probs.home, p.probs.draw, p.probs.away]), model.home, model.draw, model.away) + 0.08);
    const y = (p: number) => PAD.t + (1 - p / maxP) * (H - PAD.t - PAD.b);
    const line = (sel: (p: MatchProbs) => number) => pts.map((p) => `${x(p.at).toFixed(1)},${y(sel(p.probs)).toFixed(1)}`).join(' ');

    // hour ticks: kickoff plus a few nice -24h steps back
    const hoursSpan = span / 3_600_000;
    const step = hoursSpan > 96 ? 48 : hoursSpan > 36 ? 24 : hoursSpan > 12 ? 12 : 6;
    const ticks: { px: number; label: string }[] = [];
    for (let h = 0; h <= hoursSpan; h += step) {
      ticks.push({ px: x(koT - h * 3_600_000), label: h === 0 ? '0h' : `-${h}h` });
    }
    const yTicks = [0.25, 0.5, 0.75].filter((p) => p < maxP).map((p) => ({ py: y(p), label: `${Math.round(p * 100)}%` }));
    return {
      home: line((p) => p.home), draw: line((p) => p.draw), away: line((p) => p.away),
      yModel: { home: y(model.home), draw: y(model.draw), away: y(model.away) },
      ticks, yTicks,
    };
  }, [history, model, kickoff]);

  if (!data) return null;

  return (
    <div>
      <svg viewBox={`0 0 ${W} ${H}`} className="w-full" role="img" aria-label={t.match.oddsMovement}>
        <rect x={PAD.l} y={PAD.t} width={W - PAD.l - PAD.r} height={H - PAD.t - PAD.b} className="fill-[var(--app-elevated)]" rx={4} />
        {data.yTicks.map((yt) => (
          <g key={yt.label}>
            <line x1={PAD.l} x2={W - PAD.r} y1={yt.py} y2={yt.py} className="stroke-[var(--app-line)]" strokeWidth={1} />
            <text x={PAD.l - 4} y={yt.py + 3} textAnchor="end" className="fill-[var(--app-faint)] text-[10px]">{yt.label}</text>
          </g>
        ))}
        {/* model references (dashed) */}
        <line x1={PAD.l} x2={W - PAD.r} y1={data.yModel.home} y2={data.yModel.home} className="stroke-[var(--app-accent)]" strokeDasharray="5 4" strokeWidth={1.5} opacity={0.7} />
        <line x1={PAD.l} x2={W - PAD.r} y1={data.yModel.draw} y2={data.yModel.draw} className="stroke-[var(--app-line-strong)]" strokeDasharray="5 4" strokeWidth={1.5} opacity={0.9} />
        <line x1={PAD.l} x2={W - PAD.r} y1={data.yModel.away} y2={data.yModel.away} className="stroke-[var(--app-info)]" strokeDasharray="5 4" strokeWidth={1.5} opacity={0.7} />
        {/* market lines */}
        <polyline points={data.home} fill="none" className="stroke-[var(--app-accent)]" strokeWidth={2.5} />
        <polyline points={data.draw} fill="none" className="stroke-[var(--app-line-strong)]" strokeWidth={2.5} />
        <polyline points={data.away} fill="none" className="stroke-[var(--app-info)]" strokeWidth={2.5} />
        {data.ticks.map((tk) => (
          <text key={tk.label} x={tk.px} y={H - 6} textAnchor="middle" className="fill-[var(--app-faint)] text-[10px]">{tk.label}</text>
        ))}
      </svg>
      <p className="mt-1.5 text-xs text-faint">{t.match.oddsMovementNote}</p>
    </div>
  );
}
