import { useState } from "react";
import { Form, Link, redirect } from "react-router";
import { getAuth } from "@clerk/react-router/server";
import { findLeagueById, updateLeague, deleteLeague } from "~/models/league";
import { isCommissioner } from "~/models/commissioner";
import { findCurrentSeasonWithSports } from "~/models/season";
import { findTeamsBySeasonId, createManyTeams, deleteTeam } from "~/models/team";
import { unlinkSportFromSeason, linkMultipleSportsToSeason } from "~/models/season-sport";
import { findAllSportsSeasons } from "~/models/sports-season";
import type { Route } from "./+types/$leagueId.settings";
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 {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "~/components/ui/select";
import { Badge } from "~/components/ui/badge";
import { Checkbox } from "~/components/ui/checkbox";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "~/components/ui/alert-dialog";

export async function loader(args: Route.LoaderArgs) {
  const { userId } = await getAuth(args);
  const { params } = args;
  const { leagueId } = params;

  if (!userId) {
    throw new Response("Unauthorized", { status: 401 });
  }

  // Fetch league
  const league = await findLeagueById(leagueId);

  if (!league) {
    throw new Response("League not found", { status: 404 });
  }

  // Check if user is authorized (creator or commissioner)
  const userIsCommissioner = await isCommissioner(leagueId, userId);
  const isCreator = league.createdBy === userId;

  if (!isCreator && !userIsCommissioner) {
    throw new Response("Forbidden - You must be a commissioner to access settings", {
      status: 403,
    });
  }

  // Get current season with sports
  const season = await findCurrentSeasonWithSports(leagueId);
  const teams = season ? await findTeamsBySeasonId(season.id) : [];
  const allSportsSeasons = await findAllSportsSeasons();

  // Count teams with owners
  const teamsWithOwners = teams.filter(team => team.ownerId !== null).length;

  return {
    league,
    season,
    teams,
    teamCount: teams.length,
    teamsWithOwners,
    allSportsSeasons: allSportsSeasons as Array<typeof allSportsSeasons[0] & { sport: { id: string; name: string; type: string; slug: string } }>,
  };
}

export async function action(args: Route.ActionArgs) {
  const { userId } = await getAuth(args);
  const { params, request } = args;
  const { leagueId } = params;

  if (!userId) {
    throw new Response("Unauthorized", { status: 401 });
  }

  // Verify authorization
  const league = await findLeagueById(leagueId);
  if (!league) {
    throw new Response("League not found", { status: 404 });
  }

  const userIsCommissioner = await isCommissioner(leagueId, userId);
  const isCreator = league.createdBy === userId;

  if (!isCreator && !userIsCommissioner) {
    throw new Response("Forbidden", { status: 403 });
  }

  const formData = await request.formData();
  const intent = formData.get("intent");

  // Get current season to check status
  const season = await findCurrentSeasonWithSports(leagueId);
  if (!season) {
    return { error: "No active season found" };
  }

  if (intent === "update-sports") {
    if (season.status !== "pre_draft") {
      return { error: "Cannot modify sports after draft has started" };
    }

    const selectedSports = formData.getAll("sportsSeasons");
    const currentSportIds = new Set(
      season.seasonSports?.map((s: any) => s.sportsSeason.id) || []
    );
    const newSportIds = new Set(selectedSports as string[]);

    // Remove sports that are no longer selected
    for (const sportId of currentSportIds) {
      if (!newSportIds.has(sportId)) {
        await unlinkSportFromSeason(season.id, sportId);
      }
    }

    // Add newly selected sports
    const sportsToAdd = [];
    for (const sportId of newSportIds) {
      if (!currentSportIds.has(sportId)) {
        sportsToAdd.push({
          seasonId: season.id,
          sportsSeasonId: sportId as string,
        });
      }
    }

    if (sportsToAdd.length > 0) {
      await linkMultipleSportsToSeason(sportsToAdd);
    }

    return { success: true };
  }

  if (intent === "delete") {
    // Delete the league
    await deleteLeague(leagueId);
    
    // Redirect to home with success message
    return redirect("/?deleted=true");
  }

  if (intent === "update") {
    const name = formData.get("name");
    const teamCount = formData.get("teamCount");

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

    if (name.trim().length < 3 || name.trim().length > 50) {
      return { error: "League name must be between 3 and 50 characters" };
    }

    try {
      await updateLeague(leagueId, {
        name: name.trim(),
      });

      // Handle team count changes if provided
      if (typeof teamCount === "string") {
        const newTeamCount = parseInt(teamCount, 10);
        
        if (!isNaN(newTeamCount)) {
          const teams = await findTeamsBySeasonId(season.id);
          const currentTeamCount = teams.length;
          const teamsWithOwners = teams.filter(t => t.ownerId !== null).length;

          // Validate team count
          if (newTeamCount < 6 || newTeamCount > 16) {
            return { error: "Number of teams must be between 6 and 16" };
          }

          if (newTeamCount < teamsWithOwners) {
            return { error: `Cannot reduce team count below ${teamsWithOwners} (number of teams with owners)` };
          }

          // Add or remove teams as needed
          if (newTeamCount > currentTeamCount) {
            // Add new teams
            const teamsToAdd = Array.from(
              { length: newTeamCount - currentTeamCount },
              (_, i) => ({
                seasonId: season.id,
                name: `Team ${currentTeamCount + i + 1}`,
                ownerId: null,
              })
            );
            await createManyTeams(teamsToAdd);
          } else if (newTeamCount < currentTeamCount) {
            // Remove teams without owners (from the end)
            const teamsToRemove = teams
              .filter(t => t.ownerId === null)
              .slice(-(currentTeamCount - newTeamCount));
            
            for (const team of teamsToRemove) {
              await deleteTeam(team.id);
            }
          }
        }
      }

      return redirect(`/leagues/${leagueId}?updated=true`);
    } catch (error) {
      console.error("Error updating league:", error);
      return { error: "Failed to update league. Please try again." };
    }
  }

  return { error: "Invalid action" };
}

export default function LeagueSettings({ loaderData, actionData }: Route.ComponentProps) {
  const { league, season, teamCount, teamsWithOwners, allSportsSeasons } = loaderData;
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
  const [selectedSports, setSelectedSports] = useState<Set<string>>(
    new Set(season?.seasonSports?.map((s: any) => s.sportsSeason.id) || [])
  );

  const canEditSports = season && season.status === "pre_draft";
  const canEditTeamCount = season && season.status === "pre_draft";
  const minTeamCount = Math.max(6, teamsWithOwners);

  const handleSportToggle = (sportId: string) => {
    const newSelected = new Set(selectedSports);
    if (newSelected.has(sportId)) {
      newSelected.delete(sportId);
    } else {
      newSelected.add(sportId);
    }
    setSelectedSports(newSelected);
  };

  const handleDelete = () => {
    setIsDeleteDialogOpen(false);
    // The form submission will handle the actual deletion
  };

  return (
    <div className="container max-w-2xl mx-auto py-8 px-4">
      <div className="mb-8">
        <div className="flex items-center justify-between mb-2">
          <h1 className="text-4xl font-bold">League Settings</h1>
          <Button variant="outline" asChild>
            <Link to={`/leagues/${league.id}`}>Back to League</Link>
          </Button>
        </div>
        <p className="text-muted-foreground">{league.name}</p>
      </div>

      <div className="space-y-6">
        {/* Update League Form */}
        <Card>
          <CardHeader>
            <CardTitle>General Settings</CardTitle>
            <CardDescription>
              Update your league's basic information
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Form method="post" className="space-y-4">
              <input type="hidden" name="intent" value="update" />
              
              <div className="space-y-2">
                <Label htmlFor="name">League Name</Label>
                <Input
                  id="name"
                  name="name"
                  type="text"
                  defaultValue={league.name}
                  placeholder="Enter league name"
                  required
                  minLength={3}
                  maxLength={50}
                />
              </div>

              <div className="space-y-2">
                <Label htmlFor="teamCount">Number of Teams</Label>
                <Select 
                  name="teamCount" 
                  defaultValue={teamCount.toString()} 
                  disabled={!canEditTeamCount}
                >
                  <SelectTrigger id="teamCount">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    {Array.from({ length: 11 }, (_, i) => i + 6).map((num) => (
                      <SelectItem 
                        key={num} 
                        value={num.toString()}
                        disabled={num < minTeamCount}
                      >
                        {num} Teams
                        {num < minTeamCount && ` (${teamsWithOwners} teams have owners)`}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
                <p className="text-sm text-muted-foreground">
                  {canEditTeamCount 
                    ? `Can be changed before draft starts (minimum ${minTeamCount} based on registered teams)`
                    : "Team count cannot be changed after draft has started"}
                </p>
              </div>

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

              <Button type="submit" className="w-full">
                Save Changes
              </Button>
            </Form>
          </CardContent>
        </Card>

        {/* Sports Seasons Management */}
        <Card>
          <CardHeader>
            <CardTitle>Sports Seasons</CardTitle>
            <CardDescription>
              {canEditSports
                ? "Select the sports seasons that teams can draft from"
                : "Sports cannot be modified after the draft has started"}
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Form method="post" className="space-y-4">
              <input type="hidden" name="intent" value="update-sports" />
              
              <div className="space-y-3">
                <div className="bg-muted/50 border border-muted-foreground/20 rounded-md p-3">
                  <p className="text-sm text-muted-foreground">
                    <strong>Recommendation:</strong> Select 16-20 sports seasons for optimal league balance and variety.
                  </p>
                </div>
                
                <div className="space-y-2">
                  <Label className="text-sm font-medium">
                    Sports Seasons ({selectedSports.size} selected)
                  </Label>
                  <div className="max-h-96 overflow-y-auto border rounded-md p-3 space-y-2">
                    {allSportsSeasons.length > 0 ? (
                      allSportsSeasons.map((season) => (
                        <div key={season.id} className="flex items-center space-x-2">
                          <Checkbox
                            id={season.id}
                            name="sportsSeasons"
                            value={season.id}
                            checked={selectedSports.has(season.id)}
                            onCheckedChange={() => handleSportToggle(season.id)}
                            disabled={!canEditSports}
                          />
                          <Label
                            htmlFor={season.id}
                            className={`font-normal flex-1 ${canEditSports ? 'cursor-pointer' : 'cursor-not-allowed opacity-60'}`}
                          >
                            <span className="font-medium">{season.sport.name}</span> - {season.name} ({season.year})
                            <Badge variant="outline" className="ml-2 text-xs">
                              {season.scoringType.replace("_", " ")}
                            </Badge>
                          </Label>
                        </div>
                      ))
                    ) : (
                      <p className="text-sm text-muted-foreground">
                        No sports seasons available
                      </p>
                    )}
                  </div>
                </div>
              </div>

              {canEditSports && (
                <Button type="submit" className="w-full">
                  Save Sports Selection
                </Button>
              )}

              {actionData?.success && (
                <div className="bg-green-500/15 text-green-700 dark:text-green-400 px-4 py-3 rounded-md text-sm">
                  Sports updated successfully!
                </div>
              )}

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

        {/* Danger Zone */}
        <Card className="border-destructive">
          <CardHeader>
            <CardTitle className="text-destructive">Danger Zone</CardTitle>
            <CardDescription>
              Irreversible and destructive actions
            </CardDescription>
          </CardHeader>
          <CardContent>
            <AlertDialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
              <AlertDialogTrigger asChild>
                <Button variant="destructive" className="w-full">
                  Delete League
                </Button>
              </AlertDialogTrigger>
              <AlertDialogContent>
                <AlertDialogHeader>
                  <AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
                  <AlertDialogDescription>
                    This will permanently delete <strong>{league.name}</strong> and all
                    associated data including seasons, teams, and commissioners. This
                    action cannot be undone.
                  </AlertDialogDescription>
                </AlertDialogHeader>
                <AlertDialogFooter>
                  <AlertDialogCancel>Cancel</AlertDialogCancel>
                  <Form method="post" onSubmit={handleDelete}>
                    <input type="hidden" name="intent" value="delete" />
                    <AlertDialogAction type="submit" className="bg-destructive hover:bg-destructive/90">
                      Delete League
                    </AlertDialogAction>
                  </Form>
                </AlertDialogFooter>
              </AlertDialogContent>
            </AlertDialog>
          </CardContent>
        </Card>
      </div>
    </div>
  );
}
