import { Form, useLoaderData, useActionData, useNavigation, Link } from 'react-router';
import type { Route } from './+types/admin.sports-seasons.$id.events.$eventId.swiss-matches';

import { findSportsSeasonById } from '~/models/sports-season';
import { getScoringEventById } from '~/models/scoring-event';
import { findParticipantsBySportsSeasonId } from '~/models/season-participant';
import {
  findSeasonMatchesByScoringEventId,
  upsertSeasonMatch,
  updateSeasonMatch,
  deleteSeasonMatch,
  upsertMatchSubGame,
  findMatchSubGamesByMatchId,
} from '~/models/season-match';
import type { MatchStatus } from '~/models/season-match';
import { Button } from '~/components/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '~/components/ui/card';
import { Badge } from '~/components/ui/badge';
import { ArrowLeft, Plus, Save, Trash2 } from 'lucide-react';

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

export async function loader({ params }: Route.LoaderArgs) {
  const sportsSeasonId = params.id;
  const eventId = params.eventId;

  const [sportsSeason, event] = await Promise.all([
    findSportsSeasonById(sportsSeasonId),
    getScoringEventById(eventId),
  ]);

  if (!sportsSeason) throw new Response('Sports season not found', { status: 404 });
  if (!event) throw new Response('Event not found', { status: 404 });

  const [participants, matches] = await Promise.all([
    findParticipantsBySportsSeasonId(sportsSeasonId),
    findSeasonMatchesByScoringEventId(eventId),
  ]);

  return { sportsSeason, event, participants, matches };
}

interface ActionData {
  success?: boolean;
  message?: string;
}

export async function action({ request, params }: Route.ActionArgs) {
  const eventId = params.eventId;
  const sportsSeasonId = params.id;
  const formData = await request.formData();
  const intent = formData.get('intent') as string;

  if (intent === 'create-match') {
    const participant1Id = formData.get('participant1Id') as string;
    const participant2Id = formData.get('participant2Id') as string;
    const matchStage = parseInt(formData.get('matchStage') as string, 10);
    const matchRound = parseInt(formData.get('matchRound') as string, 10);
    const isSeries = formData.get('isSeries') === 'true';

    if (!participant1Id || !participant2Id || isNaN(matchStage) || isNaN(matchRound)) {
      return { success: false, message: 'Missing required fields.' };
    }

    const externalMatchId = `manual_${eventId}_s${matchStage}_r${matchRound}_${participant1Id}_${participant2Id}`;
    await upsertSeasonMatch({
      sportsSeasonId,
      scoringEventId: eventId,
      participant1Id,
      participant2Id,
      matchStage,
      matchRound,
      isSeries,
      status: 'scheduled',
      externalMatchId,
    });
    return { success: true, message: 'Match created.' };
  }

  if (intent === 'update-result') {
    const matchId = formData.get('matchId') as string;
    const participant1Score = formData.get('participant1Score');
    const participant2Score = formData.get('participant2Score');
    const winnerId = formData.get('winnerId') as string | null;
    const status = formData.get('status') as MatchStatus;

    const p1Score = participant1Score ? parseInt(participant1Score as string, 10) : null;
    const p2Score = participant2Score ? parseInt(participant2Score as string, 10) : null;

    await updateSeasonMatch(matchId, {
      participant1Score: p1Score,
      participant2Score: p2Score,
      winnerId: winnerId || null,
      status,
      completedAt: status === 'complete' ? new Date() : null,
    });

    // Handle sub-games (maps) if provided
    const mapCount = parseInt(formData.get('mapCount') as string ?? '0', 10);
    for (let i = 1; i <= mapCount; i++) {
      const mapLabel = formData.get(`map${i}_label`) as string | null;
      const map1Score = formData.get(`map${i}_p1`) as string | null;
      const map2Score = formData.get(`map${i}_p2`) as string | null;
      if (map1Score !== null && map2Score !== null) {
        await upsertMatchSubGame({
          seasonMatchId: matchId,
          gameNumber: i,
          gameLabel: mapLabel || null,
          participant1Score: parseInt(map1Score, 10),
          participant2Score: parseInt(map2Score, 10),
          status: 'complete',
        });
      }
    }

    return { success: true, message: 'Result saved.' };
  }

  if (intent === 'delete-match') {
    const matchId = formData.get('matchId') as string;
    await deleteSeasonMatch(matchId);
    return { success: true, message: 'Match deleted.' };
  }

  return { success: false, message: 'Unknown action.' };
}

const STAGE_NAMES: Record<number, string> = {
  1: 'Opening Stage',
  2: 'Challengers Stage',
  3: 'Legends Stage',
};

