'use client'

import { useEffect, useState } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Button } from '@/components/ui/button'
import { Checkbox } from '@/components/ui/checkbox'
import { Switch } from '@/components/ui/switch'
import { Skeleton } from '@/components/ui/skeleton'
import { Textarea } from '@/components/ui/textarea'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Loader2 } from 'lucide-react'
import { toast } from 'sonner'

export type AttendanceMode = 'confirm' | 'decline'

export function AdminAttendanceDialog({
  open,
  mode,
  confirmationId,
  programId,
  onOpenChange,
}: {
  open: boolean
  mode: AttendanceMode
  confirmationId: string | null
  programId: string
  onOpenChange: (next: boolean) => void
}) {
  const utils = trpc.useUtils()
  const enabled = open && !!confirmationId
  const { data: detail, isLoading } = trpc.finalist.getConfirmationDetail.useQuery(
    { confirmationId: confirmationId ?? '' },
    { enabled },
  )

  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [visa, setVisa] = useState<Record<string, boolean>>({})
  const [reason, setReason] = useState('')

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

  const confirmMutation = trpc.finalist.adminConfirm.useMutation({
    onSuccess: () => {
      toast.success('Attendance confirmed')
      invalidate()
      onOpenChange(false)
    },
    onError: (e) => toast.error(e.message),
  })
  const declineMutation = trpc.finalist.adminDecline.useMutation({
    onSuccess: () => {
      toast.success('Marked as declined')
      invalidate()
      onOpenChange(false)
    },
    onError: (e) => toast.error(e.message),
  })

  // Reset form when the dialog opens for a new row
  useEffect(() => {
    if (!open) return
    setReason('')
    if (detail) {
      // Default-pre-select the team lead + up to cap members
      const cap = detail.project.program.defaultAttendeeCap
      const initial = new Set(
        detail.project.teamMembers.slice(0, cap).map((tm) => tm.userId),
      )
      setSelected(initial)
      setVisa({})
    }
  }, [open, detail])

  const isPending = confirmMutation.isPending || declineMutation.isPending

  const handleConfirm = () => {
    if (!confirmationId) return
    const ids = Array.from(selected)
    confirmMutation.mutate({
      confirmationId,
      attendingUserIds: ids,
      visaFlags: Object.fromEntries(ids.map((id) => [id, !!visa[id]])),
    })
  }
  const handleDecline = () => {
    if (!confirmationId) return
    declineMutation.mutate({
      confirmationId,
      reason: reason.trim() || undefined,
    })
  }

  const cap = detail?.project.program.defaultAttendeeCap ?? 3
  const overCap = selected.size > cap
  const noneSelected = selected.size === 0

  return (
    <Dialog
      open={open}
      onOpenChange={(next) => {
        if (!isPending) onOpenChange(next)
      }}
    >
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>
            {mode === 'confirm' ? 'Confirm attendance on team behalf' : 'Decline on team behalf'}
          </DialogTitle>
          <DialogDescription>
            {mode === 'confirm'
              ? 'Use this when the team replied by email. The selected attendees will be locked in just like a public confirmation.'
              : 'Use this when the team has told us they cannot attend. The slot will cascade to the next waitlist entry.'}
          </DialogDescription>
        </DialogHeader>

        {isLoading || !detail ? (
          <div className="space-y-2">
            <Skeleton className="h-6 w-3/4" />
            <Skeleton className="h-20 w-full" />
          </div>
        ) : mode === 'confirm' ? (
          <>
            <div className="text-sm">
              <span className="text-muted-foreground">Project:</span>{' '}
              <strong>{detail.project.title}</strong>
            </div>
            <ul className="space-y-2 max-h-[50vh] overflow-y-auto pr-1">
              {detail.project.teamMembers.map((tm) => {
                const checked = selected.has(tm.userId)
                return (
                  <li
                    key={tm.userId}
                    className="flex items-start justify-between gap-4 rounded-md border px-3 py-2"
                  >
                    <label className="flex flex-1 items-start gap-3 cursor-pointer">
                      <Checkbox
                        checked={checked}
                        onCheckedChange={(c) => {
                          setSelected((prev) => {
                            const next = new Set(prev)
                            if (c === true) next.add(tm.userId)
                            else next.delete(tm.userId)
                            return next
                          })
                        }}
                        className="mt-0.5"
                      />
                      <div>
                        <div className="text-sm font-medium">
                          {tm.user.name ?? tm.user.email}
                        </div>
                        <div className="text-muted-foreground text-xs">
                          {tm.user.email}
                          {tm.role && tm.role !== 'MEMBER' ? ` · ${tm.role.toLowerCase()}` : ''}
                        </div>
                      </div>
                    </label>
                    {checked && (
                      <label className="flex items-center gap-2 text-xs">
                        <span className="text-muted-foreground">Visa?</span>
                        <Switch
                          checked={!!visa[tm.userId]}
                          onCheckedChange={(c) =>
                            setVisa((prev) => ({ ...prev, [tm.userId]: c }))
                          }
                        />
                      </label>
                    )}
                  </li>
                )
              })}
            </ul>
            {overCap && (
              <p className="text-destructive text-sm">
                Please select no more than {cap} member{cap === 1 ? '' : 's'}.
              </p>
            )}
          </>
        ) : (
          <>
            <div className="text-sm">
              <span className="text-muted-foreground">Project:</span>{' '}
              <strong>{detail.project.title}</strong>
            </div>
            <div className="space-y-2">
              <label className="text-muted-foreground text-sm" htmlFor="admin-decline-reason">
                Reason (optional)
              </label>
              <Textarea
                id="admin-decline-reason"
                value={reason}
                onChange={(e) => setReason(e.target.value)}
                placeholder="e.g. logistics conflict, team disbanded, no longer interested"
                rows={3}
              />
            </div>
          </>
        )}

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)} disabled={isPending}>
            Cancel
          </Button>
          {mode === 'confirm' ? (
            <Button
              onClick={handleConfirm}
              disabled={!detail || overCap || noneSelected || isPending}
            >
              {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              Confirm attendance
            </Button>
          ) : (
            <Button
              onClick={handleDecline}
              disabled={!detail || isPending}
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
            >
              {isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              Mark as declined
            </Button>
          )}
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
