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

import { logger } from "~/lib/logger";
import { findSportById, updateSport } from "~/models/sport";
import { writeFile, mkdir } from "node:fs/promises";
import { join } from "node:path";
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 {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/components/ui/select";
import { SIMULATOR_TYPES, getSimulatorInfo } from "~/services/simulations/registry";

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 });
  }
  
  return { sport };
}

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 iconFile = formData.get("iconFile");
  const keepExistingIcon = formData.get("keepExistingIcon");

  // 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" };
  }

  // Get existing sport to preserve icon if needed
  const existingSport = await findSportById(params.id);
  let iconUrl: string | null | undefined = existingSport?.iconUrl;

  // Handle file upload
  if (iconFile instanceof File && iconFile.size > 0) {
    const fileExtension = iconFile.name.split(".").pop()?.toLowerCase();
    
    // Validate file type
    if (!fileExtension || !["svg", "png", "jpg", "jpeg"].includes(fileExtension)) {
      return { error: "Icon must be an SVG, PNG, or JPG file" };
    }

    // Create filename using slug
    const filename = `${slug.trim()}.${fileExtension}`;
    iconUrl = filename;

    try {
      // Ensure directory exists
      const iconsDir = join(process.cwd(), "public", "sports-icons");
      await mkdir(iconsDir, { recursive: true });

      // Save file
      const filepath = join(iconsDir, filename);
      const bytes = await iconFile.arrayBuffer();
      const buffer = Buffer.from(bytes);
      await writeFile(filepath, buffer);
    } catch (error) {
      logger.error("Error saving icon file:", error);
      return { error: "Failed to save icon file" };
    }
  } else if (keepExistingIcon !== "true") {
    // If no file uploaded and not keeping existing, set to null
    iconUrl = null;
  }

  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 {
    await updateSport(params.id, {
      name: name.trim(),
      type,
      slug: slug.trim(),
      description: typeof description === "string" ? description.trim() : null,
      iconUrl,
      simulatorType: parsedSimulatorType,
    });

    return redirect("/admin/sports");
  } catch (error) {
    logger.error("Error updating sport:", error);
    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 } = 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 name="type" defaultValue={sport.type} required>
                  <SelectTrigger id="type">
                    <SelectValue placeholder="Select sport type" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="team">Team Sport</SelectItem>
                    <SelectItem value="individual">Individual Sport</SelectItem>
                  </SelectContent>
                </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 name="simulatorType" defaultValue={sport.simulatorType ?? "none"}>
                  <SelectTrigger id="simulatorType">
                    <SelectValue placeholder="No simulator" />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">No simulator</SelectItem>
                    {SIMULATOR_TYPES.map((type) => (
                      <SelectItem key={type} value={type}>
                        {getSimulatorInfo(type)?.name ?? type}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </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 htmlFor="iconFile">Icon File (Optional)</Label>
                {sport.iconUrl && (
                  <div className="mb-2 p-3 bg-muted rounded-md">
                    <p className="text-sm font-medium mb-1">Current icon:</p>
                    <div className="flex items-center gap-3">
                      <img 
                        src={`/sports-icons/${sport.iconUrl}`} 
                        alt={sport.name}
                        className="w-12 h-12 object-contain"
                        onError={(e) => {
                          e.currentTarget.style.display = 'none';
                        }}
                      />
                      <code className="text-xs bg-background px-2 py-1 rounded">{sport.iconUrl}</code>
                    </div>
                  </div>
                )}
                <Input
                  id="iconFile"
                  name="iconFile"
                  type="file"
                  accept=".svg,.png,.jpg,.jpeg"
                />
                <input type="hidden" name="keepExistingIcon" value={sport.iconUrl ? "true" : "false"} />
                <p className="text-sm text-muted-foreground">
                  Upload a new SVG, PNG, or JPG file to replace the current icon. Leave empty to keep the existing icon.
                </p>
              </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>
  );
}
