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

import { logger } from "~/lib/logger";
import { createSport, findAllSports } 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";

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

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

export async function loader() {
  const sports = await findAllSports();
  return {
    existingIconOptions: sports
      .filter((sport) => Boolean(sport.iconUrl))
      .map((sport) => ({ id: sport.id, name: sport.name, iconUrl: sport.iconUrl as string })),
  };
}

export async function action({ request }: 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 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 iconUrl = parseSportIconUrlInput(iconUrlValue);
  if (iconUrl === undefined) {
    return { error: "Sport icon must be an uploaded SVG icon." };
  }

  try {
    await createSport({
      name: name.trim(),
      type,
      slug: slug.trim(),
      description: typeof description === "string" ? description.trim() : null,
      iconUrl,
      excludeFromHomepage,
    });

    return redirect("/admin/sports");
  } catch (error) {
    logger.error("Error creating sport:", error);
    if (iconUrl) {
      await deleteSportIconIfUnused({ iconUrl, reason: "unused" });
    }
    return { error: "Failed to create sport. The slug might already exist." };
  }
}

export default function NewSport({ loaderData, actionData }: Route.ComponentProps) {
  return (
    <div className="p-8">
      <div className="max-w-2xl">
        <div className="mb-6">
          <h1 className="text-3xl font-bold">Create New Sport</h1>
          <p className="text-muted-foreground mt-1">
            Add a new sport to the system
          </p>
        </div>

        <Card>
          <CardHeader>
            <CardTitle>Sport Details</CardTitle>
            <CardDescription>
              Enter the information for the new 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"
                  required
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="type">Type</Label>
                <select id="type" name="type" required defaultValue="" className={SELECT_CLASS}>
                  <option value="" disabled>Select sport type</option>
                  <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-]+"
                  required
                />
                <p className="text-sm text-muted-foreground">
                  URL-friendly identifier (lowercase, hyphens only)
                </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}
                />
              </div>

              <div className="space-y-2">
                <Label>Sport Icon (Optional)</Label>
                <SportIconUploader
                  uploadUrl="/api/upload-sport-icon"
                  sportName="New sport"
                  existingIconOptions={loaderData.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"
                    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">
                  Create Sport
                </Button>
                <Button type="button" variant="outline" asChild>
                  <Link to="/admin/sports">Cancel</Link>
                </Button>
              </div>
            </Form>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
