'use client'

import { trpc } from '@/lib/trpc/client'
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Skeleton } from '@/components/ui/skeleton'
import { PlaneTakeoff, ShieldCheck, AlertTriangle } from 'lucide-react'
import { EditAttendeesDialog } from './edit-attendees-dialog'
import { LunchPickForm } from './lunch-pick-form'
import type { VisaStatus } from '@prisma/client'
import { useSession } from 'next-auth/react'

const VISA_BADGE: Record<
  VisaStatus,
  { label: string; variant: 'default' | 'secondary' | 'destructive' | 'outline' }
> = {
  NOT_NEEDED: { label: 'Visa not needed', variant: 'outline' },
  REQUESTED: { label: 'Visa requested', variant: 'secondary' },
  INVITATION_SENT: { label: 'Invitation sent', variant: 'secondary' },
  APPOINTMENT_BOOKED: { label: 'Appointment booked', variant: 'default' },
  GRANTED: { label: 'Visa granted', variant: 'default' },
  DENIED: { label: 'Visa denied', variant: 'destructive' },
}

function formatDateOnly(d: Date | string): string {
  return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium' }).format(new Date(d))
}

function nextVisaDate(v: {
  invitationSentAt: Date | string | null
  appointmentAt: Date | string | null
  decisionAt: Date | string | null
  status: VisaStatus
}): { label: string; date: Date | string } | null {
  if (v.status === 'GRANTED' || v.status === 'DENIED') {
    if (v.decisionAt) return { label: 'Decision', date: v.decisionAt }
    return null
  }
  if (v.appointmentAt) return { label: 'Appointment', date: v.appointmentAt }
  if (v.invitationSentAt) return { label: 'Invitation sent', date: v.invitationSentAt }
  return null
}

export function AttendingMembersCard() {
  const { data: session } = useSession()
  const { data, isLoading } = trpc.applicant.getMyFinalistConfirmation.useQuery()
  const { data: myVisas } = trpc.applicant.getMyVisaApplications.useQuery()
  const programId = data?.project.programId
  const { data: lunchEvent } = trpc.lunch.getEventForMember.useQuery(
    { programId: programId ?? '' },
    { enabled: !!programId },
  )

  if (isLoading) {
    return (
      <Card>
        <CardHeader>
          <Skeleton className="h-5 w-48" />
        </CardHeader>
        <CardContent>
          <Skeleton className="h-24 w-full" />
        </CardContent>
      </Card>
    )
  }

  if (!data || data.confirmation.status !== 'CONFIRMED') return null

  const cutoffAt = data.cutoffAt ? new Date(data.cutoffAt) : null
  const userById = new Map(data.project.teamMembers.map((tm) => [tm.userId, tm.user]))
  const attendees = data.confirmation.attendingMembers
  const visaByUser = new Map(
    (myVisas ?? []).map((v) => [v.userId, v] as const),
  )

  const editDisabled = !data.editableNow
  const editDisabledReason = !data.editableNow
    ? 'Attendee changes are closed for this edition.'
    : undefined

  return (
    <Card>
      <CardHeader className="flex-row items-start justify-between gap-4 space-y-0">
        <div>
          <CardTitle className="flex items-center gap-2.5 text-lg">
            <div className="rounded-lg bg-sky-500/10 p-1.5">
              <PlaneTakeoff className="h-4 w-4 text-sky-500" />
            </div>
            Grand Finale Attendees
          </CardTitle>
          <CardDescription className="mt-1">
            Team members confirmed to travel to Monaco
            {cutoffAt && data.editableNow && (
              <>
                {' '}
                · editable until{' '}
                <strong>
                  {new Intl.DateTimeFormat(undefined, {
                    dateStyle: 'medium',
                    timeStyle: 'short',
                  }).format(cutoffAt)}
                </strong>
              </>
            )}
            {cutoffAt && !data.editableNow && (
              <span className="text-muted-foreground inline-flex items-center gap-1">
                {' '}
                · <AlertTriangle className="h-3 w-3" /> editing closed
              </span>
            )}
          </CardDescription>
        </div>
        {data.isLead && (
          <EditAttendeesDialog
            confirmationId={data.confirmation.id}
            cap={data.project.program.defaultAttendeeCap}
            teamMembers={data.project.teamMembers}
            attendingMembers={attendees}
            cutoffAt={cutoffAt}
            disabled={editDisabled}
            disabledReason={editDisabledReason}
          />
        )}
      </CardHeader>
      <CardContent>
        {attendees.length === 0 ? (
          <p className="text-muted-foreground text-sm">No attendees selected yet.</p>
        ) : (
          <ul className="space-y-2">
            {attendees.map((a) => {
              const user = userById.get(a.userId)
              if (!user) return null
              const visa = visaByUser.get(a.userId)
              const visaBadge = visa ? VISA_BADGE[visa.status] : null
              const next = visa ? nextVisaDate(visa) : null
              const sessionUserId = session?.user?.id
              const sessionRole = session?.user?.role
              const isAdmin =
                sessionRole === 'SUPER_ADMIN' || sessionRole === 'PROGRAM_ADMIN'
              const isSelf = sessionUserId === a.userId
              const isLeadActing = data.isLead && !isSelf
              const lunchDeadline = lunchEvent?.changeDeadline
                ? new Date(lunchEvent.changeDeadline)
                : null
              const lunchPastDeadline =
                !!lunchDeadline && new Date() > lunchDeadline
              const canEditLunch =
                !!lunchEvent &&
                ((isSelf && !lunchPastDeadline) ||
                  (data.isLead && !lunchPastDeadline) ||
                  isAdmin)
              return (
                <li
                  key={a.userId}
                  className="space-y-3 rounded-md border px-3 py-2"
                >
                  <div className="flex items-center justify-between gap-3">
                    <div>
                      <div className="text-sm font-medium">{user.name ?? user.email}</div>
                      <div className="text-muted-foreground text-xs">{user.email}</div>
                    </div>
                    <div className="flex flex-col items-end gap-1">
                      {visa && visaBadge ? (
                        <>
                          <Badge variant={visaBadge.variant} className="gap-1">
                            <ShieldCheck className="h-3 w-3" />
                            {visaBadge.label}
                          </Badge>
                          {next && (
                            <span className="text-muted-foreground text-xs">
                              {next.label}: {formatDateOnly(next.date)}
                            </span>
                          )}
                        </>
                      ) : (
                        a.needsVisa && (
                          <Badge variant="outline" className="gap-1">
                            <ShieldCheck className="h-3 w-3" />
                            Visa support
                          </Badge>
                        )
                      )}
                    </div>
                  </div>
                  {lunchEvent && programId && (
                    <LunchPickForm
                      attendingMemberId={a.id}
                      programId={programId}
                      lunchEventId={lunchEvent.id}
                      canEdit={canEditLunch}
                      editingOnBehalfOf={
                        isLeadActing ? (user.name ?? user.email) : null
                      }
                    />
                  )}
                </li>
              )
            })}
          </ul>
        )}
      </CardContent>
    </Card>
  )
}
