import { Form, Link, useActionData, useNavigation, useSearchParams } from "react-router";
import type { Route } from "./+types/admin.simulators";

import { Badge } from "~/components/ui/badge";
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 { listSportsSeasonSimulatorSummaries } from "~/models/simulator";
import { runSportsSeasonSimulation } from "~/services/simulations/runner";
import { Activity, CheckCircle2, Loader2, Play, SlidersHorizontal, XCircle } from "lucide-react";

export function meta(): Route.MetaDescriptors {
  return [{ title: "Simulators - Brackt Admin" }];
}

export async function loader() {
  const simulators = (await listSportsSeasonSimulatorSummaries())
    .filter((simulator) => simulator.seasonStatus !== "completed");
  const sports = [...new Set(simulators.map((sim) => sim.sportName))].toSorted();
  const simulatorTypes = [...new Set(simulators.map((sim) => sim.simulatorType))].toSorted();
  return { simulators, sports, simulatorTypes };
}

interface ActionData {
  success?: boolean;
  message: string;
  results?: Array<{ sportsSeasonId: string; ok: boolean; message: string }>;
}

export async function action({ request }: Route.ActionArgs): Promise<ActionData> {
  const formData = await request.formData();
  const intent = formData.get("intent");
  const ids = intent === "run-selected"
    ? formData.getAll("sportsSeasonId").filter((id): id is string => typeof id === "string")
    : [formData.get("sportsSeasonId")].filter((id): id is string => typeof id === "string");

  if (ids.length === 0) {
    return { success: false, message: "Select at least one simulator to run." };
  }

  const results: ActionData["results"] = [];
  for (const sportsSeasonId of ids) {
    try {
      const result = await runSportsSeasonSimulation(sportsSeasonId);
      results.push({
        sportsSeasonId,
        ok: true,
        message: `Simulated ${result.simulatedParticipants} participant(s).`,
      });
    } catch (error) {
      results.push({
        sportsSeasonId,
        ok: false,
        message: error instanceof Error ? error.message : "Simulation failed.",
      });
    }
  }

  const succeeded = results.filter((result) => result.ok).length;
  return {
    success: succeeded > 0 && succeeded === results.length,
    message: `Simulation run complete: ${succeeded}/${results.length} succeeded.`,
    results,
  };
}

function futuresBlendLabel(oddsWeight: number): string {
  if (oddsWeight >= 1) return "overrides Elo";
  if (oddsWeight <= 0) return "Elo only";
  return `${Math.round(oddsWeight * 100)}% blend`;
}

function statusBadge(status: string) {
  if (status === "ready") return <Badge className="gap-1"><CheckCircle2 className="h-3 w-3" /> Ready</Badge>;
  return <Badge variant="secondary" className="gap-1"><XCircle className="h-3 w-3" /> Needs setup</Badge>;
}

