import { Form, Link, redirect } from "react-router";
import { auth } from "~/lib/auth.server";
import type { Route } from "./+types/admin.sports-seasons.$id.clone";

import { logger } from "~/lib/logger";
import { findSportsSeasonById, cloneSportsSeason, shiftDateByYears, type NewSportsSeason } from "~/models/sports-season";
import { isUserAdmin } from "~/models/user";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "~/components/ui/card";
import { Badge } from "~/components/ui/badge";
import { Copy } from "lucide-react";
import { useState } from "react";

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: `Clone ${data?.sourceSeason?.name ?? "Sports Season"} - Brackt Admin` }];
}

export async function loader({ params }: Route.LoaderArgs) {
  const sourceSeason = await findSportsSeasonById(params.id);

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

  const delta = 1;
  const newYear = sourceSeason.year + delta;

  const defaults = {
    name: sourceSeason.name.replace(/\b(20\d{2})\b/g, (_, y) => String(parseInt(y, 10) + delta)),
    year: newYear,
    startDate: sourceSeason.startDate ? shiftDateByYears(sourceSeason.startDate, delta) : "",
    endDate: sourceSeason.endDate ? shiftDateByYears(sourceSeason.endDate, delta) : "",
    draftOn: shiftDateByYears(sourceSeason.draftOn, delta),
    draftOff: shiftDateByYears(sourceSeason.draftOff, delta),
    scoringType: sourceSeason.scoringType,
    scoringPattern: sourceSeason.scoringPattern ?? "",
    totalMajors: sourceSeason.totalMajors ?? 4,
  };

  return { sourceSeason, defaults };
}

export async function action(args: Route.ActionArgs) {
  const { request, params } = args;
  const session = await auth.api.getSession({ headers: args.request.headers });
  const userId = session?.user.id ?? null;
  const isAdmin = userId ? await isUserAdmin(userId) : false;
  if (!isAdmin) {
    throw new Response("Forbidden", { status: 403 });
  }

  const formData = await request.formData();
  const sportId = formData.get("sportId");
  const name = formData.get("name");
  const year = formData.get("year");
  const startDate = formData.get("startDate");
  const endDate = formData.get("endDate");
  const scoringType = formData.get("scoringType");
  const scoringPattern = formData.get("scoringPattern");
  const totalMajors = formData.get("totalMajors");
  const draftOn = formData.get("draftOn");
  const draftOff = formData.get("draftOff");
  const copySimulatorInputs = formData.get("copySimulatorInputs") === "on";

  // Validation
  if (typeof sportId !== "string" || !sportId) {
    return { error: "Sport ID is missing" };
  }

  // Cross-validate sportId against source season to prevent tampering
  const sourceSeason = await findSportsSeasonById(params.id);
  if (!sourceSeason) {
    throw new Response("Sports season not found", { status: 404 });
  }
  if (sportId !== sourceSeason.sportId) {
    return { error: "Sport ID does not match source season" };
  }

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

  if (typeof year !== "string") {
    return { error: "Year is required" };
  }

  const yearNum = parseInt(year, 10);
  if (isNaN(yearNum) || yearNum < 2000 || yearNum > 2100) {
    return { error: "Year must be between 2000 and 2100" };
  }

  if (scoringType !== "playoffs" && scoringType !== "regular_season" && scoringType !== "majors") {
    return { error: "Invalid scoring type" };
  }

  const validScoringPatterns = ["playoff_bracket", "season_standings", "qualifying_points"];
  if (scoringPattern && typeof scoringPattern === "string" && !validScoringPatterns.includes(scoringPattern)) {
    return { error: "Invalid scoring pattern" };
  }

  if (typeof draftOn !== "string" || !draftOn) {
    return { error: "Draft open date is required" };
  }

  if (typeof draftOff !== "string" || !draftOff) {
    return { error: "Draft close date is required" };
  }

  if (draftOff < draftOn) {
    return { error: "Draft close date must be on or after draft open date" };
  }

  const newSeasonData: Partial<NewSportsSeason> = {
    sportId,
    name: name.trim(),
    year: yearNum,
    startDate: typeof startDate === "string" && startDate ? startDate : null,
    endDate: typeof endDate === "string" && endDate ? endDate : null,
    status: "upcoming",
    simulationStatus: "idle",
    majorsCompleted: 0,
    qualifyingPointsFinalized: false,
    scoringType,
    draftOn,
    draftOff,
  };

  if (scoringPattern && typeof scoringPattern === "string") {
    newSeasonData.scoringPattern = scoringPattern as "playoff_bracket" | "season_standings" | "qualifying_points";
  }

  if (totalMajors && typeof totalMajors === "string") {
    const totalMajorsNum = parseInt(totalMajors, 10);
    if (!isNaN(totalMajorsNum) && totalMajorsNum > 0) {
      newSeasonData.totalMajors = totalMajorsNum;
    }
  }

  let newSeason;
  try {
    newSeason = await cloneSportsSeason(params.id, newSeasonData as NewSportsSeason, {
      copySimulatorInputs,
    });
  } catch (error) {
    logger.error("Error cloning sports season:", error);
    return { error: "Failed to clone sports season. Please try again." };
  }

  return redirect(`/admin/sports-seasons/${newSeason.id}`);
}

