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

import { logger } from "~/lib/logger";
import { findAllSports, findSportById, updateSport } from "~/models/sport";
import { deleteSportIconIfUnused } from "~/lib/sport-icon-cleanup.server";
import { parseSportIconUrlInput } from "~/lib/sport-icon-url";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label";
import { Textarea } from "~/components/ui/textarea";
import { SportIconUploader } from "~/components/ui/SportIconUploader";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import { SIMULATOR_TYPES, getSimulatorInfo } from "~/services/simulations/registry";

const SELECT_CLASS = "h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm";

export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
  return [{ title: `${data?.sport?.name ?? "Sport"} - Brackt Admin` }];
}

export async function loader({ params }: Route.LoaderArgs) {
  const sport = await findSportById(params.id);
  
  if (!sport) {
    throw new Response("Sport not found", { status: 404 });
  }
  
  const sports = await findAllSports();

  const simulatorOptions = [...SIMULATOR_TYPES]
    .toSorted((a, b) => {
      const nameA = getSimulatorInfo(a)?.name ?? a;
      const nameB = getSimulatorInfo(b)?.name ?? b;
      return nameA.localeCompare(nameB);
    })
    .map((type) => ({ value: type, label: getSimulatorInfo(type)?.name ?? type }));

  return {
    sport,
    simulatorOptions,
    existingIconOptions: sports
      .filter((option) => option.id !== sport.id && Boolean(option.iconUrl))
      .map((option) => ({ id: option.id, name: option.name, iconUrl: option.iconUrl as string })),
  };
}

export async function action({ request, params }: Route.ActionArgs) {
  const formData = await request.formData();
  const name = formData.get("name");
  const type = formData.get("type");
  const slug = formData.get("slug");
  const description = formData.get("description");
  const simulatorType = formData.get("simulatorType");
  const iconUrlValue = formData.get("iconUrl");
  const excludeFromHomepage = formData.get("excludeFromHomepage") === "on";

  // Validation
  if (typeof name !== "string" || !name.trim()) {
    return { error: "Sport name is required" };
  }

  if (type !== "team" && type !== "individual") {
    return { error: "Sport type must be either 'team' or 'individual'" };
  }

  if (typeof slug !== "string" || !slug.trim()) {
    return { error: "Slug is required" };
  }

  // Validate slug format (lowercase, hyphens only)
  if (!/^[a-z0-9-]+$/.test(slug)) {
    return { error: "Slug must contain only lowercase letters, numbers, and hyphens" };
  }

  const existingSport = await findSportById(params.id);
  const iconUrl = parseSportIconUrlInput(iconUrlValue);
  if (iconUrl === undefined) {
    return { error: "Sport icon must be an uploaded SVG icon." };
  }

  type ValidSimulatorType = typeof SIMULATOR_TYPES[number];
  const parsedSimulatorType: ValidSimulatorType | null =
    typeof simulatorType === "string" && (SIMULATOR_TYPES as readonly string[]).includes(simulatorType)
      ? (simulatorType as ValidSimulatorType)
      : null;

  try {
    const updatedSport = await updateSport(params.id, {
      name: name.trim(),
      type,
      slug: slug.trim(),
      description: typeof description === "string" ? description.trim() : null,
      iconUrl,
      simulatorType: parsedSimulatorType,
      excludeFromHomepage,
    });

    if (existingSport?.iconUrl && existingSport.iconUrl !== updatedSport.iconUrl) {
      await deleteSportIconIfUnused({
        iconUrl: existingSport.iconUrl,
        excludeSportId: params.id,
        reason: "replaced",
      });
    }

    return redirect("/admin/sports");
  } catch (error) {
    logger.error("Error updating sport:", error);
    if (iconUrl && iconUrl !== existingSport?.iconUrl) {
      await deleteSportIconIfUnused({ iconUrl, excludeSportId: params.id, reason: "unused" });
    }
    const message = error instanceof Error ? error.message : String(error);
    const isUniqueViolation = message.includes("unique") || message.includes("duplicate");
    return {
      error: isUniqueViolation
        ? "A sport with that slug already exists. Please choose a different slug."
        : `Failed to update sport: ${message}`,
    };
  }
}