export default function AdminSimulators({ loaderData }: Route.ComponentProps) {
  const { simulators, sports, simulatorTypes } = loaderData;
  const actionData = useActionData<ActionData>();
  const navigation = useNavigation();
  const [searchParams, setSearchParams] = useSearchParams();
  const selectedSport = searchParams.get("sport") ?? "all";
  const selectedType = searchParams.get("type") ?? "all";
  const selectedReadiness = searchParams.get("readiness") ?? "all";
  const selectedStatus = searchParams.get("status") ?? "all";
  const isSubmitting = navigation.state === "submitting";

  const filtered = simulators.filter((sim) => {
    if (selectedSport !== "all" && sim.sportName !== selectedSport) return false;
    if (selectedType !== "all" && sim.simulatorType !== selectedType) return false;
    if (selectedReadiness !== "all" && sim.readiness.status !== selectedReadiness) return false;
    if (selectedStatus !== "all" && sim.seasonStatus !== selectedStatus) return false;
    return true;
  });

  function updateFilter(key: string, value: string) {
    const next = new URLSearchParams(searchParams);
    if (value === "all") next.delete(key);
    else next.set(key, value);
    setSearchParams(next);
  }

  return (
    <div className="p-8 space-y-6">
      <div>
        <h1 className="text-3xl font-bold flex items-center gap-2">
          <Activity className="h-7 w-7" />
          Simulators
        </h1>
        <p className="text-muted-foreground mt-1">
          Inventory, validate, and run every sports-season EV simulator from one place.
        </p>
      </div>

      {actionData && (
        <Card className={actionData.success ? "border-emerald-500/40" : "border-amber-500/40"}>
          <CardHeader>
            <CardTitle className="text-base">{actionData.message}</CardTitle>
          </CardHeader>
          {actionData.results && (
            <CardContent className="space-y-1 text-sm">
              {actionData.results.map((result) => (
                <div key={result.sportsSeasonId} className={result.ok ? "text-emerald-600" : "text-destructive"}>
                  {result.sportsSeasonId}: {result.message}
                </div>
              ))}
            </CardContent>
          )}
        </Card>
      )}

      <Card>
        <CardHeader>
          <CardTitle>Filters</CardTitle>
          <CardDescription>{filtered.length} of {simulators.length} simulator seasons shown</CardDescription>
        </CardHeader>
        <CardContent className="grid gap-3 md:grid-cols-4">
          <select className="h-9 rounded-md border bg-background px-3 text-sm" value={selectedSport} onChange={(e) => updateFilter("sport", e.target.value)}>
            <option value="all">All sports</option>
            {sports.map((sport) => <option key={sport} value={sport}>{sport}</option>)}
          </select>
          <select className="h-9 rounded-md border bg-background px-3 text-sm" value={selectedType} onChange={(e) => updateFilter("type", e.target.value)}>
            <option value="all">All simulator types</option>
            {simulatorTypes.map((type) => <option key={type} value={type}>{type}</option>)}
          </select>
          <select className="h-9 rounded-md border bg-background px-3 text-sm" value={selectedReadiness} onChange={(e) => updateFilter("readiness", e.target.value)}>
            <option value="all">All readiness</option>
            <option value="ready">Ready</option>
            <option value="not_ready">Needs setup</option>
          </select>
          <select className="h-9 rounded-md border bg-background px-3 text-sm" value={selectedStatus} onChange={(e) => updateFilter("status", e.target.value)}>
            <option value="all">All season statuses</option>
            <option value="upcoming">Upcoming</option>
            <option value="active">Active</option>
          </select>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <div className="flex items-center justify-between gap-4">
            <div>
              <CardTitle>Sports-Season Simulators</CardTitle>
              <CardDescription>
                Bulk runs execute sequentially and skip nothing silently: failures are reported per season.
              </CardDescription>
            </div>
            <Form method="post" id="bulk-run-simulators">
              <input type="hidden" name="intent" value="run-selected" />
              <Button type="submit" disabled={isSubmitting}>
                {isSubmitting ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Play className="mr-2 h-4 w-4" />}
                Run Selected
              </Button>
            </Form>
          </div>
        </CardHeader>
        <CardContent>
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-10" />
                <TableHead>Season</TableHead>
                <TableHead>Simulator</TableHead>
                <TableHead>Status</TableHead>
                <TableHead>Readiness</TableHead>
                <TableHead>Inputs</TableHead>
                <TableHead>Last Run</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.map((sim) => {
                const canRun = sim.readiness.canRun && sim.simulationStatus !== "running";
                return (
                  <TableRow key={sim.sportsSeasonId}>
                    <TableCell>
                      <input
                        form="bulk-run-simulators"
                        type="checkbox"
                        name="sportsSeasonId"
                        value={sim.sportsSeasonId}
                        disabled={!canRun}
                      />
                    </TableCell>
                    <TableCell>
                      <div className="font-medium">{sim.sportName} {sim.year}</div>
                      <div className="text-xs text-muted-foreground">{sim.seasonName}</div>
                      {sim.leagueName && (
                        <div className="text-xs text-muted-foreground">League: {sim.leagueName}</div>
                      )}
                    </TableCell>
                    <TableCell>
                      <div>{sim.simulatorName}</div>
                      <code className="text-xs text-muted-foreground">{sim.simulatorType}</code>
                    </TableCell>
                    <TableCell>
                      <div className="space-y-1">
                        <Badge variant={sim.seasonStatus === "active" ? "default" : "outline"}>{sim.seasonStatus}</Badge>
                        <Badge variant={sim.simulationStatus === "failed" ? "destructive" : "secondary"}>{sim.simulationStatus}</Badge>
                      </div>
                    </TableCell>
                    <TableCell>
                      <div className="space-y-1">
                        {statusBadge(sim.readiness.status)}
                        {sim.readiness.missingInputs.length > 0 && (
                          <div className="text-xs text-muted-foreground max-w-64">
                            Missing {sim.readiness.missingInputs.join(", ")}
                          </div>
                        )}
                        {sim.readiness.warnings.some((warning) => warning.includes("Derived") || warning.includes("fallback")) && (
                          <div className="text-xs text-muted-foreground max-w-64">
                            {sim.readiness.warnings
                              .filter((warning) => warning.includes("Derived") || warning.includes("fallback"))
                              .join(" ")}
                          </div>
                        )}
                      </div>
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      <div>{sim.participantInputCount}/{sim.participantCount}</div>
                      {sim.supportsFuturesOdds && (
                        <Badge variant={sim.oddsWeight > 0 ? "default" : "outline"} className="mt-1 text-xs font-normal">
                          {sim.oddsParticipantCount > 0
                            ? `Futures: ${sim.oddsParticipantCount} · ${futuresBlendLabel(sim.oddsWeight)}`
                            : "No futures odds"}
                        </Badge>
                      )}
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {sim.lastSimulatedDate ?? "Never"}
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex items-center justify-end gap-2">
                        <Button variant="ghost" size="sm" asChild>
                          <Link to={`/admin/sports-seasons/${sim.sportsSeasonId}/simulator`}>
                            <SlidersHorizontal className="mr-2 h-4 w-4" />
                            Setup
                          </Link>
                        </Button>
                        {sim.supportsFuturesOdds && (
                          <Button variant="ghost" size="sm" asChild>
                            <Link to={`/admin/sports-seasons/${sim.sportsSeasonId}/futures-odds`}>Futures</Link>
                          </Button>
                        )}
                        <Button variant="ghost" size="sm" asChild>
                          <Link to={`/admin/sports-seasons/${sim.sportsSeasonId}/expected-values`}>EVs</Link>
                        </Button>
                        <Form method="post">
                          <input type="hidden" name="intent" value="run-one" />
                          <input type="hidden" name="sportsSeasonId" value={sim.sportsSeasonId} />
                          <Button type="submit" size="sm" disabled={!canRun || isSubmitting}>
                            Run
                          </Button>
                        </Form>
                      </div>
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </CardContent>
      </Card>
    </div>
  );
}
