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

import { findSportsSeasonById } from '~/models/sports-season';
import { getScoringEventById } from '~/models/scoring-event';
import { findParticipantsBySportsSeasonId } from '~/models/participant';
import {
  getCs2StageResultsForEvent,
  upsertCs2StageAssignments,
  markCs2StageEliminations,
  clearCs2StageAssignments,
} from '~/models/cs2-major-stage';
import { Button } from '~/components/ui/button';
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '~/components/ui/card';
import { Badge } from '~/components/ui/badge';
import { ArrowLeft, Save, Trash2, CheckCircle2 } from 'lucide-react';
import { useState } from 'react';

export function meta({ data }: Route.MetaArgs): Route.MetaDescriptors {
  return [{ title: `CS2 Stage Setup — ${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, stageResults] = await Promise.all([
    findParticipantsBySportsSeasonId(sportsSeasonId),
    getCs2StageResultsForEvent(eventId),
  ]);

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

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

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

  if (intent === 'reset') {
    await clearCs2StageAssignments(eventId);
    return { success: true, message: 'Stage assignments cleared.' };
  }

  if (intent === 'assign') {
    const assignments: Array<{ scoringEventId: string; participantId: string; stageEntry: number }> = [];
    for (const [key, value] of formData.entries()) {
      if (key.startsWith('stage_')) {
        const participantId = key.slice('stage_'.length);
        const stageEntry = parseInt(value as string, 10);
        if (!isNaN(stageEntry) && stageEntry >= 1 && stageEntry <= 3) {
          assignments.push({ scoringEventId: eventId, participantId, stageEntry });
        }
      }
    }

    if (assignments.length === 0) {
      return { success: false, message: 'No stage assignments submitted.' };
    }

    await upsertCs2StageAssignments(assignments);
    return { success: true, message: `Saved ${assignments.length} stage assignments.` };
  }

  if (intent === 'mark-eliminations') {
    // Parse elimination data: elim_{participantId} = winsAtElimination (0, 1, or 2)
    const eliminations: Array<{ participantId: string; winsAtElimination: number }> = [];
    for (const [key, value] of formData.entries()) {
      if (key.startsWith('elim_')) {
        const participantId = key.slice('elim_'.length);
        const wins = parseInt(value as string, 10);
        if (!isNaN(wins) && wins >= 0 && wins <= 2) {
          eliminations.push({ participantId, winsAtElimination: wins });
        }
      }
    }

    await markCs2StageEliminations(eventId, eliminations);
    return { success: true, message: `Marked ${eliminations.length} eliminations.` };
  }

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

const STAGE_LABELS: Record<number, { label: string; description: string; maxTeams: number; badgeVariant: 'default' | 'secondary' | 'outline' }> = {
  1: { label: 'Stage 1', description: 'Opening Stage (16 teams, Bo1 Swiss)', maxTeams: 16, badgeVariant: 'outline' },
  2: { label: 'Stage 2', description: 'Elimination Stage (8 Challengers, Bo1/Bo3 Swiss)', maxTeams: 8, badgeVariant: 'secondary' },
  3: { label: 'Stage 3', description: 'Decider Stage (8 Legends, all Bo3 Swiss)', maxTeams: 8, badgeVariant: 'default' },
};

const RECORD_OPTIONS = [
  { value: '2', label: '2-3 (advanced furthest)' },
  { value: '1', label: '1-3' },
  { value: '0', label: '0-3 (earliest exit)' },
];

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

  // Build maps from existing stage results
  const stageMap = new Map(stageResults.map(r => [r.participantId, r]));
  const assignedIds = new Set(stageResults.map(r => r.participantId));
  const unassignedParticipants = participants.filter(p => !assignedIds.has(p.id));

  // Stage assignment state (local, submitted via form)
  const [stageSelections, setStageSelections] = useState<Record<string, string>>(() => {
    const initial: Record<string, string> = {};
    stageResults.forEach(r => { initial[r.participantId] = r.stageEntry.toString(); });
    return initial;
  });

  // Group participants by stage for display
  const byStage: Record<number, typeof stageResults> = { 1: [], 2: [], 3: [] };
  for (const r of stageResults) {
    byStage[r.stageEntry]?.push(r);
  }

  const stageCounts = Object.fromEntries(
    Object.entries(byStage).map(([k, v]) => [k, v.length])
  );

  return (
    <div className="container mx-auto py-8">
      <div className="mb-6">
        <Link
          to={`/admin/sports-seasons/${sportsSeason.id}/events/${event.id}`}
          className="flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground mb-4"
        >
          <ArrowLeft className="h-4 w-4" />
          Back to event
        </Link>
        <h1 className="text-3xl font-bold mb-1">CS2 Stage Setup</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>
      )}

      {/* Stage Assignment */}
      <Card className="mb-6">
        <CardHeader>
          <CardTitle className="flex items-center justify-between">
            Stage Assignments
            {stageResults.length > 0 && (
              <Form method="post">
                <input type="hidden" name="intent" value="reset" />
                <Button type="submit" variant="ghost" size="sm" className="text-destructive">
                  <Trash2 className="h-4 w-4 mr-1" />
                  Reset all
                </Button>
              </Form>
            )}
          </CardTitle>
          <CardDescription>
            Assign each team to their starting stage. Stage 1 = 16 Opening Stage teams,
            Stage 2 = 8 Challengers (skip Stage 1), Stage 3 = 8 Legends (skip Stages 1 and 2).
            Total: 32 teams across all three stages.
          </CardDescription>
        </CardHeader>
        <CardContent>
          <Form method="post" className="space-y-6">
            <input type="hidden" name="intent" value="assign" />

            {/* Stage summary badges */}
            <div className="flex gap-3 flex-wrap">
              {[1, 2, 3].map(stage => (
                <div key={stage} className="flex items-center gap-2 text-sm">
                  <Badge variant={STAGE_LABELS[stage].badgeVariant}>{STAGE_LABELS[stage].label}</Badge>
                  <span className="text-muted-foreground">
                    {stageCounts[stage] ?? 0}/{STAGE_LABELS[stage].maxTeams} teams
                  </span>
                </div>
              ))}
            </div>

            {/* Teams listed with stage selectors */}
            <div className="space-y-1">
              <div className="grid grid-cols-[1fr_160px] gap-x-3 text-xs font-medium text-muted-foreground px-1 mb-2">
                <span>Team</span>
                <span>Starting Stage</span>
              </div>
              {participants.map(participant => (
                <div key={participant.id} className="grid grid-cols-[1fr_160px] gap-x-3 items-center py-1 border-b border-border/40 last:border-0">
                  <span className="text-sm">{participant.name}</span>
                  <select
                    name={`stage_${participant.id}`}
                    value={stageSelections[participant.id] ?? ''}
                    onChange={e => setStageSelections(prev => ({ ...prev, [participant.id]: e.target.value }))}
                    className="h-8 text-sm rounded-md border border-input bg-background px-2"
                  >
                    <option value="">— not assigned —</option>
                    <option value="1">Stage 1 (Opening)</option>
                    <option value="2">Stage 2 (Elimination)</option>
                    <option value="3">Stage 3 (Decider)</option>
                  </select>
                </div>
              ))}
            </div>

            <Button type="submit" disabled={isSubmitting}>
              <Save className="h-4 w-4 mr-2" />
              {isSubmitting ? 'Saving...' : 'Save Stage Assignments'}
            </Button>
          </Form>
        </CardContent>
      </Card>

      {/* Advancement Tracking (only shown when stage assignments exist) */}
      {stageResults.length > 0 && (
        <Card className="mb-6">
          <CardHeader>
            <CardTitle>Stage Advancement Tracking</CardTitle>
            <CardDescription>
              Record which teams were eliminated and their W-L record at elimination.
              Teams not listed as eliminated are assumed to have advanced (or are still playing).
              Stage 3 W-L records determine QP sub-placements (9–16).
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Form method="post" className="space-y-6">
              <input type="hidden" name="intent" value="mark-eliminations" />

              {[1, 2, 3].map(stage => {
                const teamsInStage = byStage[stage];
                if (teamsInStage.length === 0) return null;

                return (
                  <div key={stage}>
                    <h3 className="text-sm font-semibold mb-3 flex items-center gap-2">
                      <Badge variant={STAGE_LABELS[stage].badgeVariant}>{STAGE_LABELS[stage].label}</Badge>
                      {STAGE_LABELS[stage].description}
                    </h3>
                    <div className="space-y-1">
                      {teamsInStage.map(r => {
                        const isEliminated = r.stageEliminated !== null;
                        return (
                          <div key={r.participantId} className="grid grid-cols-[1fr_auto_200px] gap-x-3 items-center py-1 border-b border-border/40 last:border-0">
                            <span className="text-sm flex items-center gap-2">
                              {r.participantName}
                              {isEliminated && (
                                <Badge variant="outline" className="text-xs">
                                  eliminated {r.stageEliminatedWins}-3
                                </Badge>
                              )}
                            </span>
                            <label className="flex items-center gap-2 text-sm cursor-pointer">
                              <input
                                type="checkbox"
                                defaultChecked={isEliminated}
                                onChange={e => {
                                  // Show/hide the wins selector
                                  const winsEl = document.getElementById(`wins_${r.participantId}`);
                                  if (winsEl) winsEl.style.display = e.target.checked ? 'block' : 'none';
                                  // Also show/hide the hidden input
                                  const hiddenEl = document.getElementById(`elim_hidden_${r.participantId}`) as HTMLInputElement | null;
                                  if (hiddenEl) hiddenEl.disabled = !e.target.checked;
                                }}
                                className="rounded"
                              />
                              Eliminated
                            </label>
                            <div id={`wins_${r.participantId}`} style={{ display: isEliminated ? 'block' : 'none' }}>
                              <select
                                name={`elim_${r.participantId}`}
                                id={`elim_hidden_${r.participantId}`}
                                defaultValue={r.stageEliminatedWins?.toString() ?? '0'}
                                className="h-8 w-full text-sm rounded-md border border-input bg-background px-2"
                              >
                                {RECORD_OPTIONS.map(opt => (
                                  <option key={opt.value} value={opt.value}>{opt.label}</option>
                                ))}
                              </select>
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                );
              })}

              <Button type="submit" disabled={isSubmitting}>
                <CheckCircle2 className="h-4 w-4 mr-2" />
                {isSubmitting ? 'Saving...' : 'Save Eliminations'}
              </Button>
            </Form>
          </CardContent>
        </Card>
      )}

      {/* Champions Stage link */}
      {stageResults.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle>Champions Stage (Playoffs)</CardTitle>
            <CardDescription>
              The 8-team single-elimination bracket. Use the bracket admin to track
              Quarterfinals, Semifinals, and Grand Final results.
            </CardDescription>
          </CardHeader>
          <CardContent>
            <Link to={`/admin/sports-seasons/${sportsSeason.id}/events/${event.id}/bracket`}>
              <Button variant="outline">
                Open Bracket Admin →
              </Button>
            </Link>
          </CardContent>
        </Card>
      )}
    </div>
  );
}
