import { Link } from "react-router";
import type { Route } from "./+types/admin.sports-seasons.$id.expected-values";

import { loader } from "./admin.sports-seasons.$id.expected-values.server";
import { Button } from "~/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "~/components/ui/table";
import { ArrowLeft, Calculator } from "lucide-react";

export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
  return [{ title: `Expected Values — ${data?.sportsSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}

export { loader };

// DEFAULT scoring values — must match DEFAULT_SCORING_RULES in the simulate route.
// Scoring: 1st=100, 2nd=70, 3rd/4th (FF losers)=45 each, 5th–8th (E8 losers)=20 each.
// Sum = 100+70+45+45+20+20+20+20 = 340.
//
// Total EV invariant: Σ EV across all participants = Σ scoring values = 340,
// because each probability column sums to 1.0 across all participants.
// If total drifts from 340, likely causes:
//   1. Stale EV records from a prior simulation run (fix: re-run simulation, which now
//      zeros non-bracket participants automatically)
//   2. DB precision truncation (numeric(6,4) = 4dp; max drift ≈ ±1 for 68 teams)
const SCORING = [100, 70, 45, 45, 20, 20, 20, 20] as const;

function evFromProbs(ev: {
  probFirst: string; probSecond: string; probThird: string; probFourth: string;
  probFifth: string; probSixth: string; probSeventh: string; probEighth: string;
}): number {
  return parseFloat(ev.probFirst) * SCORING[0]
    + parseFloat(ev.probSecond) * SCORING[1]
    + parseFloat(ev.probThird) * SCORING[2]
    + parseFloat(ev.probFourth) * SCORING[3]
    + parseFloat(ev.probFifth) * SCORING[4]
    + parseFloat(ev.probSixth) * SCORING[5]
    + parseFloat(ev.probSeventh) * SCORING[6]
    + parseFloat(ev.probEighth) * SCORING[7];
}

function fmt(val: string | number) {
  return (parseFloat(val as string) * 100).toFixed(1) + "%";
}

export default function ExpectedValuesPage({ loaderData }: Route.ComponentProps) {
  const { sportsSeason, participants, existingEVs } = loaderData;

  // Compute total and sort from stored prob columns, not stored expectedValue.
  // The simulator normalizes per-position column sums to exactly 1.0 (step 10),
  // so the total EV should always equal the sum of scoring values (340).
  // Sum only over participants shown in the table — excludes orphan EV records
  // from prior simulation runs for participants no longer in this season.
  const sorted = [...participants].toSorted((a, b) => {
    const evDataA = existingEVs.get(a.id);
    const evA = evDataA ? evFromProbs(evDataA) : 0;
    const evDataB = existingEVs.get(b.id);
    const evB = evDataB ? evFromProbs(evDataB) : 0;
    return evB - evA;
  });

  const totalEV = sorted.reduce((sum, p) => {
    const ev = existingEVs.get(p.id);
    return ev ? sum + evFromProbs(ev) : sum;
  }, 0);

  return (
    <div className="container mx-auto p-6 space-y-6">
      <div className="flex items-center gap-4">
        <Link to={`/admin/sports-seasons/${sportsSeason.id}`}>
          <Button variant="ghost" size="sm">
            <ArrowLeft className="h-4 w-4 mr-2" />
            Back to Sports Season
          </Button>
        </Link>
      </div>

      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Calculator className="h-5 w-5" />
            Expected Values: {sportsSeason.sport.name} {sportsSeason.year}
          </CardTitle>
          <CardDescription>
            Probability distributions from the last simulation run. Sorted by EV descending.
          </CardDescription>
        </CardHeader>
        <CardContent>
          {participants.length === 0 ? (
            <p className="text-center text-muted-foreground py-8">
              No participants found.
            </p>
          ) : existingEVs.size === 0 ? (
            <p className="text-center text-muted-foreground py-8">
              No EV data yet. Run a simulation from the sports season page.
            </p>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Participant</TableHead>
                  <TableHead className="text-center">1st</TableHead>
                  <TableHead className="text-center">2nd</TableHead>
                  <TableHead className="text-center">3rd</TableHead>
                  <TableHead className="text-center">4th</TableHead>
                  <TableHead className="text-center">5th</TableHead>
                  <TableHead className="text-center">6th</TableHead>
                  <TableHead className="text-center">7th</TableHead>
                  <TableHead className="text-center">8th</TableHead>
                  <TableHead className="text-center">EV</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {sorted.map((participant) => {
                  const ev = existingEVs.get(participant.id);
                  return (
                    <TableRow key={participant.id}>
                      <TableCell className="font-medium">{participant.name}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probFirst) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probSecond) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probThird) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probFourth) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probFifth) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probSixth) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probSeventh) : "—"}</TableCell>
                      <TableCell className="text-center font-mono text-sm">{ev ? fmt(ev.probEighth) : "—"}</TableCell>
                      <TableCell className="text-center font-semibold">{ev ? evFromProbs(ev).toFixed(2) : "—"}</TableCell>
                    </TableRow>
                  );
                })}
                {existingEVs.size > 0 && (
                  <TableRow className="border-t-2 font-bold bg-muted/50">
                    <TableCell colSpan={9} className="text-right">
                      Total EV
                      {Math.abs(totalEV - 340) > 1 && (
                        <span className="ml-2 text-xs font-normal text-destructive">
                          (expected ~340; re-run simulation to fix stale data)
                        </span>
                      )}
                    </TableCell>
                    <TableCell className="text-center">{totalEV.toFixed(2)}</TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