export default function EditSport({ loaderData, actionData }: Route.ComponentProps) {
  const { sport, simulatorOptions, existingIconOptions } = loaderData;

  return (
    <div className="p-8">
      <div className="max-w-2xl">
        <div className="mb-6">
          <h1 className="text-3xl font-bold">Edit Sport</h1>
          <p className="text-muted-foreground mt-1">
            Update the sport information
          </p>
        </div>

        <Card>
          <CardHeader>
            <CardTitle>Sport Details</CardTitle>
            <CardDescription>
              Modify the information for this sport
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Form method="post" className="space-y-6">
              <div className="space-y-2">
                <Label htmlFor="name">Sport Name</Label>
                <Input
                  id="name"
                  name="name"
                  type="text"
                  placeholder="e.g., NFL, NBA, Golf - Men's"
                  defaultValue={sport.name}
                  required
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="type">Type</Label>
                <select id="type" name="type" defaultValue={sport.type} required className={SELECT_CLASS}>
                  <option value="team">Team Sport</option>
                  <option value="individual">Individual Sport</option>
                </select>
                <p className="text-sm text-muted-foreground">
                  Team sports have teams, individual sports have players
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="slug">Slug</Label>
                <Input
                  id="slug"
                  name="slug"
                  type="text"
                  placeholder="e.g., nfl, nba, golf-mens"
                  pattern="[a-z0-9-]+"
                  defaultValue={sport.slug}
                  required
                />
                <p className="text-sm text-muted-foreground">
                  URL-friendly identifier (lowercase, hyphens only)
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="simulatorType">Simulator Type (Optional)</Label>
                <select
                  id="simulatorType"
                  name="simulatorType"
                  defaultValue={sport.simulatorType ?? "none"}
                  className={SELECT_CLASS}
                >
                  <option value="none">No simulator</option>
                  {simulatorOptions.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </select>
                <p className="text-sm text-muted-foreground">
                  Algorithm used when running EV simulations for this sport
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="description">Description (Optional)</Label>
                <Textarea
                  id="description"
                  name="description"
                  placeholder="Brief description of the sport"
                  rows={3}
                  defaultValue={sport.description || ""}
                />
              </div>

              <div className="space-y-2">
                <Label>Sport Icon (Optional)</Label>
                <SportIconUploader
                  uploadUrl="/api/upload-sport-icon"
                  initialIconUrl={sport.iconUrl}
                  sportName={sport.name}
                  existingIconOptions={existingIconOptions}
                />
              </div>

              <div className="rounded-md border border-border/70 p-4">
                <div className="flex items-start gap-3">
                  <input
                    id="excludeFromHomepage"
                    name="excludeFromHomepage"
                    type="checkbox"
                    defaultChecked={sport.excludeFromHomepage}
                    className="mt-1 h-4 w-4 rounded border-input bg-background"
                  />
                  <div className="space-y-1">
                    <Label htmlFor="excludeFromHomepage">
                      Exclude from public sports page
                    </Label>
                    <p className="text-sm text-muted-foreground">
                      Keep this sport available in admin and drafts, but hide it from the public Sports page.
                    </p>
                  </div>
                </div>
              </div>

              {actionData?.error && (
                <div className="bg-destructive/15 text-destructive px-4 py-3 rounded-md text-sm">
                  {actionData.error}
                </div>
              )}

              <div className="flex gap-4">
                <Button type="submit" className="flex-1">
                  Update Sport
                </Button>
                <Button type="button" variant="outline" asChild>
                  <Link to="/admin/sports">Cancel</Link>
                </Button>
              </div>
            </Form>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
