import { Form, Link } from "react-router";
import { useState, useEffect } from "react";
import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId.bracket";
import { loader, action } from "./admin.sports-seasons.$id.events.$eventId.bracket.server";
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 { ArrowLeft, Plus, Trophy } from "lucide-react";
import { getAllBracketTemplates, getBracketTemplate } from "~/lib/bracket-templates";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "~/components/ui/table";

export { loader, action };

export default function EventBracket({
  loaderData,
  actionData,
}: Route.ComponentProps) {
  const { sportsSeason, event, participants, matches } = loaderData;
  const [selectedTemplate, setSelectedTemplate] = useState("simple_8");
  const [selectedParticipants, setSelectedParticipants] = useState<Record<number, string>>({});
  const [selectedWinners, setSelectedWinners] = useState<Record<string, string>>({});
  const templates = getAllBracketTemplates();
  const template = templates.find((t) => t.id === selectedTemplate);

  // Clear selected winners after successful batch submission
  useEffect(() => {
    if (actionData?.success) {
      setSelectedWinners({});
    }
  }, [actionData?.success]);

  // Reset selected participants when template changes
  const handleTemplateChange = (newTemplateId: string) => {
    setSelectedTemplate(newTemplateId);
    setSelectedParticipants({});
  };

  // Update selected participant for a seed
  const handleParticipantChange = (seedIndex: number, participantId: string) => {
    setSelectedParticipants(prev => ({
      ...prev,
      [seedIndex]: participantId
    }));
  };

  // Get available participants for a specific seed (excluding already selected)
  const getAvailableParticipants = (currentSeedIndex: number) => {
    const selectedIds = Object.entries(selectedParticipants)
      .filter(([seedIdx]) => Number(seedIdx) !== currentSeedIndex)
      .map(([_, id]) => id);

    return participants.filter(
      (p: { id: string; name: string }) => !selectedIds.includes(p.id)
    );
  };

  // Update selected winner for a match
  const handleWinnerChange = (matchId: string, winnerId: string) => {
    setSelectedWinners(prev => ({
      ...prev,
      [matchId]: winnerId
    }));
  };

  // Get matches with pending winner selections in a round
  const getPendingWinnersInRound = (round: string) => {
    return Object.entries(selectedWinners)
      .filter(([matchId]) => {
        const match = matches.find((m: any) => m.id === matchId);
        return match && match.round === round && !match.isComplete;
      });
  };

  // Group matches by round
  const matchesByRound: Record<string, typeof matches> = {};
  for (const match of matches) {
    if (!matchesByRound[match.round]) {
      matchesByRound[match.round] = [];
    }
    matchesByRound[match.round].push(match);
  }

  // Get available rounds in chronological order (first round to finals)
  const getOrderedRounds = () => {
    const roundsInMatches = Array.from(new Set(matches.map(m => m.round)));

    // If event has a bracket template, use its round order
    if (event.bracketTemplateId) {
      const eventTemplate = getBracketTemplate(event.bracketTemplateId);
      if (eventTemplate) {
        // Filter template rounds to only those that have matches
        return eventTemplate.rounds
          .map((r) => r.name)
          .filter((roundName: string) => roundsInMatches.includes(roundName));
      }
    }

    // Fallback: return rounds as they appear
    return roundsInMatches;
  };

  const availableRounds = getOrderedRounds();

  // Get participants not yet in any match
  const participantsInMatches = new Set(
    matches.flatMap(m => [m.participant1Id, m.participant2Id].filter(Boolean))
  );
  const availableParticipants = participants.filter(
    (p: { id: string }) => !participantsInMatches.has(p.id)
  );

  return (
    <div className="p-8">
      <div className="max-w-6xl mx-auto">
        <div className="mb-6">
          <Button variant="ghost" size="sm" asChild className="mb-2">
            <Link to={`/admin/sports-seasons/${sportsSeason.id}/events/${event.id}`}>
              <ArrowLeft className="mr-2 h-4 w-4" />
              Back to Event
            </Link>
          </Button>
          <div className="flex items-center justify-between">
            <div>
              <h1 className="text-3xl font-bold">Playoff Bracket</h1>
              <p className="text-muted-foreground mt-1">
                {event.name} - {sportsSeason.sport.name} {sportsSeason.name}
              </p>
            </div>
          </div>
        </div>

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

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

          {/* Generate Bracket Form */}
          {matches.length === 0 && (
            <Card>
              <CardHeader>
                <CardTitle>Generate Bracket</CardTitle>
                <CardDescription>
                  Create the bracket structure for this playoff event
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Form method="post" className="space-y-4">
                  <input type="hidden" name="intent" value="generate-bracket" />

                  <div className="space-y-2">
                    <Label htmlFor="templateId">Bracket Template</Label>
                    <Select
                      name="templateId"
                      value={selectedTemplate}
                      onValueChange={handleTemplateChange}
                      required
                    >
                      <SelectTrigger id="templateId">
                        <SelectValue />
                      </SelectTrigger>
                      <SelectContent>
                        {templates.map((t) => (
                          <SelectItem key={t.id} value={t.id}>
                            {t.name} - {t.totalTeams} teams
                          </SelectItem>
                        ))}
                      </SelectContent>
                    </Select>
                    {template && (
                      <p className="text-sm text-muted-foreground">
                        Rounds: {template.rounds.map(r => r.name).join(" → ")}
                      </p>
                    )}
                  </div>

                  <div className="space-y-2">
                    <Label>Select Participants (in order)</Label>
                    <p className="text-sm text-muted-foreground">
                      Select {template?.totalTeams || 8} participants for the bracket
                    </p>
                    {[...Array(template?.totalTeams || 8)].map((_, i) => {
                      const availableParticipants = getAvailableParticipants(i);

                      return (
                        <Select
                          key={i}
                          name={`participant${i}`}
                          value={selectedParticipants[i] || ""}
                          onValueChange={(value) => handleParticipantChange(i, value)}
                          required
                        >
                          <SelectTrigger>
                            <SelectValue placeholder={`Seed ${i + 1}`} />
                          </SelectTrigger>
                          <SelectContent>
                            {availableParticipants.map((participant: { id: string; name: string }) => (
                              <SelectItem key={participant.id} value={participant.id}>
                                {participant.name}
                              </SelectItem>
                            ))}
                          </SelectContent>
                        </Select>
                      );
                    })}
                  </div>

                  <Button type="submit" className="w-full">
                    <Plus className="mr-2 h-4 w-4" />
                    Generate Bracket
                  </Button>
                </Form>
              </CardContent>
            </Card>
          )}

          {/* Bracket Display */}
          {availableRounds.map((round: string) => (
            <Card key={round}>
              <CardHeader>
                <CardTitle>{round}</CardTitle>
                <CardDescription>
                  {matchesByRound[round].length} {matchesByRound[round].length === 1 ? "match" : "matches"}
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-16">Match</TableHead>
                      <TableHead>Participant 1</TableHead>
                      <TableHead>Score</TableHead>
                      <TableHead className="w-24 text-center">vs</TableHead>
                      <TableHead>Score</TableHead>
                      <TableHead>Participant 2</TableHead>
                      <TableHead>Winner</TableHead>
                      <TableHead className="w-32">Actions</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {matchesByRound[round].map((match) => (
                      <TableRow key={match.id}>
                        <TableCell className="font-semibold">
                          {match.matchNumber}
                        </TableCell>
                        <TableCell>
                          {match.participant1?.name || "TBD"}
                        </TableCell>
                        <TableCell>
                          {match.participant1Score ? parseFloat(match.participant1Score) : "-"}
                        </TableCell>
                        <TableCell className="text-center text-muted-foreground">
                          vs
                        </TableCell>
                        <TableCell>
                          {match.participant2Score ? parseFloat(match.participant2Score) : "-"}
                        </TableCell>
                        <TableCell>
                          {match.participant2?.name || "TBD"}
                        </TableCell>
                        <TableCell>
                          {match.winner?.name ? (
                            <div className="flex items-center gap-1">
                              <Trophy className="h-4 w-4 text-yellow-500" />
                              {match.winner.name}
                            </div>
                          ) : (
                            "-"
                          )}
                        </TableCell>
                        <TableCell>
                          {!match.isComplete && match.participant1Id && match.participant2Id ? (
                            <Select
                              value={selectedWinners[match.id] || ""}
                              onValueChange={(value) => handleWinnerChange(match.id, value)}
                            >
                              <SelectTrigger className="h-8 w-full">
                                <SelectValue placeholder="Select winner" />
                              </SelectTrigger>
                              <SelectContent>
                                <SelectItem value={match.participant1Id}>
                                  {match.participant1?.name}
                                </SelectItem>
                                <SelectItem value={match.participant2Id}>
                                  {match.participant2?.name}
                                </SelectItem>
                              </SelectContent>
                            </Select>
                          ) : match.isComplete ? (
                            <span className="text-sm text-muted-foreground">Complete</span>
                          ) : (
                            <span className="text-sm text-muted-foreground">Waiting</span>
                          )}
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>

                {/* Batch Submit Winners */}
                {getPendingWinnersInRound(round).length > 0 && (
                  <Form method="post" className="mt-4">
                    <input type="hidden" name="intent" value="set-round-winners" />
                    <input type="hidden" name="round" value={round} />
                    {getPendingWinnersInRound(round).map(([matchId, winnerId]) => (
                      <input key={matchId} type="hidden" name={`winner-${matchId}`} value={winnerId} />
                    ))}
                    <Button type="submit" className="w-full">
                      Save {getPendingWinnersInRound(round).length} Winner{getPendingWinnersInRound(round).length > 1 ? 's' : ''} for {round}
                    </Button>
                  </Form>
                )}
              </CardContent>
            </Card>
          ))}

          {/* Complete Round Button */}
          {availableRounds.length > 0 && (
            <Card>
              <CardHeader>
                <CardTitle>Complete Round</CardTitle>
                <CardDescription>
                  Finalize the current round and calculate placements
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Form method="post">
                  <input type="hidden" name="intent" value="complete-round" />
                  <div className="space-y-4">
                    <div className="space-y-2">
                      <Label htmlFor="round">Round to Complete</Label>
                      <Select name="round" required>
                        <SelectTrigger id="round">
                          <SelectValue placeholder="Select round" />
                        </SelectTrigger>
                        <SelectContent>
                          {availableRounds.map((round: string) => (
                            <SelectItem key={round} value={round}>
                              {round}
                            </SelectItem>
                          ))}
                        </SelectContent>
                      </Select>
                    </div>
                    <Button type="submit">
                      Complete Round & Calculate Placements
                    </Button>
                  </div>
                </Form>
              </CardContent>
            </Card>
          )}
        </div>
      </div>
    </div>
  );
}
