import { Form, Link } from "react-router";
import { Fragment, useState, useEffect, useMemo } from "react";
import { localDateTimeToUtcIso } from "~/lib/date-utils";
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, X, Check, ChevronDown, ChevronRight, Calendar, TrendingUp, Trash2 } from "lucide-react";
import { getAllBracketTemplates, getBracketTemplate, getOrderedRoundsFromMatches, buildNCAA68SlotMap, ALL_16_SEEDS, type BracketRegion } from "~/lib/bracket-templates";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "~/components/ui/table";
import { Badge } from "~/components/ui/badge";
import { ParticipantSelector } from "~/components/ParticipantSelector";

export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
  return [{ title: `Bracket — ${data?.event?.name ?? "Event"} - Brackt Admin` }];
}

export { loader, action };

export default function EventBracket({
  loaderData,
  actionData,
}: Route.ComponentProps) {
  const { sportsSeason, event, participants, matches, tournamentGroups } = loaderData;
  const [selectedTemplate, setSelectedTemplate] = useState("simple_8");
  const [selectedParticipants, setSelectedParticipants] = useState<Record<number, string>>({});
  const [selectedWinners, setSelectedWinners] = useState<Record<string, string>>({});
  const [knockoutAssignments, setKnockoutAssignments] = useState<Record<string, string>>({});
  const [expandedMatches, setExpandedMatches] = useState<Set<string>>(new Set());
  const localTzAbbr = new Intl.DateTimeFormat("en-US", { timeZoneName: "short" })
    .formatToParts(new Date())
    .find(p => p.type === "timeZoneName")?.value ?? "local";

  const toggleMatchExpanded = (matchId: string) => {
    setExpandedMatches(prev => {
      const next = new Set(prev);
      if (next.has(matchId)) next.delete(matchId);
      else next.add(matchId);
      return next;
    });
  };
  const templates = getAllBracketTemplates();
  const template = templates.find((t) => t.id === selectedTemplate);

  // Determine if this is a group-stage event
  const hasGroupStage = template?.groupStage !== null;

  // Determine if this template uses named regions (e.g. NCAA 68)
  const hasRegions = (template?.regions?.length ?? 0) > 0;

  // Per-region configuration state: name + which seed slots are play-ins
  // Initialized from: stored event config → template defaults → empty
  const buildDefaultRegionConfig = (tmpl: typeof template) => {
    const source =
      (event.bracketRegionConfig as unknown as BracketRegion[] | null) ?? tmpl?.regions ?? [];
    return source.map((r) => ({
      name: r.name,
      playInSeeds: r.playIns.map((pi) => pi.seedSlot),
    }));
  };
  const [regionConfig, setRegionConfig] = useState(() => buildDefaultRegionConfig(template));

  // Derive effective BracketRegion[] from regionConfig state
  const effectiveRegions: BracketRegion[] = useMemo(() => {
    return regionConfig.map((cfg) => {
      const playInSet = new Set(cfg.playInSeeds);
      return {
        name: cfg.name,
        directSeeds: ALL_16_SEEDS.filter((s) => !playInSet.has(s)),
        playIns: cfg.playInSeeds.map((s) => ({ seedSlot: s, teams: 2 as const })),
      };
    });
  }, [regionConfig]);

  const regionSlotMap = useMemo(
    () => (effectiveRegions.length > 0 ? buildNCAA68SlotMap(effectiveRegions) : null),
    [effectiveRegions]
  );

  // Region config handlers
  const updateRegionName = (regionIdx: number, name: string) => {
    setRegionConfig((prev) =>
      prev.map((r, i) => (i === regionIdx ? { ...r, name } : r))
    );
  };
  const addPlayIn = (regionIdx: number) => {
    setRegionConfig((prev) =>
      prev.map((r, i) => {
        if (i !== regionIdx || r.playInSeeds.length >= 2) return r;
        // Default to seed 16 if no play-ins yet, otherwise seed 11
        const defaultSeed = r.playInSeeds.length === 0 ? 16 : 11;
        const seed = r.playInSeeds.includes(defaultSeed)
          ? ([11, 16].find((s) => !r.playInSeeds.includes(s)) ?? 11)
          : defaultSeed;
        return { ...r, playInSeeds: [...r.playInSeeds, seed] };
      })
    );
    // Reset participant selections since slot indices change
    setSelectedParticipants({});
  };
  const removePlayIn = (regionIdx: number, piIdx: number) => {
    setRegionConfig((prev) =>
      prev.map((r, i) =>
        i === regionIdx
          ? { ...r, playInSeeds: r.playInSeeds.filter((_, j) => j !== piIdx) }
          : r
      )
    );
    setSelectedParticipants({});
  };
  const updatePlayInSeed = (regionIdx: number, piIdx: number, seed: number) => {
    setRegionConfig((prev) =>
      prev.map((r, i) =>
        i === regionIdx
          ? {
              ...r,
              playInSeeds: r.playInSeeds.map((s, j) => (j === piIdx ? seed : s)),
            }
          : r
      )
    );
    setSelectedParticipants({});
  };

  const isGroupStageEvent = tournamentGroups.length > 0;

  // Determine the phase for group-stage events
  const knockoutPopulated = useMemo(() => {
    if (!isGroupStageEvent) return false;
    // Check if any Round of 32 match has participants assigned
    const r32Matches = matches.filter((m) => m.round === "Round of 32");
    return r32Matches.some((m) => m.participant1Id || m.participant2Id);
  }, [isGroupStageEvent, matches]);

  // Group stage stats
  const groupStageStats = useMemo(() => {
    if (!isGroupStageEvent) return null;
    let eliminated = 0;
    let total = 0;
    for (const group of tournamentGroups) {
      for (const member of group.members || []) {
        total++;
        if (member.eliminated) eliminated++;
      }
    }
    return { eliminated, advancing: total - eliminated, total };
  }, [isGroupStageEvent, tournamentGroups]);

  // Advancing participants (non-eliminated) for knockout assignment
  const advancingParticipants = useMemo(() => {
    if (!isGroupStageEvent) return [];
    const advancing: Array<{ id: string; name: string }> = [];
    for (const group of tournamentGroups) {
      for (const member of group.members || []) {
        if (!member.eliminated && member.participant) {
          advancing.push({
            id: member.participant.id,
            name: member.participant.name,
          });
        }
      }
    }
    return advancing;
  }, [isGroupStageEvent, tournamentGroups]);

  // Available advancing participants for knockout assignment (exclude already assigned)
  const availableAdvancingMap = useMemo(() => {
    const assignedIds = new Set(Object.values(knockoutAssignments).filter(Boolean));
    const map: Record<string, typeof advancingParticipants> = {};

    // Create 32 slots (16 matches × 2 slots)
    for (let m = 1; m <= 16; m++) {
      for (const slot of ["participant1Id", "participant2Id"]) {
        const key = `match-${m}-${slot}`;
        const currentSelection = knockoutAssignments[key];
        map[key] = advancingParticipants.filter(
          (p) => !assignedIds.has(p.id) || p.id === currentSelection
        );
      }
    }
    return map;
  }, [knockoutAssignments, advancingParticipants]);

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

  // Reset selected participants and region config when template changes
  const handleTemplateChange = (newTemplateId: string) => {
    setSelectedTemplate(newTemplateId);
    setSelectedParticipants({});
    const newTemplate = templates.find((t) => t.id === newTemplateId);
    setRegionConfig(buildDefaultRegionConfig(newTemplate));
  };

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

  // Memoized available participants calculation
  const availableParticipantsMap = useMemo(() => {
    const selectedIdsSet = new Set(Object.values(selectedParticipants));
    const map: Record<number, typeof participants> = {};
    const totalSeeds = template?.totalTeams || 8;

    for (let i = 0; i < totalSeeds; i++) {
      const currentSelection = selectedParticipants[i];
      map[i] = participants.filter((p: { id: string; name: string }) => {
        return !selectedIdsSet.has(p.id) || p.id === currentSelection;
      });
    }
    return map;
  }, [selectedParticipants, participants, template?.totalTeams]);

  const getAvailableParticipants = (seedIndex: number) => {
    return availableParticipantsMap[seedIndex] || participants;
  };

  // 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) => m.id === matchId);
        return match && match.round === round && !match.isComplete;
      });
  };

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

  // Memoized: Get available rounds in chronological order
  const availableRounds = useMemo(() => {
    const bracketTemplate = event.bracketTemplateId ? getBracketTemplate(event.bracketTemplateId) : undefined;
    return getOrderedRoundsFromMatches(matches, bracketTemplate);
  }, [matches, event.bracketTemplateId]);

  // Check if all matches are complete
  const allMatchesComplete = useMemo(() => {
    return matches.length > 0 && matches.every((m) => m.isComplete);
  }, [matches]);

  // No bracket and no groups yet = setup phase
  const showSetup = matches.length === 0 && !isGroupStageEvent;

  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-emerald-500/15 text-emerald-400 px-4 py-3 rounded-md text-sm">
              {actionData.success}
            </div>
          )}

          {/* Reprocess Eliminations - For existing brackets (non-group-stage) */}
          {matches.length > 0 && !isGroupStageEvent && (
            <Card>
              <CardHeader>
                <CardTitle>Reprocess Eliminations</CardTitle>
                <CardDescription>
                  Mark participants not in this bracket as eliminated (for brackets created before automatic elimination tracking)
                </CardDescription>
              </CardHeader>
              <CardContent>
                <Form method="post">
                  <input type="hidden" name="intent" value="reprocess-eliminations" />
                  <div className="space-y-4">
                    <div className="text-sm text-muted-foreground">
                      This will set finalPosition = 0 for all participants who are not in any playoff match,
                      allowing probability recalculation to set their odds to 0%.
                    </div>
                    <Button type="submit" variant="outline">
                      Reprocess Eliminations
                    </Button>
                  </div>
                </Form>
              </CardContent>
            </Card>
          )}

          {/* ====== SETUP PHASE ====== */}
          {showSetup && (
            <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">
                  {/* Intent depends on whether this is a group-stage template */}
                  <input
                    type="hidden"
                    name="intent"
                    value={hasGroupStage ? "generate-groups" : "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">
                        {template.groupStage ? (
                          <>
                            Groups: {template.groupStage.groupCount} groups of {template.groupStage.teamsPerGroup}
                            {" | "}Knockout: {template.rounds.map(r => r.name).join(" \u2192 ")}
                          </>
                        ) : (
                          <>Rounds: {template.rounds.map(r => r.name).join(" \u2192 ")}</>
                        )}
                      </p>
                    )}
                  </div>

                  {/* Group-stage template: show group assignments */}
                  {hasGroupStage && template?.groupStage && (
                    <div className="space-y-4">
                      <Label>Assign Participants to Groups</Label>
                      <p className="text-sm text-muted-foreground">
                        Assign {template.totalTeams} participants across {template.groupStage.groupCount} groups
                        ({template.groupStage.teamsPerGroup} per group).
                      </p>
                      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                        {template.groupStage.groupLabels.map((label, groupIndex) => (
                          <Card key={label} className="border-dashed">
                            <CardHeader className="py-3 px-4">
                              <CardTitle className="text-base">Group {label}</CardTitle>
                            </CardHeader>
                            <CardContent className="px-4 pb-4 space-y-2">
                              {[...Array(template.groupStage?.teamsPerGroup ?? 0)].map((_, teamIndex) => {
                                const seedIndex = groupIndex * (template.groupStage?.teamsPerGroup ?? 0) + teamIndex;
                                const availableParticipants = getAvailableParticipants(seedIndex);

                                return (
                                  <div key={seedIndex}>
                                    <input
                                      type="hidden"
                                      name={`participant${seedIndex}`}
                                      value={selectedParticipants[seedIndex] || ""}
                                      required
                                    />
                                    <ParticipantSelector
                                      participants={availableParticipants}
                                      value={selectedParticipants[seedIndex] || ""}
                                      onValueChange={(value) => handleParticipantChange(seedIndex, value)}
                                      placeholder={`Team ${teamIndex + 1}...`}
                                    />
                                  </div>
                                );
                              })}
                            </CardContent>
                          </Card>
                        ))}
                      </div>
                    </div>
                  )}

                  {/* Non-group-stage template: region-grouped or flat seeded list */}
                  {!hasGroupStage && hasRegions && regionSlotMap && (
                    <div className="space-y-6">

                      {/* ── Region configuration ─────────────────────────────── */}
                      <div className="border rounded-lg p-4 space-y-3">
                        <div>
                          <h4 className="font-semibold text-sm">Configure Regions</h4>
                          <p className="text-xs text-muted-foreground mt-0.5">
                            Set each region's name and which seed slots are play-in games.
                          </p>
                        </div>
                        {regionConfig.map((region, r) => (
                          // eslint-disable-next-line react/no-array-index-key
                          <div key={r} className="flex flex-wrap items-center gap-2">
                            <Input
                              className="w-36 h-8 text-sm"
                              value={region.name}
                              onChange={(e) => updateRegionName(r, e.target.value)}
                              placeholder={`Region ${r + 1}`}
                            />
                            {region.playInSeeds.map((seed, pi) => (
                              // eslint-disable-next-line react/no-array-index-key
                              <div key={pi} className="flex items-center gap-1">
                                <span className="text-xs text-muted-foreground">play-in seed:</span>
                                <Select
                                  value={String(seed)}
                                  onValueChange={(val) => updatePlayInSeed(r, pi, parseInt(val, 10))}
                                >
                                  <SelectTrigger className="h-8 w-16 text-sm">
                                    <SelectValue />
                                  </SelectTrigger>
                                  <SelectContent>
                                    {ALL_16_SEEDS.map((s) => (
                                      <SelectItem key={s} value={String(s)}>{s}</SelectItem>
                                    ))}
                                  </SelectContent>
                                </Select>
                                <Button
                                  type="button"
                                  variant="ghost"
                                  size="sm"
                                  className="h-7 w-7 p-0 text-muted-foreground"
                                  onClick={() => removePlayIn(r, pi)}
                                >
                                  <X className="h-3 w-3" />
                                </Button>
                              </div>
                            ))}
                            {region.playInSeeds.length < 2 && (
                              <Button
                                type="button"
                                variant="outline"
                                size="sm"
                                className="h-7 text-xs"
                                onClick={() => addPlayIn(r)}
                              >
                                <Plus className="h-3 w-3 mr-1" />
                                Add play-in
                              </Button>
                            )}
                          </div>
                        ))}
                        {/* Hidden fields so server receives the region config */}
                        {regionConfig.map((region, r) => (
                          // eslint-disable-next-line react/no-array-index-key
                          <Fragment key={r}>
                            <input type="hidden" name={`regionName${r}`} value={region.name} />
                            <input type="hidden" name={`regionPlayInSeeds${r}`} value={region.playInSeeds.join(",")} />
                          </Fragment>
                        ))}
                      </div>

                      {/* ── Seed entry per region ─────────────────────────────── */}
                      <p className="text-sm text-muted-foreground">
                        Select participants by region. Use search to find teams quickly.
                      </p>
                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        {effectiveRegions.map((region, r) => {
                          const directOffset = regionSlotMap.directOffsets[r];
                          return (
                            // eslint-disable-next-line react/no-array-index-key
                            <div key={r} className="border rounded-lg p-4 space-y-2">
                              <h4 className="font-semibold text-sm">{region.name || `Region ${r + 1}`}</h4>
                              {region.directSeeds.map((seedNum, pos) => {
                                const globalIdx = directOffset + pos;
                                const opponentSeed = 17 - seedNum;
                                const opponentIsPlayIn = region.playIns.some((pi) => pi.seedSlot === opponentSeed);
                                return (
                                  <div key={seedNum} className="flex items-center gap-2">
                                    <Label className="w-16 text-xs text-muted-foreground shrink-0">
                                      Seed {seedNum}
                                    </Label>
                                    <div className="flex-1 min-w-0">
                                      <input
                                        type="hidden"
                                        name={`participant${globalIdx}`}
                                        value={selectedParticipants[globalIdx] || ""}
                                        required
                                      />
                                      <ParticipantSelector
                                        participants={getAvailableParticipants(globalIdx)}
                                        value={selectedParticipants[globalIdx] || ""}
                                        onValueChange={(value) => handleParticipantChange(globalIdx, value)}
                                        placeholder={`Seed ${seedNum}…`}
                                      />
                                    </div>
                                    {opponentIsPlayIn && (
                                      <span className="text-xs text-muted-foreground shrink-0">← faces play-in</span>
                                    )}
                                  </div>
                                );
                              })}
                              {region.playIns.length > 0 && (
                                <p className="text-xs text-muted-foreground pt-1 border-t">
                                  {region.playIns.map((pi) => `Seed ${pi.seedSlot}`).join(" & ")} via play-in ↓
                                </p>
                              )}
                            </div>
                          );
                        })}
                      </div>

                      {/* ── Play-in team entry ─────────────────────────────────── */}
                      {regionSlotMap.playInOffsets.length > 0 && (
                        <div className="border rounded-lg p-4 space-y-4">
                          <h4 className="font-semibold text-sm">Play-In Teams</h4>
                          <p className="text-xs text-muted-foreground">
                            Enter both teams for each play-in game. The winner advances to the main bracket.
                          </p>
                          {regionSlotMap.playInOffsets.map((pi, ffIdx) => {
                            const regionName = effectiveRegions[pi.regionIndex]?.name || `Region ${pi.regionIndex + 1}`;
                            const idx1 = pi.startIndex;
                            const idx2 = pi.startIndex + 1;
                            return (
                              <div key={`${pi.regionIndex}-${pi.seedSlot}`} className="space-y-2">
                                <p className="text-xs font-medium text-muted-foreground">
                                  Play-In {ffIdx + 1} — {regionName} {pi.seedSlot}-seed
                                </p>
                                {[idx1, idx2].map((globalIdx, slot) => (
                                  <div key={globalIdx} className="flex items-center gap-2">
                                    <Label className="w-16 text-xs text-muted-foreground shrink-0">
                                      Team {slot + 1}
                                    </Label>
                                    <div className="flex-1 min-w-0">
                                      <input
                                        type="hidden"
                                        name={`participant${globalIdx}`}
                                        value={selectedParticipants[globalIdx] || ""}
                                        required
                                      />
                                      <ParticipantSelector
                                        participants={getAvailableParticipants(globalIdx)}
                                        value={selectedParticipants[globalIdx] || ""}
                                        onValueChange={(value) => handleParticipantChange(globalIdx, value)}
                                        placeholder={`${regionName} ${pi.seedSlot}-seed play-in team ${slot + 1}…`}
                                      />
                                    </div>
                                  </div>
                                ))}
                              </div>
                            );
                          })}
                        </div>
                      )}
                    </div>
                  )}

                  {/* Non-group-stage, non-region template: flat seeded list */}
                  {!hasGroupStage && !hasRegions && (
                    <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. Use search to quickly find participants.
                      </p>
                      {[...Array(template?.totalTeams || 8)].map((_, i) => {
                        const availableParticipants = getAvailableParticipants(i);

                        return (
                          // eslint-disable-next-line react/no-array-index-key
                          <div key={i} className="flex items-center gap-2">
                            <Label className="w-20 text-sm text-muted-foreground shrink-0">
                              Seed {i + 1}
                            </Label>
                            <div className="flex-1 min-w-0">
                              <input
                                type="hidden"
                                name={`participant${i}`}
                                value={selectedParticipants[i] || ""}
                                required
                              />
                              <ParticipantSelector
                                participants={availableParticipants}
                                value={selectedParticipants[i] || ""}
                                onValueChange={(value) => handleParticipantChange(i, value)}
                                placeholder={`Select seed ${i + 1}...`}
                              />
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  )}

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

          {/* ====== GROUP STAGE MANAGEMENT (Phase 2) ====== */}
          {isGroupStageEvent && !knockoutPopulated && (
            <>
              {/* Group Stage Summary */}
              {groupStageStats && (
                <Card>
                  <CardHeader>
                    <CardTitle>Group Stage</CardTitle>
                    <CardDescription>
                      Manage group stage eliminations. Mark teams as eliminated, then assign advancing teams to the knockout bracket.
                    </CardDescription>
                  </CardHeader>
                  <CardContent>
                    <div className="flex gap-4 text-sm">
                      <Badge variant="secondary">
                        {groupStageStats.total} total teams
                      </Badge>
                      <Badge variant="destructive">
                        {groupStageStats.eliminated} eliminated
                      </Badge>
                      <Badge variant="default">
                        {groupStageStats.advancing} advancing
                      </Badge>
                    </div>
                  </CardContent>
                </Card>
              )}

              {/* Group Cards */}
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
                {tournamentGroups.map((group) => (
                  <Card key={group.id}>
                    <CardHeader className="py-3 px-4">
                      <CardTitle className="text-base">Group {group.groupName}</CardTitle>
                    </CardHeader>
                    <CardContent className="px-4 pb-4 space-y-2">
                      {(group.members || []).map((member) => (
                        <div
                          key={member.id}
                          className={`flex items-center justify-between gap-2 p-2 rounded-md border ${
                            member.eliminated
                              ? "bg-destructive/10 border-destructive/20"
                              : "bg-background border-border"
                          }`}
                        >
                          <span
                            className={`text-sm truncate ${
                              member.eliminated ? "line-through text-muted-foreground" : ""
                            }`}
                          >
                            {member.participant?.name || "Unknown"}
                          </span>
                          <Form method="post" className="shrink-0">
                            <input type="hidden" name="intent" value="toggle-elimination" />
                            <input type="hidden" name="memberId" value={member.id} />
                            <Button
                              type="submit"
                              size="sm"
                              variant={member.eliminated ? "outline" : "destructive"}
                              className="h-7 text-xs"
                            >
                              {member.eliminated ? (
                                <>
                                  <Check className="h-3 w-3 mr-1" />
                                  Reinstate
                                </>
                              ) : (
                                <>
                                  <X className="h-3 w-3 mr-1" />
                                  Eliminate
                                </>
                              )}
                            </Button>
                          </Form>
                        </div>
                      ))}
                    </CardContent>
                  </Card>
                ))}
              </div>

              {/* Knockout Assignment Section */}
              {groupStageStats && groupStageStats.advancing === 32 && (
                <Card className="border-blue-500">
                  <CardHeader>
                    <CardTitle>Assign Knockout Bracket</CardTitle>
                    <CardDescription>
                      32 teams are advancing. Assign them to the Round of 32 knockout bracket slots.
                    </CardDescription>
                  </CardHeader>
                  <CardContent>
                    <Form method="post" className="space-y-4">
                      <input type="hidden" name="intent" value="populate-knockout" />

                      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                        {[...Array(16)].map((_, matchIndex) => {
                          const matchNum = matchIndex + 1;
                          const key1 = `match-${matchNum}-participant1Id`;
                          const key2 = `match-${matchNum}-participant2Id`;

                          return (
                            <Card key={matchNum} className="border-dashed">
                              <CardContent className="p-4 space-y-2">
                                <div className="text-sm font-semibold text-muted-foreground">
                                  Match {matchNum}
                                </div>
                                <input
                                  type="hidden"
                                  name={key1}
                                  value={knockoutAssignments[key1] || ""}
                                  required
                                />
                                <ParticipantSelector
                                  participants={availableAdvancingMap[key1] || []}
                                  value={knockoutAssignments[key1] || ""}
                                  onValueChange={(value) =>
                                    setKnockoutAssignments((prev) => ({ ...prev, [key1]: value }))
                                  }
                                  placeholder="Team 1..."
                                />
                                <div className="text-center text-xs text-muted-foreground">vs</div>
                                <input
                                  type="hidden"
                                  name={key2}
                                  value={knockoutAssignments[key2] || ""}
                                  required
                                />
                                <ParticipantSelector
                                  participants={availableAdvancingMap[key2] || []}
                                  value={knockoutAssignments[key2] || ""}
                                  onValueChange={(value) =>
                                    setKnockoutAssignments((prev) => ({ ...prev, [key2]: value }))
                                  }
                                  placeholder="Team 2..."
                                />
                              </CardContent>
                            </Card>
                          );
                        })}
                      </div>

                      <Button type="submit" className="w-full">
                        Populate Knockout Bracket
                      </Button>
                    </Form>
                  </CardContent>
                </Card>
              )}

              {groupStageStats && groupStageStats.advancing !== 32 && groupStageStats.eliminated > 0 && (
                <Card>
                  <CardContent className="pt-6">
                    <p className="text-sm text-muted-foreground">
                      {groupStageStats.advancing} teams advancing (need exactly 32 to populate knockout bracket).
                      {groupStageStats.advancing > 32 && ` Eliminate ${groupStageStats.advancing - 32} more.`}
                      {groupStageStats.advancing < 32 && ` Reinstate ${32 - groupStageStats.advancing} teams or adjust eliminations.`}
                    </p>
                  </CardContent>
                </Card>
              )}
            </>
          )}

          {/* ====== KNOCKOUT BRACKET DISPLAY (Phase 3) ====== */}
          {/* Show bracket rounds when: non-group event with matches, OR group event with knockout populated */}
          {((matches.length > 0 && !isGroupStageEvent) || knockoutPopulated) && (
            <>
              {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-8" />
                          <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) => (
                          <Fragment key={match.id}>
                          <TableRow>
                            <TableCell className="w-8 p-1">
                              <button
                                type="button"
                                onClick={() => toggleMatchExpanded(match.id)}
                                className="text-muted-foreground hover:text-foreground"
                                aria-label="Toggle games and odds"
                              >
                                {expandedMatches.has(match.id)
                                  ? <ChevronDown className="h-4 w-4" />
                                  : <ChevronRight className="h-4 w-4" />}
                              </button>
                            </TableCell>
                            <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>

                          {/* Expanded: Games & Odds panel */}
                          {expandedMatches.has(match.id) && (
                            <TableRow className="bg-muted/30">
                              <TableCell colSpan={9} className="p-4">
                                <div className="grid grid-cols-1 md:grid-cols-2 gap-6">

                                  {/* Games section */}
                                  <div>
                                    <div className="flex items-center gap-2 mb-3">
                                      <Calendar className="h-4 w-4 text-muted-foreground" />
                                      <span className="text-sm font-semibold">Game Schedule</span>
                                    </div>

                                    {/* Existing games */}
                                    {match.games?.length > 0 ? (
                                      <div className="space-y-2 mb-3">
                                        {match.games.map((game) => (
                                          <div key={game.id} className="flex items-center gap-2 text-sm bg-background rounded p-2 border">
                                            <span className="font-medium w-12 shrink-0">Game {game.gameNumber}</span>
                                            <span className="text-muted-foreground flex-1">
                                              {game.scheduledAt
                                                ? new Date(game.scheduledAt).toLocaleString()
                                                : "No date set"}
                                            </span>
                                            <Badge variant={
                                              game.status === "complete" ? "default"
                                              : game.status === "postponed" ? "destructive"
                                              : "secondary"
                                            } className="text-xs">
                                              {game.status}
                                            </Badge>
                                            {game.status === "complete" && game.winner && (
                                              <span className="text-xs text-muted-foreground">
                                                W: {game.winner.name}
                                              </span>
                                            )}
                                            <Form method="post" className="shrink-0">
                                              <input type="hidden" name="intent" value="delete-game" />
                                              <input type="hidden" name="gameId" value={game.id} />
                                              <button type="submit" className="text-muted-foreground hover:text-destructive">
                                                <Trash2 className="h-3.5 w-3.5" />
                                              </button>
                                            </Form>
                                          </div>
                                        ))}
                                      </div>
                                    ) : (
                                      <p className="text-xs text-muted-foreground mb-3">No games scheduled yet.</p>
                                    )}

                                    {/* Add game form */}
                                    <Form method="post" className="flex gap-2 items-end" onSubmit={(e) => {
                                      const form = e.currentTarget;
                                      // Read from the datetime-local display input (not submitted directly)
                                      const scheduledAtLocal = form.elements.namedItem("scheduledAtLocal") as HTMLInputElement;
                                      // Write the UTC ISO string into the hidden input that IS submitted
                                      const scheduledAtHidden = form.elements.namedItem("scheduledAt") as HTMLInputElement;
                                      if (scheduledAtHidden) {
                                        scheduledAtHidden.value = localDateTimeToUtcIso(scheduledAtLocal?.value) ?? "";
                                      }
                                    }}>
                                      <input type="hidden" name="intent" value="add-game" />
                                      <input type="hidden" name="matchId" value={match.id} />
                                      {/* Hidden field holds the UTC ISO string written by onSubmit */}
                                      <input type="hidden" name="scheduledAt" defaultValue="" />
                                      <div className="flex-1">
                                        <Label className="text-xs">Game #</Label>
                                        <Input
                                          name="gameNumber"
                                          type="number"
                                          min={1}
                                          max={9}
                                          defaultValue={(match.games?.length ?? 0) + 1}
                                          className="h-8 w-20"
                                          required
                                        />
                                      </div>
                                      <div className="flex-1">
                                        <Label className="text-xs">Date &amp; Time ({localTzAbbr})</Label>
                                        <Input
                                          name="scheduledAtLocal"
                                          type="datetime-local"
                                          className="h-8"
                                        />
                                      </div>
                                      <Button type="submit" size="sm" variant="outline" className="h-8">
                                        <Plus className="h-3.5 w-3.5 mr-1" />
                                        Add
                                      </Button>
                                    </Form>
                                  </div>

                                  {/* Odds section */}
                                  <div>
                                    <div className="flex items-center gap-2 mb-3">
                                      <TrendingUp className="h-4 w-4 text-muted-foreground" />
                                      <span className="text-sm font-semibold">Moneyline Odds</span>
                                    </div>

                                    {match.odds?.length > 0 ? (
                                      <div className="space-y-2 mb-3">
                                        {match.odds.map((odd) => (
                                          <div key={odd.id} className="flex items-center gap-2 text-sm bg-background rounded p-2 border">
                                            <span className="flex-1 font-medium">{odd.participant?.name}</span>
                                            <span className={`font-mono ${odd.moneylineOdds > 0 ? "text-emerald-500" : "text-muted-foreground"}`}>
                                              {odd.moneylineOdds > 0 ? "+" : ""}{odd.moneylineOdds}
                                            </span>
                                            <span className="text-xs text-muted-foreground">
                                              ({(parseFloat(odd.impliedProbability) * 100).toFixed(1)}%)
                                            </span>
                                            {odd.oddsSource && (
                                              <span className="text-xs text-muted-foreground">{odd.oddsSource}</span>
                                            )}
                                            <Form method="post" className="shrink-0">
                                              <input type="hidden" name="intent" value="delete-odds" />
                                              <input type="hidden" name="matchId" value={match.id} />
                                              <input type="hidden" name="participantId" value={odd.participantId} />
                                              <button type="submit" className="text-muted-foreground hover:text-destructive">
                                                <Trash2 className="h-3.5 w-3.5" />
                                              </button>
                                            </Form>
                                          </div>
                                        ))}
                                      </div>
                                    ) : (
                                      <p className="text-xs text-muted-foreground mb-3">No odds set.</p>
                                    )}

                                    {/* Set odds forms for each participant */}
                                    {[
                                      { id: match.participant1Id, name: match.participant1?.name },
                                      { id: match.participant2Id, name: match.participant2?.name },
                                    ].filter(p => p.id).map(participant => (
                                      <Form key={participant.id} method="post" className="flex gap-2 items-end mb-2">
                                        <input type="hidden" name="intent" value="upsert-odds" />
                                        <input type="hidden" name="matchId" value={match.id} />
                                        <input type="hidden" name="participantId" value={participant.id ?? ""} />
                                        <div className="flex-1">
                                          <Label className="text-xs">{participant.name ?? "TBD"}</Label>
                                          <Input
                                            name="moneylineOdds"
                                            type="number"
                                            placeholder="-110"
                                            className="h-8"
                                            required
                                          />
                                        </div>
                                        <div className="flex-1">
                                          <Label className="text-xs">Source</Label>
                                          <Input
                                            name="oddsSource"
                                            placeholder="e.g. DraftKings"
                                            className="h-8"
                                          />
                                        </div>
                                        <Button type="submit" size="sm" variant="outline" className="h-8">
                                          Set
                                        </Button>
                                      </Form>
                                    ))}
                                  </div>
                                </div>
                              </TableCell>
                            </TableRow>
                          )}
                          </Fragment>
                        ))}
                      </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>
              ))}


              {/* Finalize Bracket Button */}
              {allMatchesComplete && !event.isComplete && (
                <Card className="border-emerald-500/30 bg-emerald-500/10">
                  <CardHeader>
                    <CardTitle className="flex items-center gap-2">
                      <Trophy className="h-5 w-5 text-emerald-400" />
                      Finalize Bracket
                    </CardTitle>
                    <CardDescription>
                      All matches are complete! Process all rounds and assign final placements.
                    </CardDescription>
                  </CardHeader>
                  <CardContent>
                    <Form method="post">
                      <input type="hidden" name="intent" value="finalize-bracket" />
                      <div className="space-y-4">
                        <div className="text-sm space-y-2">
                          <p className="font-medium">This will:</p>
                          <ul className="list-disc list-inside space-y-1 text-muted-foreground">
                            <li>Process all playoff rounds in order</li>
                            <li>Assign fantasy placements (1st-8th) based on bracket results</li>
                            <li>Assign 0 points to participants not in the bracket</li>
                            <li>Mark the event as complete</li>
                            <li>Recalculate all team standings</li>
                          </ul>
                        </div>
                        <Button type="submit" className="w-full">
                          Finalize Bracket & Update Standings
                        </Button>
                      </div>
                    </Form>
                  </CardContent>
                </Card>
              )}
            </>
          )}

          {/* Event Complete Badge */}
          {event.isComplete && (
            <Card className="border-electric/30 bg-electric/10">
              <CardContent className="pt-6">
                <div className="flex items-center gap-2 text-electric">
                  <Trophy className="h-5 w-5" />
                  <span className="font-semibold">Event Complete</span>
                  <span className="text-sm text-muted-foreground ml-auto">
                    {event.completedAt && new Date(event.completedAt).toLocaleDateString()}
                  </span>
                </div>
              </CardContent>
            </Card>
          )}
        </div>
      </div>
    </div>
  );
}