export default function CloneSportsSeason({ loaderData, actionData }: Route.ComponentProps) {
  const { sourceSeason, defaults } = loaderData;
  const [scoringPattern, setScoringPattern] = useState<string>(defaults.scoringPattern);

  return (
    <div className="p-8">
      <div className="max-w-2xl">
        <div className="mb-6">
          <div className="flex items-center gap-2 mb-1">
            <h1 className="text-3xl font-bold">Clone Sports Season</h1>
            <Badge variant="secondary">
              <Copy className="mr-1 h-3 w-3" />
              Clone
            </Badge>
          </div>
          <p className="text-muted-foreground">
            Cloning from: <span className="font-medium text-foreground">{sourceSeason.name}</span>
          </p>
        </div>

        <Card>
          <CardHeader>
            <CardTitle>New Sports Season Details</CardTitle>
            <CardDescription>
              Review and adjust the pre-filled settings. Participants, events, simulator structure, and qualifying-points rules will be copied automatically.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Form method="post" className="space-y-6">
              <input type="hidden" name="sportId" value={sourceSeason.sportId} />

              <div className="space-y-2">
                <Label>Sport</Label>
                <div className="flex h-9 w-full rounded-md border border-input bg-muted px-3 py-2 text-sm text-muted-foreground">
                  {sourceSeason.sport.name}
                </div>
                <p className="text-xs text-muted-foreground">Sport is locked to the source season.</p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="name">Season Name</Label>
                <Input
                  id="name"
                  name="name"
                  type="text"
                  defaultValue={defaults.name}
                  required
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="year">Year</Label>
                <Input
                  id="year"
                  name="year"
                  type="number"
                  min="2000"
                  max="2100"
                  defaultValue={defaults.year}
                  required
                />
              </div>

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="startDate">Start Date (Optional)</Label>
                  <Input
                    id="startDate"
                    name="startDate"
                    type="date"
                    defaultValue={defaults.startDate}
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="endDate">End Date (Optional)</Label>
                  <Input
                    id="endDate"
                    name="endDate"
                    type="date"
                    defaultValue={defaults.endDate}
                  />
                </div>
              </div>

              <div className="space-y-2">
                <Label htmlFor="scoringType">Scoring Type</Label>
                <select
                  id="scoringType"
                  name="scoringType"
                  defaultValue={defaults.scoringType}
                  required
                  className={SELECT_CLASS}
                >
                  <option value="playoffs">Playoffs</option>
                  <option value="regular_season">Regular Season</option>
                  <option value="majors">Majors</option>
                </select>
                <p className="text-sm text-muted-foreground">
                  Playoffs: Team sports playoffs. Regular Season: Full season standings. Majors: Individual sport majors.
                </p>
              </div>

              <div className="space-y-2">
                <Label htmlFor="scoringPattern">Scoring Pattern (Optional)</Label>
                <select
                  id="scoringPattern"
                  name="scoringPattern"
                  value={scoringPattern}
                  onChange={(event) => setScoringPattern(event.target.value)}
                  className={SELECT_CLASS}
                >
                  <option value="">Select scoring pattern (optional)</option>
                  <option value="playoff_bracket">Playoff Bracket</option>
                  <option value="season_standings">Season Standings</option>
                  <option value="qualifying_points">Qualifying Points (Golf/Tennis)</option>
                </select>
              </div>

              {scoringPattern === "qualifying_points" && (
                <div className="space-y-2">
                  <Label htmlFor="totalMajors">Total Majors</Label>
                  <Input
                    id="totalMajors"
                    name="totalMajors"
                    type="number"
                    min="1"
                    max="10"
                    defaultValue={defaults.totalMajors}
                    placeholder="e.g., 4 (for Golf)"
                  />
                  <p className="text-sm text-muted-foreground">
                    How many major tournaments will be tracked?
                  </p>
                </div>
              )}

              <div className="grid grid-cols-2 gap-4">
                <div className="space-y-2">
                  <Label htmlFor="draftOn">Draft Open Date</Label>
                  <Input
                    id="draftOn"
                    name="draftOn"
                    type="date"
                    defaultValue={defaults.draftOn}
                    required
                  />
                </div>

                <div className="space-y-2">
                  <Label htmlFor="draftOff">Draft Close Date</Label>
                  <Input
                    id="draftOff"
                    name="draftOff"
                    type="date"
                    defaultValue={defaults.draftOff}
                    required
                  />
                </div>
              </div>
              <p className="text-sm text-muted-foreground">
                This season appears in league creation and pre-draft settings only between these two dates (inclusive).
              </p>

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

              <div className="rounded-md border p-4 space-y-2">
                <div className="flex items-center gap-2">
                  <input id="copySimulatorInputs" name="copySimulatorInputs" type="checkbox" className="h-4 w-4" />
                  <Label htmlFor="copySimulatorInputs">Copy volatile simulator inputs</Label>
                </div>
                <p className="text-sm text-muted-foreground">
                  Leave unchecked for a fresh season. Check only when prior-season odds, Elo ratings, rankings, and simulator input metadata should intentionally carry forward.
                </p>
              </div>

              <div className="flex gap-4">
                <Button type="submit" className="flex-1">
                  <Copy className="mr-2 h-4 w-4" />
                  Clone Sports Season
                </Button>
                <Button type="button" variant="outline" asChild>
                  <Link to={`/admin/sports-seasons/${sourceSeason.id}`}>Cancel</Link>
                </Button>
              </div>
            </Form>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
