'use client'

import { useState } from 'react'
import { trpc } from '@/lib/trpc/client'
import { toast } from 'sonner'
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Checkbox } from '@/components/ui/checkbox'
import { Skeleton } from '@/components/ui/skeleton'
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { Loader2, UserCheck } from 'lucide-react'
import { formatEnumLabel } from '@/lib/utils'
import {
  EnrollAttendeesDialog,
  type AttendeeSelection,
} from './enroll-attendees-dialog'

interface Props {
  programId: string
  roundId: string
}

type EnrollMode = 'EMAIL' | 'ADMIN_CONFIRM'

type RowState = {
  mode: EnrollMode
  attendees?: AttendeeSelection
}

type Candidate = {
  projectId: string
  title: string
  teamName: string | null
  country: string | null
  inLiveFinal: boolean
  confirmationStatus: string | null
  teamMembers: Array<{ userId: string; name: string | null; role: string; email: string }>
}

const STATUS_CONFIG: Record<
  string,
  { label: string; variant: 'default' | 'secondary' | 'outline' | 'destructive' }
> = {
  PENDING: { label: 'Pending', variant: 'secondary' },
  CONFIRMED: { label: 'Confirmed', variant: 'default' },
  DECLINED: { label: 'Declined', variant: 'destructive' },
  EXPIRED: { label: 'Expired', variant: 'outline' },
}

function deriveStatus(candidate: Candidate): string {
  if (candidate.confirmationStatus) return candidate.confirmationStatus
  if (candidate.inLiveFinal) return 'IN_ROUND'
  return 'NOT_ENROLLED'
}

function StatusBadge({ candidate }: { candidate: Candidate }) {
  const status = deriveStatus(candidate)
  if (status === 'NOT_ENROLLED') {
    return (
      <Badge variant="outline" className="text-xs">
        Not enrolled
      </Badge>
    )
  }
  if (status === 'IN_ROUND') {
    return (
      <Badge variant="secondary" className="text-xs">
        In round
      </Badge>
    )
  }
  const cfg = STATUS_CONFIG[status] ?? { label: status, variant: 'outline' as const }
  return (
    <Badge variant={cfg.variant} className="text-xs">
      {cfg.label}
    </Badge>
  )
}

