import { Form, Link, useLoaderData, useActionData } from "react-router";
import type { LoaderFunctionArgs, ActionFunctionArgs } from "react-router";
import { findSportsSeasonById } from "~/models/sports-season";
import { findParticipantResultsBySportsSeasonId } from "~/models/participant-result";
import { getAllParticipantEVsForSeason } from "~/models/participant-expected-value";
import {
  updateProbabilitiesAfterResult,
  previewProbabilityUpdate,
  type ProbabilityComparison,
} from "~/services/probability-updater";
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 { Badge } from "~/components/ui/badge";
import { ArrowLeft, RefreshCw, CheckCircle, AlertTriangle } from "lucide-react";
import { database } from "~/database/context";
import * as schema from "~/database/schema";
import { eq } from "drizzle-orm";

export async function loader({ params }: LoaderFunctionArgs) {
  if (!params.id) {
    throw new Response("Missing season ID", { status: 400 });
  }

  const sportsSeason = await findSportsSeasonById(params.id);

  if (!sportsSeason) {
    throw new Response("Sports season not found", { status: 404 });
  }

  const results = await findParticipantResultsBySportsSeasonId(params.id);
  const existingEVs = await getAllParticipantEVsForSeason(params.id);

  // Get preview of what would change
  const preview = await previewProbabilityUpdate(params.id);

  // Get participant names for display
  const db = database();
  const participants = await db.query.participants.findMany({
    where: (participants, { inArray }) =>
      inArray(
        participants.id,
        preview.map((p: ProbabilityComparison) => p.participantId)
      ),
  });

  const participantMap = new Map(participants.map((p: typeof participants[0]) => [p.id, p]));

  return {
    sportsSeason,
    results,
    existingEVs,
    preview: preview.map((p: ProbabilityComparison) => ({
      ...p,
      participantName: participantMap.get(p.participantId)?.name || "Unknown",
    })),
  };
}

export async function action({ params, request }: ActionFunctionArgs) {
  const formData = await request.formData();
  const intent = formData.get("intent");

  if (intent === "recalculate") {
    const recalculateUnfinished = formData.get("recalculateUnfinished") === "true";

    if (!params.id) {
      return { success: false, error: "Missing season ID" };
    }

    const result = await updateProbabilitiesAfterResult(
      params.id,
      recalculateUnfinished
    );

    if (result.errors.length > 0) {
      return {
        success: false,
        error: result.errors.join("; "),
        result,
      };
    }

    return {
      success: true,
      result,
    };
  }

  return { success: false, error: "Invalid intent" };
}