const STATUS_BADGE: Record<MatchStatus, { label: string; variant: 'default' | 'secondary' | 'outline' | 'destructive' }> = {
  scheduled: { label: 'Scheduled', variant: 'outline' },
  in_progress: { label: 'Live', variant: 'default' },
  complete: { label: 'Complete', variant: 'secondary' },
  canceled: { label: 'Canceled', variant: 'destructive' },
  postponed: { label: 'Postponed', variant: 'outline' },
};

export default function AdminSwissMatches() {
  const { sportsSeason, event, participants, matches } = useLoaderData<typeof loader>();
  const actionData = useActionData<ActionData>();
  const navigation = useNavigation();
  const isSubmitting = navigation.state === 'submitting';

  // Group matches by stage → round
  const byStage = new Map<number, Map<number, typeof matches>>();
  for (const m of matches) {
    const stage = m.matchStage ?? 0;
    const round = m.matchRound ?? 0;
    if (!byStage.has(stage)) byStage.set(stage, new Map());
    const stageMap = byStage.get(stage)!;
    if (!stageMap.has(round)) stageMap.set(round, []);
    stageMap.get(round)!.push(m);
  }

  return (
    <div className="container mx-auto py-8">
      <div className="mb-6">
        <Link
          to={`/admin/sports-seasons/${sportsSeason.id}/events/${event.id}/cs2-setup`}
          className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground mb-4"
        >
          <ArrowLeft className="h-4 w-4" />
          Back to CS2 Setup
        </Link>
        <h1 className="text-3xl font-bold mb-1">Swiss Match Entry</h1>
        <p className="text-muted-foreground">{event.name} — {sportsSeason.name}</p>
      </div>

      {actionData?.message && (
        <div className={`mb-4 p-3 rounded-md text-sm ${actionData.success ? 'bg-emerald-500/10 text-emerald-400 border border-emerald-500/30' : 'bg-destructive/10 text-destructive border border-destructive/30'}`}>
          {actionData.message}
        </div>
      )}

      {/* Create new match */}
      <Card className="mb-6">
        <CardHeader>
          <CardTitle>Add Match</CardTitle>
          <CardDescription>Manually add a Swiss round match.</CardDescription>
        </CardHeader>
        <CardContent>
          <Form method="post" className="grid grid-cols-2 md:grid-cols-3 gap-4">
            <input type="hidden" name="intent" value="create-match" />
            <div className="space-y-1">
              <label className="text-sm font-medium">Stage</label>
              <select name="matchStage" className="h-9 w-full text-sm rounded-md border border-input bg-background px-2">
                <option value="1">Stage 1 — Opening</option>
                <option value="2">Stage 2 — Challengers</option>
                <option value="3">Stage 3 — Legends</option>
              </select>
            </div>
            <div className="space-y-1">
              <label className="text-sm font-medium">Round</label>
              <select name="matchRound" className="h-9 w-full text-sm rounded-md border border-input bg-background px-2">
                {[1, 2, 3, 4, 5].map(r => <option key={r} value={r}>Round {r}</option>)}
              </select>
            </div>
            <div className="space-y-1">
              <label className="text-sm font-medium">Format</label>
              <select name="isSeries" className="h-9 w-full text-sm rounded-md border border-input bg-background px-2">
                <option value="false">Bo1</option>
                <option value="true">Bo3</option>
              </select>
            </div>
            <div className="space-y-1">
              <label className="text-sm font-medium">Team 1</label>
              <select name="participant1Id" className="h-9 w-full text-sm rounded-md border border-input bg-background px-2">
                <option value="">— select —</option>
                {participants.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </div>
            <div className="space-y-1">
              <label className="text-sm font-medium">Team 2</label>
              <select name="participant2Id" className="h-9 w-full text-sm rounded-md border border-input bg-background px-2">
                <option value="">— select —</option>
                {participants.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </div>
            <div className="flex items-end">
              <Button type="submit" disabled={isSubmitting} className="w-full">
                <Plus className="h-4 w-4 mr-2" />
                Add Match
              </Button>
            </div>
          </Form>
        </CardContent>
      </Card>

      {/* Existing matches grouped by stage/round */}
      {matches.length === 0 ? (
        <p className="text-sm text-muted-foreground">No matches yet.</p>
      ) : (
        [...byStage.entries()].sort(([a], [b]) => a - b).map(([stage, rounds]) => (
          <Card key={stage} className="mb-6">
            <CardHeader>
              <CardTitle>Stage {stage} — {STAGE_NAMES[stage] ?? ''}</CardTitle>
            </CardHeader>
            <CardContent className="space-y-6">
              {[...rounds.entries()].sort(([a], [b]) => a - b).map(([round, roundMatches]) => (
                <div key={round}>
                  <p className="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-3">Round {round}</p>
                  <div className="space-y-4">
                    {roundMatches.map(match => (
                      <div key={match.id} className="border border-border rounded-md p-4">
                        <div className="flex items-center justify-between mb-3">
                          <span className="text-sm font-medium">
                            {match.participant1?.name ?? '?'} vs {match.participant2?.name ?? '?'}
                          </span>
                          <div className="flex items-center gap-2">
                            <Badge variant={STATUS_BADGE[match.status]?.variant ?? 'outline'}>
                              {STATUS_BADGE[match.status]?.label ?? match.status}
                            </Badge>
                            <Form method="post">
                              <input type="hidden" name="intent" value="delete-match" />
                              <input type="hidden" name="matchId" value={match.id} />
                              <Button type="submit" variant="ghost" size="sm" className="text-destructive h-7 px-2" disabled={isSubmitting}>
                                <Trash2 className="h-3 w-3" />
                              </Button>
                            </Form>
                          </div>
                        </div>
                        <Form method="post" className="grid grid-cols-2 md:grid-cols-4 gap-3">
                          <input type="hidden" name="intent" value="update-result" />
                          <input type="hidden" name="matchId" value={match.id} />
                          <input type="hidden" name="mapCount" value={match.isSeries ? '3' : '0'} />
                          <div className="space-y-1">
                            <label className="text-xs font-medium">{match.participant1?.name ?? 'P1'} score</label>
                            <input
                              type="number"
                              name="participant1Score"
                              defaultValue={match.participant1Score ?? ''}
                              min="0"
                              className="h-8 w-full text-sm rounded-md border border-input bg-background px-2"
                            />
                          </div>
                          <div className="space-y-1">
                            <label className="text-xs font-medium">{match.participant2?.name ?? 'P2'} score</label>
                            <input
                              type="number"
                              name="participant2Score"
                              defaultValue={match.participant2Score ?? ''}
                              min="0"
                              className="h-8 w-full text-sm rounded-md border border-input bg-background px-2"
                            />
                          </div>
                          <div className="space-y-1">
                            <label className="text-xs font-medium">Winner</label>
                            <select
                              name="winnerId"
                              defaultValue={match.winnerId ?? ''}
                              className="h-8 w-full text-sm rounded-md border border-input bg-background px-2"
                            >
                              <option value="">— none —</option>
                              <option value={match.participant1Id ?? ''}>{match.participant1?.name ?? 'P1'}</option>
                              <option value={match.participant2Id ?? ''}>{match.participant2?.name ?? 'P2'}</option>
                            </select>
                          </div>
                          <div className="space-y-1">
                            <label className="text-xs font-medium">Status</label>
                            <select
                              name="status"
                              defaultValue={match.status}
                              className="h-8 w-full text-sm rounded-md border border-input bg-background px-2"
                            >
                              <option value="scheduled">Scheduled</option>
                              <option value="in_progress">In Progress</option>
                              <option value="complete">Complete</option>
                              <option value="canceled">Canceled</option>
                              <option value="postponed">Postponed</option>
                            </select>
                          </div>
                          {match.isSeries && (
                            <>
                              {[1, 2, 3].map(mapNum => {
                                const subGame = match.subGames.find(g => g.gameNumber === mapNum);
                                return (
                                  <div key={mapNum} className="col-span-2 grid grid-cols-3 gap-2">
                                    <input
                                      type="text"
                                      name={`map${mapNum}_label`}
                                      placeholder={`Map ${mapNum} name`}
                                      defaultValue={subGame?.gameLabel ?? ''}
                                      className="h-8 text-xs rounded-md border border-input bg-background px-2"
                                    />
                                    <input
                                      type="number"
                                      name={`map${mapNum}_p1`}
                                      placeholder="P1"
                                      defaultValue={subGame?.participant1Score ?? ''}
                                      min="0"
                                      className="h-8 text-xs rounded-md border border-input bg-background px-2"
                                    />
                                    <input
                                      type="number"
                                      name={`map${mapNum}_p2`}
                                      placeholder="P2"
                                      defaultValue={subGame?.participant2Score ?? ''}
                                      min="0"
                                      className="h-8 text-xs rounded-md border border-input bg-background px-2"
                                    />
                                  </div>
                                );
                              })}
                            </>
                          )}
                          <div className="col-span-2 md:col-span-4 flex justify-end">
                            <Button type="submit" size="sm" disabled={isSubmitting}>
                              <Save className="h-3 w-3 mr-1" />
                              Save
                            </Button>
                          </div>
                        </Form>
                      </div>
                    ))}
                  </div>
                </div>
              ))}
            </CardContent>
          </Card>
        ))
      )}
    </div>
  );
}