export function FinalistEnrollmentCard({ programId, roundId }: Props) {
  const utils = trpc.useUtils()

  const { data, isLoading } = trpc.finalist.listEnrollmentCandidates.useQuery({ programId })

  // Per-row selection + mode state
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [rowState, setRowState] = useState<Record<string, RowState>>({})

  // Dialog state for "Set attendees now" picker
  const [attendeesDialog, setAttendeesDialog] = useState<{
    open: boolean
    projectId: string
    members: Candidate['teamMembers']
  } | null>(null)

  // Un-enroll state
  const [unenrolling, setUnenrolling] = useState<string | null>(null)

  const invalidateQueries = () => {
    utils.finalist.listEnrollmentCandidates.invalidate({ programId })
    utils.logistics.listConfirmations.invalidate({ programId })
  }

  const enrollMutation = trpc.finalist.enrollFinalists.useMutation({
    onSuccess: (result) => {
      const parts: string[] = []
      if (result.enrolled > 0) parts.push(`${result.enrolled} enrolled`)
      if (result.emailed > 0) parts.push(`${result.emailed} emailed`)
      if (result.adminConfirmed > 0) parts.push(`${result.adminConfirmed} admin-confirmed`)
      if (result.skipped.length > 0) parts.push(`${result.skipped.length} skipped`)
      toast.success(parts.join(' · ') || 'Done')
      setSelected(new Set())
      setRowState({})
      invalidateQueries()
    },
    onError: (err) => toast.error(err.message),
  })

  const unenrollMutation = trpc.finalist.unenroll.useMutation({
    onSuccess: () => {
      toast.success('Team removed from the Grand Final round')
      setUnenrolling(null)
      invalidateQueries()
    },
    onError: (err) => {
      toast.error(err.message)
      setUnenrolling(null)
    },
  })

  // ---------------------------------------------------------------------------
  // Helpers
  // ---------------------------------------------------------------------------

  const toggleRow = (projectId: string) => {
    setSelected((prev) => {
      const next = new Set(prev)
      if (next.has(projectId)) {
        next.delete(projectId)
      } else {
        next.add(projectId)
      }
      return next
    })
    setRowState((prev) => {
      if (prev[projectId]) return prev
      return { ...prev, [projectId]: { mode: 'EMAIL' } }
    })
  }

  const setMode = (projectId: string, mode: EnrollMode, candidate: Candidate) => {
    if (mode === 'ADMIN_CONFIRM') {
      setAttendeesDialog({
        open: true,
        projectId,
        members: candidate.teamMembers,
      })
    } else {
      setRowState((prev) => ({
        ...prev,
        [projectId]: { mode: 'EMAIL' },
      }))
    }
  }

  const handleAttendeesConfirm = (
    projectId: string,
    attendingUserIds: string[],
    visaFlags: Record<string, boolean>,
  ) => {
    setRowState((prev) => ({
      ...prev,
      [projectId]: {
        mode: 'ADMIN_CONFIRM',
        attendees: { attendingUserIds, visaFlags },
      },
    }))
    setAttendeesDialog(null)
  }

  const buildEnrollments = (projectIds: string[]) => {
    return projectIds.map((projectId) => {
      const rs = rowState[projectId] ?? { mode: 'EMAIL' as EnrollMode }
      if (rs.mode === 'ADMIN_CONFIRM' && rs.attendees) {
        return {
          projectId,
          mode: 'ADMIN_CONFIRM' as const,
          attendingUserIds: rs.attendees.attendingUserIds,
          visaFlags: rs.attendees.visaFlags,
        }
      }
      return { projectId, mode: 'EMAIL' as const }
    })
  }

  const handleEnrollSelected = () => {
    if (!data?.liveFinalRoundId) {
      toast.error('No LIVE_FINAL round found for this program')
      return
    }
    const ids = Array.from(selected)
    if (ids.length === 0) return
    enrollMutation.mutate({
      programId,
      roundId: data.liveFinalRoundId,
      enrollments: buildEnrollments(ids),
    })
  }

  const handleEnrollAllEligible = () => {
    if (!data?.liveFinalRoundId) {
      toast.error('No LIVE_FINAL round found for this program')
      return
    }
    const allCandidates = data.categories.flatMap((c) => c.candidates)
    const eligible = allCandidates.filter((c) => c.confirmationStatus !== 'CONFIRMED')
    if (eligible.length === 0) {
      toast.info('No eligible teams to enroll')
      return
    }
    enrollMutation.mutate({
      programId,
      roundId: data.liveFinalRoundId,
      enrollments: eligible.map((c) => ({
        projectId: c.projectId,
        mode: 'EMAIL' as const,
      })),
    })
  }

  // ---------------------------------------------------------------------------
  // Render
  // ---------------------------------------------------------------------------

  if (isLoading) {
    return <Skeleton className="h-56 w-full rounded-md" />
  }

  const noMentoringTeams = !data || data.categories.length === 0

  return (
    <>
      <Card>
        <CardHeader>
          <div className="flex items-center gap-2">
            <UserCheck className="text-muted-foreground h-4 w-4" />
            <CardTitle className="text-base">Enroll finalists</CardTitle>
          </div>
          <CardDescription>
            Select mentoring-round teams to advance into the Grand Final. Each enrolled team
            immediately appears on the Finals jury&#39;s project list and receives an attendance
            confirmation request (or can be admin-confirmed on the spot).
          </CardDescription>
        </CardHeader>

        <CardContent>
          {noMentoringTeams ? (
            <p className="text-muted-foreground py-6 text-center text-sm">
              No mentoring-round teams to enroll yet.
            </p>
          ) : (
            <div className="space-y-6">
              {data.categories.map((cat) => (
                <div key={cat.category}>
                  {/* Category header */}
                  <div className="text-muted-foreground mb-2 flex items-center gap-2 text-xs font-medium uppercase tracking-wide">
                    <span>{formatEnumLabel(cat.category)}</span>
                    <span className="font-normal">
                      — {cat.confirmedCount}/{cat.quota ?? '?'} confirmed
                      {cat.pendingCount > 0 ? `, ${cat.pendingCount} pending` : ''}
                    </span>
                  </div>

                  <div className="space-y-2">
                    {cat.candidates.map((candidate) => {
                      const status = deriveStatus(candidate)
                      const isEnrolled =
                        status === 'CONFIRMED' || status === 'DECLINED' || status === 'EXPIRED'
                      const isChecked = selected.has(candidate.projectId)
                      const rs = rowState[candidate.projectId]
                      const isUnenrolling =
                        unenrollMutation.isPending && unenrolling === candidate.projectId

                      return (
                        <div
                          key={candidate.projectId}
                          className="flex flex-wrap items-start gap-3 rounded-md border p-3"
                        >
                          {/* Left: checkbox (or spacer for enrolled rows) */}
                          <div className="mt-0.5 flex-shrink-0">
                            {isEnrolled ? (
                              <div className="h-4 w-4" />
                            ) : (
                              <Checkbox
                                checked={isChecked}
                                onCheckedChange={() => toggleRow(candidate.projectId)}
                              />
                            )}
                          </div>

                          {/* Middle: project info */}
                          <div className="min-w-0 flex-1">
                            <div className="flex flex-wrap items-center gap-2">
                              <span className="text-sm font-medium">{candidate.title}</span>
                              <StatusBadge candidate={candidate} />
                            </div>
                            <div className="text-muted-foreground mt-0.5 text-xs">
                              {[candidate.teamName, candidate.country]
                                .filter(Boolean)
                                .join(' · ') || '—'}
                            </div>

                            {/* Mode toggle for selected rows */}
                            {isChecked && !isEnrolled && (
                              <div className="mt-2 flex items-center gap-2">
                                <Button
                                  size="sm"
                                  variant={rs?.mode === 'EMAIL' ? 'default' : 'outline'}
                                  className="h-7 px-2 text-xs"
                                  onClick={() => setMode(candidate.projectId, 'EMAIL', candidate)}
                                >
                                  Email team
                                </Button>
                                <Button
                                  size="sm"
                                  variant={rs?.mode === 'ADMIN_CONFIRM' ? 'default' : 'outline'}
                                  className="h-7 px-2 text-xs"
                                  onClick={() =>
                                    setMode(candidate.projectId, 'ADMIN_CONFIRM', candidate)
                                  }
                                >
                                  Set attendees now
                                  {rs?.mode === 'ADMIN_CONFIRM' && rs.attendees && (
                                    <span className="ml-1 opacity-70">
                                      ({rs.attendees.attendingUserIds.length})
                                    </span>
                                  )}
                                </Button>
                              </div>
                            )}
                          </div>

                          {/* Right: un-enroll button for CONFIRMED/DECLINED rows */}
                          {(status === 'CONFIRMED' || status === 'DECLINED') && (
                            <AlertDialog>
                              <AlertDialogTrigger asChild>
                                <Button
                                  size="sm"
                                  variant="outline"
                                  disabled={isUnenrolling}
                                  onClick={() => setUnenrolling(candidate.projectId)}
                                >
                                  {isUnenrolling ? (
                                    <Loader2 className="h-4 w-4 animate-spin" />
                                  ) : (
                                    'Un-enroll'
                                  )}
                                </Button>
                              </AlertDialogTrigger>
                              <AlertDialogContent>
                                <AlertDialogHeader>
                                  <AlertDialogTitle>Remove from Grand Final?</AlertDialogTitle>
                                  <AlertDialogDescription>
                                    This removes <strong>{candidate.title}</strong> from the Grand
                                    Final round and deletes their attendance record. Continue?
                                  </AlertDialogDescription>
                                </AlertDialogHeader>
                                <AlertDialogFooter>
                                  <AlertDialogCancel onClick={() => setUnenrolling(null)}>
                                    Cancel
                                  </AlertDialogCancel>
                                  <AlertDialogAction
                                    onClick={() => {
                                      unenrollMutation.mutate({
                                        projectId: candidate.projectId,
                                        roundId,
                                      })
                                    }}
                                  >
                                    Remove
                                  </AlertDialogAction>
                                </AlertDialogFooter>
                              </AlertDialogContent>
                            </AlertDialog>
                          )}
                        </div>
                      )
                    })}
                  </div>
                </div>
              ))}

              {/* Footer actions */}
              <div className="flex flex-wrap items-center gap-2 border-t pt-4">
                <Button
                  size="sm"
                  disabled={selected.size === 0 || enrollMutation.isPending}
                  onClick={handleEnrollSelected}
                >
                  {enrollMutation.isPending && (
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  )}
                  Enroll selected ({selected.size})
                </Button>
                <Button
                  size="sm"
                  variant="outline"
                  disabled={enrollMutation.isPending}
                  onClick={handleEnrollAllEligible}
                >
                  Enroll all eligible
                </Button>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Attendees picker dialog */}
      {attendeesDialog && (
        <EnrollAttendeesDialog
          open={attendeesDialog.open}
          onOpenChange={(open) => {
            if (!open) {
              // If user closes without confirming, revert mode to EMAIL
              setRowState((prev) => ({
                ...prev,
                [attendeesDialog.projectId]: {
                  mode: 'EMAIL',
                },
              }))
              setAttendeesDialog(null)
            }
          }}
          members={attendeesDialog.members}
          cap={data?.attendeeCap ?? 3}
          initial={rowState[attendeesDialog.projectId]?.attendees}
          onConfirm={(ids, flags) =>
            handleAttendeesConfirm(attendeesDialog.projectId, ids, flags)
          }
        />
      )}
    </>
  )
}