export default function RecalculateProbabilities() {
  const { sportsSeason, results, existingEVs, preview } = useLoaderData<typeof loader>();
  const actionData = useActionData<typeof action>();

  const finishedCount = results.filter((r) => r.finalPosition !== null).length;
  const totalCount = existingEVs.length;
  const unfinishedCount = totalCount - finishedCount;

  const changesCount = preview.filter((p) => p.status === "finished").length;

  // Check for invalid probabilities (> 1.0)
  const invalidProbabilities = preview.filter((p) =>
    p.before.some((prob) => prob > 1.0)
  );

  function formatProbability(prob: number): string {
    return (prob * 100).toFixed(1) + "%";
  }

  function getProbabilityChange(before: number, after: number): string {
    const diff = (after - before) * 100;
    if (Math.abs(diff) < 0.1) return "—";
    const sign = diff > 0 ? "+" : "";
    return sign + diff.toFixed(1) + "%";
  }

  return (
    <div className="container mx-auto py-8 px-4">
      <div className="mb-6">
        <Button variant="ghost" size="sm" asChild>
          <Link to={`/admin/sports-seasons/${sportsSeason.id}`}>
            <ArrowLeft className="mr-2 h-4 w-4" />
            Back to Sports Season
          </Link>
        </Button>
      </div>

      <div className="max-w-6xl mx-auto space-y-6">
        <div>
          <h1 className="text-3xl font-bold mb-2">Recalculate Probabilities</h1>
          <p className="text-muted-foreground">
            {sportsSeason.name} — {sportsSeason.year}
          </p>
        </div>

        {invalidProbabilities.length > 0 && (
          <Card className="border-amber-accent/30 bg-amber-accent/10">
            <CardHeader>
              <div className="flex items-center gap-2">
                <AlertTriangle className="h-5 w-5 text-amber-accent" />
                <CardTitle className="text-amber-accent">
                  Invalid Probability Data Detected
                </CardTitle>
              </div>
              <CardDescription>
                {invalidProbabilities.length} participant(s) have probabilities greater than 100%, which indicates corrupted data
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className="space-y-2 text-sm">
                <p>
                  The following participants have invalid probabilities (marked with ⚠️ in the table below):
                </p>
                <ul className="list-disc list-inside">
                  {invalidProbabilities.slice(0, 5).map((p) => (
                    <li key={p.participantId}>
                      {p.participantName}: P(1st) = {formatProbability(p.before[0])}
                    </li>
                  ))}
                  {invalidProbabilities.length > 5 && (
                    <li>... and {invalidProbabilities.length - 5} more</li>
                  )}
                </ul>
                <p className="mt-4 text-muted-foreground">
                  <strong>Solution:</strong> Go to the{" "}
                  <Link
                    to={`/admin/sports-seasons/${sportsSeason.id}/futures-odds`}
                    className="underline"
                  >
                    Futures Odds page
                  </Link>{" "}
                  and regenerate probabilities from current betting odds to fix this data.
                </p>
              </div>
            </CardContent>
          </Card>
        )}

        {actionData?.success ? (
          <Card className="border-emerald-500/30 bg-emerald-500/10">
            <CardHeader>
              <div className="flex items-center gap-2">
                <CheckCircle className="h-5 w-5 text-emerald-400" />
                <CardTitle className="text-emerald-400">
                  Probabilities Updated Successfully
                </CardTitle>
              </div>
              <CardDescription>
                {actionData.result?.updated} participant
                {actionData.result?.updated !== 1 ? "s" : ""} updated
              </CardDescription>
            </CardHeader>
            <CardContent>
              <div className="space-y-2 text-sm">
                <div>
                  Finished participants: {actionData.result?.finishedParticipants}
                </div>
                <div>
                  Recalculated participants: {actionData.result?.unfishedParticipants}
                </div>
              </div>
              <Button className="mt-4" asChild>
                <Link to={`/admin/sports-seasons/${sportsSeason.id}/expected-values`}>
                  View Expected Values
                </Link>
              </Button>
            </CardContent>
          </Card>
        ) : actionData?.error ? (
          <Card className="border-destructive bg-destructive/10">
            <CardHeader>
              <div className="flex items-center gap-2">
                <AlertTriangle className="h-5 w-5 text-destructive" />
                <CardTitle className="text-destructive">Error</CardTitle>
              </div>
              <CardDescription className="text-destructive/80">
                {actionData.error}
              </CardDescription>
            </CardHeader>
          </Card>
        ) : null}

        <Card>
          <CardHeader>
            <CardTitle>Summary</CardTitle>
            <CardDescription>
              Current state of participant results and probabilities
            </CardDescription>
          </CardHeader>
          <CardContent>
            <div className="grid grid-cols-3 gap-4">
              <div>
                <div className="text-2xl font-bold">{finishedCount}</div>
                <div className="text-sm text-muted-foreground">
                  Finished Participants
                </div>
              </div>
              <div>
                <div className="text-2xl font-bold">{unfinishedCount}</div>
                <div className="text-sm text-muted-foreground">
                  Unfinished Participants
                </div>
              </div>
              <div>
                <div className="text-2xl font-bold">{changesCount}</div>
                <div className="text-sm text-muted-foreground">
                  Changes to Apply
                </div>
              </div>
            </div>
          </CardContent>
        </Card>

        {changesCount === 0 ? (
          <Card>
            <CardHeader>
              <CardTitle>No Changes Needed</CardTitle>
              <CardDescription>
                All finished participants already have their probabilities set correctly.
              </CardDescription>
            </CardHeader>
            <CardContent>
              <p className="text-sm text-muted-foreground">
                Either no participants have finished yet, or their probabilities are
                already up to date.
              </p>
            </CardContent>
          </Card>
        ) : (
          <>
            <Card>
              <CardHeader>
                <CardTitle>Probability Changes</CardTitle>
                <CardDescription>
                  Preview of changes that will be applied
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Participant</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead className="text-right">P(1st) Before</TableHead>
                      <TableHead className="text-right">P(1st) After</TableHead>
                      <TableHead className="text-right">P(2nd) After</TableHead>
                      <TableHead className="text-right">P(3rd) After</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {preview
                      .filter((p: ProbabilityComparison) => p.status === "finished")
                      .map((p: ProbabilityComparison) => {
                        const result = results.find(
                          (r: typeof results[0]) => r.participantId === p.participantId
                        );
                        const finalPosition = result?.finalPosition;

                        return (
                          <TableRow key={p.participantId}>
                            <TableCell className="font-medium">
                              {p.participantName}
                            </TableCell>
                            <TableCell>
                              <Badge variant="default">
                                Finished {finalPosition ? `${finalPosition}${
                                  finalPosition === 1
                                    ? "st"
                                    : finalPosition === 2
                                    ? "nd"
                                    : finalPosition === 3
                                    ? "rd"
                                    : "th"
                                }` : ""}
                              </Badge>
                            </TableCell>
                            <TableCell className="text-right font-mono text-sm">
                              <div className={p.before[0] > 1 ? "text-destructive" : ""}>
                                {formatProbability(p.before[0])}
                                {p.before[0] > 1 && " ⚠️"}
                              </div>
                            </TableCell>
                            <TableCell className="text-right font-mono text-sm">
                              <div>{formatProbability(p.after[0])}</div>
                              <div className="text-xs text-muted-foreground">
                                {getProbabilityChange(p.before[0], p.after[0])}
                              </div>
                            </TableCell>
                            <TableCell className="text-right font-mono text-sm">
                              <div>{formatProbability(p.after[1])}</div>
                            </TableCell>
                            <TableCell className="text-right font-mono text-sm">
                              <div>{formatProbability(p.after[2])}</div>
                            </TableCell>
                          </TableRow>
                        );
                      })}
                  </TableBody>
                </Table>
              </CardContent>
            </Card>

            <Card>
              <CardHeader>
                <CardTitle>Apply Changes</CardTitle>
                <CardDescription>
                  Update probabilities based on real results
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Form method="post" className="space-y-4">
                  <input type="hidden" name="intent" value="recalculate" />
                  <input
                    type="hidden"
                    name="recalculateUnfinished"
                    value="true"
                  />

                  <div className="bg-electric/10 border border-electric/20 rounded-lg p-4">
                    <h4 className="font-semibold text-sm mb-2">What happens:</h4>
                    <ul className="text-sm space-y-1 text-muted-foreground">
                      <li>
                        • Finished participants get 100% probability at their final
                        position
                      </li>
                      <li>
                        • Unfinished participants get recalculated probabilities based
                        on remaining competition
                      </li>
                      <li>
                        • Expected values will be automatically updated for all
                        affected leagues
                      </li>
                    </ul>
                  </div>

                  <div className="flex gap-4">
                    <Button
                      type="submit"
                      className="flex-1"
                      disabled={changesCount === 0}
                    >
                      <RefreshCw className="mr-2 h-4 w-4" />
                      Apply {changesCount} Change
                      {changesCount !== 1 ? "s" : ""}
                    </Button>
                    <Button type="button" variant="outline" asChild>
                      <Link to={`/admin/sports-seasons/${sportsSeason.id}`}>
                        Cancel
                      </Link>
                    </Button>
                  </div>
                </Form>
              </CardContent>
            </Card>
          </>
        )}
      </div>
    </div>
  );
}
