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

import { logger } from "~/lib/logger";
import { findSportsSeasonById } from "~/models/sports-season";
import { findParticipantsBySportsSeasonId } from "~/models/participant";
import { getSeasonResults, upsertSeasonResultsBulk } from "~/models/participant-season-result";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import { ArrowLeft, Save, ListOrdered } from "lucide-react";

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

export async function loader({ params }: Route.LoaderArgs) {
  const sportsSeason = await findSportsSeasonById(params.id);
  if (!sportsSeason) {
    throw new Response("Sports season not found", { status: 404 });
  }

  const participants = await findParticipantsBySportsSeasonId(params.id);
  const seasonResults = await getSeasonResults(params.id);

  // Build a map of existing results keyed by participantId
  const resultsMap = new Map(
    seasonResults.map((r) => [r.participantId, r])
  );

  return {
    sportsSeason: sportsSeason as typeof sportsSeason & { sport: { id: string; name: string } },
    participants,
    resultsMap: Object.fromEntries(resultsMap),
  };
}

export async function action({ request, params }: Route.ActionArgs) {
  const formData = await request.formData();

  // Parse updates directly from form field names: position_<id> and points_<id>
  const byId = new Map<string, { position?: number; points?: number }>();
  for (const [key, value] of formData.entries()) {
    const posMatch = key.match(/^position_(.+)$/);
    const ptsMatch = key.match(/^points_(.+)$/);
    if (posMatch) {
      const id = posMatch[1];
      const position = parseInt(value as string, 10);
      if (!isNaN(position)) {
        byId.set(id, { ...byId.get(id), position });
      }
    } else if (ptsMatch) {
      const id = ptsMatch[1];
      const points = parseFloat(value as string);
      if (!isNaN(points)) {
        byId.set(id, { ...byId.get(id), points });
      }
    }
  }

  const updates = Array.from(byId.entries()).map(([participantId, { position, points }]) => ({
    participantId,
    sportsSeasonId: params.id,
    currentPosition: position,
    currentPoints: points,
  }));

  try {
    await upsertSeasonResultsBulk(updates);
    return { success: true };
  } catch (error) {
    logger.error("Error updating standings:", error);
    return { error: "Failed to save standings. Please try again." };
  }
}

export default function ManageStandings({ loaderData, actionData }: Route.ComponentProps) {
  const { sportsSeason, participants, resultsMap } = loaderData;

  // Sort participants by current position (unranked at bottom)
  const sorted = [...participants].toSorted((a, b) => {
    const posA = resultsMap[a.id]?.currentPosition ?? Infinity;
    const posB = resultsMap[b.id]?.currentPosition ?? Infinity;
    return posA - posB;
  });

  return (
    <div className="p-8">
      <div className="max-w-3xl">
        <div className="mb-6">
          <Button variant="ghost" size="sm" asChild className="mb-2">
            <Link to={`/admin/sports-seasons/${sportsSeason.id}`}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Back to Sports Season
            </Link>
          </Button>
          <h1 className="text-3xl font-bold">Update Standings</h1>
          <p className="text-muted-foreground mt-1">
            {sportsSeason.sport.name} — {sportsSeason.name}
          </p>
        </div>

        <div className="space-y-6">
          {actionData?.error && (
            <div className="bg-destructive/15 text-destructive px-4 py-3 rounded-md text-sm">
              {actionData.error}
            </div>
          )}
          {actionData?.success && (
            <div className="bg-emerald-500/15 text-emerald-400 px-4 py-3 rounded-md text-sm">
              Standings saved.
            </div>
          )}

          {/* Standings table */}
          <Card>
            <CardHeader>
              <CardTitle className="flex items-center gap-2">
                <ListOrdered className="h-5 w-5" />
                Championship Standings
              </CardTitle>
              <CardDescription>
                Enter each participant's current position and championship points. Leave blank to skip.
              </CardDescription>
            </CardHeader>
            <CardContent>
              <Form method="post">
                <div className="space-y-1 mb-4">
                  <div className="grid grid-cols-[2rem_1fr_6rem_7rem] gap-3 px-2 pb-1 text-xs font-medium text-muted-foreground uppercase tracking-wide border-b">
                    <span>#</span>
                    <span>Participant</span>
                    <span>Position</span>
                    <span>Points</span>
                  </div>

                  {sorted.map((participant) => {
                    const result = resultsMap[participant.id];
                    return (
                      <div
                        key={participant.id}
                        className="grid grid-cols-[2rem_1fr_6rem_7rem] gap-3 items-center px-2 py-1.5 rounded hover:bg-muted/40"
                      >
                        <span className="text-sm text-muted-foreground tabular-nums">
                          {result?.currentPosition ?? "—"}
                        </span>
                        <span className="text-sm font-medium truncate">
                          {participant.name}
                        </span>
                        <Input
                          name={`position_${participant.id}`}
                          type="number"
                          min="1"
                          defaultValue={result?.currentPosition ?? ""}
                          placeholder="—"
                          className="h-8 text-sm"
                        />
                        <Input
                          name={`points_${participant.id}`}
                          type="number"
                          min="0"
                          step="0.5"
                          defaultValue={result?.currentPoints ?? ""}
                          placeholder="—"
                          className="h-8 text-sm"
                        />
                      </div>
                    );
                  })}
                </div>

                <Button type="submit" className="w-full">
                  <Save className="mr-2 h-4 w-4" />
                  Save Standings
                </Button>
              </Form>
            </CardContent>
          </Card>
        </div>
      </div>
    </div>
  );
}
