'use client'

import { Suspense, use, useEffect, useMemo, useState } from 'react'
import Link from 'next/link'
import { trpc } from '@/lib/trpc/client'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
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 {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from '@/components/ui/alert-dialog'
import { AlertCircle, CheckCircle2, Loader2, PartyPopper, XCircle } from 'lucide-react'
import { TRPCClientError } from '@trpc/client'

interface PageProps {
  params: Promise<{ token: string }>
}

function formatDeadline(d: Date): string {
  const main = new Intl.DateTimeFormat(undefined, {
    dateStyle: 'long',
    timeStyle: 'short',
  }).format(d)
  const tzPart = new Intl.DateTimeFormat(undefined, { timeZoneName: 'short' })
    .formatToParts(d)
    .find((p) => p.type === 'timeZoneName')?.value
  return tzPart ? `${main} (${tzPart})` : main
}

function CountdownLabel({ deadline }: { deadline: Date }) {
  const [now, setNow] = useState<number>(Date.now())
  useEffect(() => {
    const id = setInterval(() => setNow(Date.now()), 1000)
    return () => clearInterval(id)
  }, [])
  const ms = deadline.getTime() - now
  if (ms <= 0) return <span className="text-destructive font-medium">expired</span>
  const totalSec = Math.floor(ms / 1000)
  const hours = Math.floor(totalSec / 3600)
  const minutes = Math.floor((totalSec % 3600) / 60)
  const seconds = totalSec % 60
  if (hours >= 24) {
    const days = Math.floor(hours / 24)
    const remHours = hours % 24
    return (
      <span className="font-medium tabular-nums">
        {days}d {remHours}h remaining
      </span>
    )
  }
  return (
    <span className="font-medium tabular-nums">
      {hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:
      {seconds.toString().padStart(2, '0')} remaining
    </span>
  )
}

function FriendlyError({
  title,
  message,
  icon: Icon,
}: {
  title: string
  message: string
  icon: typeof AlertCircle
}) {
  return (
    <Card className="mx-auto max-w-xl">
      <CardHeader>
        <div className="flex items-center gap-2">
          <Icon className="text-muted-foreground h-5 w-5" />
          <CardTitle>{title}</CardTitle>
        </div>
      </CardHeader>
      <CardContent>
        <p className="text-muted-foreground">{message}</p>
      </CardContent>
    </Card>
  )
}

function FinalistConfirmContent({ token }: { token: string }) {
  const { data, isLoading, error } = trpc.finalist.getByToken.useQuery({ token }, { retry: false })
  const confirmMutation = trpc.finalist.confirm.useMutation()
  const declineMutation = trpc.finalist.decline.useMutation()

  const [selected, setSelected] = useState<Set<string>>(new Set())
  const [visa, setVisa] = useState<Record<string, boolean>>({})
  const [declineReason, setDeclineReason] = useState('')
  const [submitState, setSubmitState] = useState<'idle' | 'confirmed' | 'declined' | 'error'>(
    'idle',
  )
  const [submitError, setSubmitError] = useState<string | null>(null)

  // Default-select all team members once data arrives
  useEffect(() => {
    if (data?.project.teamMembers && selected.size === 0 && submitState === 'idle') {
      const cap = data.project.program.defaultAttendeeCap
      const initial = new Set(
        data.project.teamMembers.slice(0, cap).map((tm) => tm.userId),
      )
      setSelected(initial)
    }
  }, [data, selected.size, submitState])

  // ── Loading
  if (isLoading) {
    return (
      <div className="mx-auto max-w-xl space-y-4">
        <Skeleton className="h-8 w-2/3" />
        <Skeleton className="h-32 w-full" />
        <Skeleton className="h-48 w-full" />
      </div>
    )
  }

  // ── Token errors → friendly states
  if (error) {
    const msg = error.message ?? ''
    if (/expired/i.test(msg)) {
      return (
        <FriendlyError
          icon={AlertCircle}
          title="This link has expired"
          message="If your team still wants to attend, please contact us at info@monaco-opc.com."
        />
      )
    }
    if (/signature|malformed|payload/i.test(msg)) {
      return (
        <FriendlyError
          icon={AlertCircle}
          title="This link is not valid"
          message="Please check your email or contact us at info@monaco-opc.com."
        />
      )
    }
    return (
      <FriendlyError
        icon={AlertCircle}
        title="Something went wrong"
        message={msg || 'Please try again or contact us at info@monaco-opc.com.'}
      />
    )
  }
  if (!data) {
    return (
      <FriendlyError
        icon={AlertCircle}
        title="Confirmation not found"
        message="Please check your email link or contact us at info@monaco-opc.com."
      />
    )
  }

  // ── Status branches: only PENDING is interactive
  if (submitState === 'confirmed' || data.status === 'CONFIRMED') {
    return (
      <Card className="mx-auto max-w-xl">
        <CardHeader>
          <div className="flex items-center gap-2">
            <PartyPopper className="text-primary h-5 w-5" />
            <CardTitle>You&apos;re in!</CardTitle>
          </div>
        </CardHeader>
        <CardContent>
          <p className="mb-2">
            Your team&apos;s attendance for <strong>{data.project.title}</strong> is confirmed.
          </p>
          <p className="text-muted-foreground text-sm">
            We&apos;ll be in touch shortly with travel and lunch logistics. You can edit your team
            selection and view hotel, flight, and visa details from your dashboard.
          </p>
          <Button asChild className="mt-4">
            <Link href="/applicant">Go to my dashboard</Link>
          </Button>
        </CardContent>
      </Card>
    )
  }
  if (submitState === 'declined' || data.status === 'DECLINED') {
    return (
      <FriendlyError
        icon={XCircle}
        title="Your team has declined"
        message="If this was a mistake, please contact us at info@monaco-opc.com."
      />
    )
  }
  if (data.status === 'EXPIRED') {
    return (
      <FriendlyError
        icon={AlertCircle}
        title="The confirmation deadline has passed"
        message="If your team still wants to attend, please contact us at info@monaco-opc.com."
      />
    )
  }
  if (data.status === 'SUPERSEDED') {
    return (
      <FriendlyError
        icon={AlertCircle}
        title="This confirmation is no longer active"
        message="Please contact us at info@monaco-opc.com for details."
      />
    )
  }

  // ── PENDING: render the form
  const cap = data.project.program.defaultAttendeeCap
  const deadline = new Date(data.deadline)
  const overCap = selected.size > cap
  const noneSelected = selected.size === 0

  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 toggleVisa = (userId: string, checked: boolean) => {
    setVisa((prev) => ({ ...prev, [userId]: checked }))
  }

  const handleConfirm = async () => {
    setSubmitError(null)
    try {
      await confirmMutation.mutateAsync({
        token,
        attendingUserIds: Array.from(selected),
        visaFlags: Object.fromEntries(
          Array.from(selected).map((uid) => [uid, !!visa[uid]]),
        ),
      })
      setSubmitState('confirmed')
    } catch (err) {
      setSubmitState('error')
      const msg =
        err instanceof TRPCClientError ? err.message : err instanceof Error ? err.message : 'Failed'
      setSubmitError(msg)
    }
  }
  const handleDecline = async () => {
    setSubmitError(null)
    try {
      await declineMutation.mutateAsync({
        token,
        reason: declineReason.trim() || undefined,
      })
      setSubmitState('declined')
    } catch (err) {
      setSubmitState('error')
      const msg =
        err instanceof TRPCClientError ? err.message : err instanceof Error ? err.message : 'Failed'
      setSubmitError(msg)
    }
  }

  return (
    <div className="mx-auto max-w-xl space-y-6">
      <Card className="border-primary/40 bg-primary/5">
        <CardHeader>
          <div className="flex items-center gap-2">
            <PartyPopper className="text-primary h-5 w-5" />
            <CardTitle>Congratulations!</CardTitle>
          </div>
        </CardHeader>
        <CardContent className="space-y-2">
          <p>
            Your project <strong>{data.project.title}</strong> is a finalist for the Monaco Ocean
            Protection Challenge grand finale.
          </p>
          <div className="bg-background border-amber-300 mt-3 rounded-md border-l-4 p-3">
            <p className="text-sm">
              <strong>Confirm by {formatDeadline(deadline)}.</strong>
            </p>
            <p className="text-muted-foreground mt-1 text-xs">
              <CountdownLabel deadline={deadline} />
            </p>
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle className="text-base">Who from your team will attend?</CardTitle>
          <p className="text-muted-foreground text-sm">
            You can select up to <strong>{cap}</strong> team members. Indicate who needs visa
            support so we can prepare documents in time.
          </p>
        </CardHeader>
        <CardContent>
          <ul className="space-y-3">
            {data.project.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) => toggleVisa(tm.userId, c)}
                      />
                    </label>
                  )}
                </li>
              )
            })}
          </ul>
          {overCap && (
            <p className="text-destructive mt-3 text-sm">
              Please select no more than {cap} member{cap === 1 ? '' : 's'}.
            </p>
          )}
        </CardContent>
      </Card>

      {submitError && (
        <div className="border-destructive bg-destructive/10 text-destructive rounded-md border p-3 text-sm">
          {submitError}
        </div>
      )}

      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <AlertDialog>
          <AlertDialogTrigger asChild>
            <Button variant="ghost" className="text-muted-foreground">
              We can&apos;t attend
            </Button>
          </AlertDialogTrigger>
          <AlertDialogContent>
            <AlertDialogHeader>
              <AlertDialogTitle>Decline finalist slot?</AlertDialogTitle>
              <AlertDialogDescription>
                If your team can&apos;t attend, we&apos;ll offer the slot to a waitlisted team. This
                action can&apos;t be undone from this page.
              </AlertDialogDescription>
            </AlertDialogHeader>
            <div className="space-y-2">
              <label className="text-muted-foreground text-sm" htmlFor="decline-reason">
                Reason (optional, helps us improve future editions)
              </label>
              <Textarea
                id="decline-reason"
                value={declineReason}
                onChange={(e) => setDeclineReason(e.target.value)}
                placeholder="e.g. logistics conflict, team disbanded, no longer interested"
                rows={3}
              />
            </div>
            <AlertDialogFooter>
              <AlertDialogCancel>Cancel</AlertDialogCancel>
              <AlertDialogAction
                onClick={handleDecline}
                disabled={declineMutation.isPending}
                className="bg-destructive hover:bg-destructive/90"
              >
                {declineMutation.isPending ? (
                  <Loader2 className="h-4 w-4 animate-spin" />
                ) : (
                  'Decline finalist slot'
                )}
              </AlertDialogAction>
            </AlertDialogFooter>
          </AlertDialogContent>
        </AlertDialog>

        <Button
          size="lg"
          onClick={handleConfirm}
          disabled={overCap || noneSelected || confirmMutation.isPending}
        >
          {confirmMutation.isPending ? (
            <>
              <Loader2 className="mr-2 h-4 w-4 animate-spin" /> Confirming…
            </>
          ) : (
            <>
              <CheckCircle2 className="mr-2 h-4 w-4" />
              Confirm Attendance
            </>
          )}
        </Button>
      </div>
    </div>
  )
}

export default function FinalistConfirmPage({ params }: PageProps) {
  const { token } = use(params)
  return (
    <Suspense fallback={<Skeleton className="h-64 w-full" />}>
      <FinalistConfirmContent token={token} />
    </Suspense>
  )
}
