'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 {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog'
import { Loader2, Pencil } from 'lucide-react'
import { toast } from 'sonner'

type TeamMember = {
  userId: string
  role: string
  user: { id: string; name: string | null; email: string }
}

type AttendingMember = { userId: string; needsVisa: boolean }

export function EditAttendeesDialog({
  confirmationId,
  cap,
  teamMembers,
  attendingMembers,
  cutoffAt,
  disabled,
  disabledReason,
}: {
  confirmationId: string
  cap: number
  teamMembers: TeamMember[]
  attendingMembers: AttendingMember[]
  cutoffAt: Date | null
  disabled?: boolean
  disabledReason?: string
}) {
  const [open, setOpen] = useState(false)
  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [visa, setVisa] = useState<Record<string, boolean>>({})

  const utils = trpc.useUtils()
  const edit = trpc.finalist.editAttendees.useMutation({
    onSuccess: () => {
      toast.success('Attendees updated')
      utils.applicant.getMyFinalistConfirmation.invalidate()
      setOpen(false)
    },
    onError: (e) => toast.error(e.message),
  })

  // Reset form to current roster when dialog opens
  useEffect(() => {
    if (open) {
      setSelected(new Set(attendingMembers.map((m) => m.userId)))
      setVisa(
        Object.fromEntries(attendingMembers.map((m) => [m.userId, m.needsVisa])),
      )
    }
  }, [open, attendingMembers])

  const toggle = (userId: string, checked: boolean) => {
    setSelected((prev) => {
      const next = new Set(prev)
      if (checked) next.add(userId)
      else next.delete(userId)
      return next
    })
  }

  const overCap = selected.size > cap
  const noneSelected = selected.size === 0

  const handleSubmit = () => {
    const ids = Array.from(selected)
    edit.mutate({
      confirmationId,
      attendingUserIds: ids,
      visaFlags: Object.fromEntries(ids.map((id) => [id, !!visa[id]])),
    })
  }

  return (
    <Dialog
      open={open}
      onOpenChange={(next) => {
        if (!edit.isPending) setOpen(next)
      }}
    >
      <DialogTrigger asChild>
        <Button variant="outline" size="sm" disabled={disabled} title={disabledReason}>
          <Pencil className="mr-2 h-3.5 w-3.5" />
          Edit attendees
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-lg">
        <DialogHeader>
          <DialogTitle>Edit attendees</DialogTitle>
          <DialogDescription>
            Update who from your team will travel to the grand finale. You can select up to{' '}
            <strong>{cap}</strong> team members. Mark anyone who needs visa support so we can prepare
            documents in time.
            {cutoffAt && (
              <>
                {' '}
                Editable until{' '}
                <strong>
                  {new Intl.DateTimeFormat(undefined, {
                    dateStyle: 'medium',
                    timeStyle: 'short',
                  }).format(cutoffAt)}
                </strong>
                .
              </>
            )}
          </DialogDescription>
        </DialogHeader>

        <ul className="space-y-3 max-h-[50vh] overflow-y-auto pr-1">
          {teamMembers.map((tm) => {
            const checked = selected.has(tm.userId)
            return (
              <li key={tm.userId} className="flex items-start justify-between gap-4">
                <label className="flex flex-1 items-start gap-3 cursor-pointer">
                  <Checkbox
                    checked={checked}
                    onCheckedChange={(c) => toggle(tm.userId, c === true)}
                    className="mt-0.5"
                  />
                  <div>
                    <div className="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-sm">
                    <span className="text-muted-foreground">Needs 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>
        )}

        <DialogFooter>
          <Button variant="outline" onClick={() => setOpen(false)} disabled={edit.isPending}>
            Cancel
          </Button>
          <Button
            onClick={handleSubmit}
            disabled={overCap || noneSelected || edit.isPending}
          >
            {edit.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            Save attendees
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
