'use client'

import { useEffect, useMemo, useState } from 'react'
import { trpc } from '@/lib/trpc/client'
import { toast } from 'sonner'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Skeleton } from '@/components/ui/skeleton'
import {
  Sheet,
  SheetContent,
  SheetDescription,
  SheetFooter,
  SheetHeader,
  SheetTitle,
} from '@/components/ui/sheet'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Download, Loader2, Plane } from 'lucide-react'
import type { FlightDetailStatus } from '@prisma/client'

interface Props {
  programId: string
}

type AttendeeRow = {
  id: string
  needsVisa: boolean
  user: { id: string; name: string | null; email: string; country: string | null }
  confirmation: {
    project: {
      id: string
      title: string
      country: string | null
      competitionCategory: string | null
    }
  }
  flightDetail: {
    id: string
    arrivalAt: Date | null
    arrivalFlightNumber: string | null
    arrivalAirport: string | null
    departureAt: Date | null
    departureFlightNumber: string | null
    departureAirport: string | null
    status: FlightDetailStatus
    adminNotes: string | null
  } | null
}

type StatusFilter = 'all' | 'PENDING' | 'CONFIRMED' | 'unfilled'

function formatDateTime(d: Date | null): string {
  if (!d) return '—'
  return new Intl.DateTimeFormat(undefined, {
    dateStyle: 'medium',
    timeStyle: 'short',
  }).format(new Date(d))
}

function isoLocalForInput(d: Date | null): string {
  if (!d) return ''
  // Format as 'YYYY-MM-DDTHH:mm' for datetime-local input
  const local = new Date(d.getTime() - new Date().getTimezoneOffset() * 60000)
  return local.toISOString().slice(0, 16)
}

function FlightEditorSheet({
  attendee,
  programId,
  open,
  onClose,
}: {
  attendee: AttendeeRow | null
  programId: string
  open: boolean
  onClose: () => void
}) {
  const utils = trpc.useUtils()
  const [arrivalAt, setArrivalAt] = useState('')
  const [arrivalFlightNumber, setArrivalFlightNumber] = useState('')
  const [arrivalAirport, setArrivalAirport] = useState('')
  const [departureAt, setDepartureAt] = useState('')
  const [departureFlightNumber, setDepartureFlightNumber] = useState('')
  const [departureAirport, setDepartureAirport] = useState('')
  const [adminNotes, setAdminNotes] = useState('')

  useEffect(() => {
    if (!attendee) return
    const fd = attendee.flightDetail
    setArrivalAt(isoLocalForInput(fd?.arrivalAt ?? null))
    setArrivalFlightNumber(fd?.arrivalFlightNumber ?? '')
    setArrivalAirport(fd?.arrivalAirport ?? '')
    setDepartureAt(isoLocalForInput(fd?.departureAt ?? null))
    setDepartureFlightNumber(fd?.departureFlightNumber ?? '')
    setDepartureAirport(fd?.departureAirport ?? '')
    setAdminNotes(fd?.adminNotes ?? '')
  }, [attendee])

  const upsertMutation = trpc.logistics.upsertFlightDetail.useMutation({
    onSuccess: () => {
      toast.success('Flight details saved')
      utils.logistics.listFlightDetails.invalidate({ programId })
      onClose()
    },
    onError: (err) => toast.error(err.message),
  })

  if (!attendee) return null

  const handleSave = () => {
    upsertMutation.mutate({
      attendingMemberId: attendee.id,
      arrivalAt: arrivalAt ? new Date(arrivalAt) : null,
      arrivalFlightNumber: arrivalFlightNumber.trim() || null,
      arrivalAirport: arrivalAirport.trim().toUpperCase() || null,
      departureAt: departureAt ? new Date(departureAt) : null,
      departureFlightNumber: departureFlightNumber.trim() || null,
      departureAirport: departureAirport.trim().toUpperCase() || null,
      adminNotes: adminNotes.trim() || null,
    })
  }

  return (
    <Sheet open={open} onOpenChange={(o) => !o && onClose()}>
      <SheetContent className="sm:max-w-md overflow-y-auto">
        <SheetHeader>
          <SheetTitle>{attendee.user.name ?? attendee.user.email}</SheetTitle>
          <SheetDescription>
            {attendee.confirmation.project.title}
          </SheetDescription>
        </SheetHeader>

        <div className="space-y-5 py-6">
          <div className="space-y-3 rounded-md border p-3">
            <div className="text-muted-foreground text-xs font-medium uppercase tracking-wide">
              Arrival
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="arr-at">Date &amp; time</Label>
              <Input
                id="arr-at"
                type="datetime-local"
                value={arrivalAt}
                onChange={(e) => setArrivalAt(e.target.value)}
              />
            </div>
            <div className="grid grid-cols-2 gap-2">
              <div className="space-y-1.5">
                <Label htmlFor="arr-flight">Flight number</Label>
                <Input
                  id="arr-flight"
                  value={arrivalFlightNumber}
                  onChange={(e) => setArrivalFlightNumber(e.target.value)}
                  placeholder="AF7400"
                />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="arr-airport">Airport (IATA)</Label>
                <Input
                  id="arr-airport"
                  value={arrivalAirport}
                  onChange={(e) => setArrivalAirport(e.target.value)}
                  placeholder="NCE"
                />
              </div>
            </div>
          </div>

          <div className="space-y-3 rounded-md border p-3">
            <div className="text-muted-foreground text-xs font-medium uppercase tracking-wide">
              Departure
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="dep-at">Date &amp; time</Label>
              <Input
                id="dep-at"
                type="datetime-local"
                value={departureAt}
                onChange={(e) => setDepartureAt(e.target.value)}
              />
            </div>
            <div className="grid grid-cols-2 gap-2">
              <div className="space-y-1.5">
                <Label htmlFor="dep-flight">Flight number</Label>
                <Input
                  id="dep-flight"
                  value={departureFlightNumber}
                  onChange={(e) => setDepartureFlightNumber(e.target.value)}
                  placeholder="AF7405"
                />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="dep-airport">Airport (IATA)</Label>
                <Input
                  id="dep-airport"
                  value={departureAirport}
                  onChange={(e) => setDepartureAirport(e.target.value)}
                  placeholder="NCE"
                />
              </div>
            </div>
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="notes">Admin notes</Label>
            <Textarea
              id="notes"
              value={adminNotes}
              onChange={(e) => setAdminNotes(e.target.value)}
              placeholder="e.g. paid by program, awaiting receipt"
              rows={3}
            />
          </div>
        </div>

        <SheetFooter>
          <Button variant="outline" onClick={onClose}>
            Cancel
          </Button>
          <Button onClick={handleSave} disabled={upsertMutation.isPending}>
            {upsertMutation.isPending ? (
              <Loader2 className="mr-2 h-4 w-4 animate-spin" />
            ) : null}
            Save
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  )
}

function csvEscape(value: string | null | undefined): string {
  const str = value ?? ''
  if (str.includes('"') || str.includes(',') || str.includes('\n')) {
    return `"${str.replace(/"/g, '""')}"`
  }
  return str
}

function buildTravelCsv(rows: AttendeeRow[]): string {
  const header = [
    'Project',
    'Attendee',
    'Email',
    'Arrival date/time',
    'Arrival flight',
    'Arrival airport',
    'Departure date/time',
    'Departure flight',
    'Departure airport',
    'Status',
    'Needs visa',
  ].join(',')
  const lines = rows.map((r) => {
    const fd = r.flightDetail
    return [
      csvEscape(r.confirmation.project.title),
      csvEscape(r.user.name ?? r.user.email),
      csvEscape(r.user.email),
      csvEscape(fd?.arrivalAt ? new Date(fd.arrivalAt).toLocaleString() : ''),
      csvEscape(fd?.arrivalFlightNumber),
      csvEscape(fd?.arrivalAirport),
      csvEscape(fd?.departureAt ? new Date(fd.departureAt).toLocaleString() : ''),
      csvEscape(fd?.departureFlightNumber),
      csvEscape(fd?.departureAirport),
      csvEscape(fd?.status ?? ''),
      r.needsVisa ? 'Yes' : 'No',
    ].join(',')
  })
  return [header, ...lines].join('\r\n')
}

export function TravelTab({ programId }: Props) {
  const utils = trpc.useUtils()
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all')
  const [editing, setEditing] = useState<AttendeeRow | null>(null)

  const { data, isLoading } = trpc.logistics.listFlightDetails.useQuery(
    { programId },
    { refetchInterval: 60_000 },
  )

  const setStatusMutation = trpc.logistics.setFlightStatus.useMutation({
    onSuccess: () => {
      toast.success('Status updated')
      utils.logistics.listFlightDetails.invalidate({ programId })
    },
    onError: (err) => toast.error(err.message),
  })

  const filtered = useMemo(() => {
    if (!data) return []
    if (statusFilter === 'all') return data
    if (statusFilter === 'unfilled') return data.filter((r) => !r.flightDetail)
    return data.filter((r) => r.flightDetail?.status === statusFilter)
  }, [data, statusFilter])

  const totals = useMemo(() => {
    const c = { all: 0, PENDING: 0, CONFIRMED: 0, unfilled: 0 }
    for (const r of data ?? []) {
      c.all++
      if (!r.flightDetail) c.unfilled++
      else c[r.flightDetail.status]++
    }
    return c
  }, [data])

  const StatusPill = ({
    value,
    label,
    count,
  }: {
    value: StatusFilter
    label: string
    count: number
  }) => (
    <button
      type="button"
      onClick={() => setStatusFilter(value)}
      className={`rounded-md border px-2.5 py-1 text-xs font-medium transition-colors ${
        statusFilter === value
          ? 'bg-primary text-primary-foreground border-primary'
          : 'bg-background hover:bg-muted'
      }`}
    >
      {label} <span className="tabular-nums opacity-80">({count})</span>
    </button>
  )

  return (
    <div className="space-y-4">
      <Card>
        <CardHeader className="space-y-3">
          <div className="flex items-center justify-between gap-4">
            <div className="flex items-center gap-2">
              <Plane className="text-muted-foreground h-4 w-4" />
              <CardTitle className="text-base">Travel for confirmed finalists</CardTitle>
            </div>
            <div className="flex flex-wrap items-center gap-1.5">
              <StatusPill value="all" label="All" count={totals.all} />
              <StatusPill value="unfilled" label="Unfilled" count={totals.unfilled} />
              <StatusPill value="PENDING" label="Pending" count={totals.PENDING} />
              <StatusPill value="CONFIRMED" label="Confirmed" count={totals.CONFIRMED} />
              <Button
                variant="outline"
                size="sm"
                disabled={!data || data.length === 0}
                onClick={() => {
                  if (!data) return
                  const csv = buildTravelCsv(data as AttendeeRow[])
                  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' })
                  const url = URL.createObjectURL(blob)
                  const a = document.createElement('a')
                  a.href = url
                  a.download = 'travel-manifest.csv'
                  document.body.appendChild(a)
                  a.click()
                  document.body.removeChild(a)
                  URL.revokeObjectURL(url)
                }}
              >
                <Download className="mr-1 h-4 w-4" /> Download CSV
              </Button>
            </div>
          </div>
        </CardHeader>
        <CardContent>
          {isLoading ? (
            <div className="space-y-2">
              {[1, 2, 3].map((i) => (
                <Skeleton key={i} className="h-14 w-full" />
              ))}
            </div>
          ) : filtered.length === 0 ? (
            <p className="text-muted-foreground py-12 text-center text-sm">
              {data && data.length === 0
                ? 'No confirmed finalist attendees yet.'
                : 'No attendees match this filter.'}
            </p>
          ) : (
            <div className="overflow-hidden rounded-md border">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Attendee</TableHead>
                    <TableHead>Arrival</TableHead>
                    <TableHead>Departure</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead></TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {filtered.map((r) => {
                    const fd = r.flightDetail
                    return (
                      <TableRow key={r.id}>
                        <TableCell>
                          <div className="font-medium">
                            {r.user.name ?? r.user.email}
                          </div>
                          <div className="text-muted-foreground text-xs">
                            {r.confirmation.project.title}
                            {r.needsVisa ? ' · needs visa' : ''}
                          </div>
                        </TableCell>
                        <TableCell className="text-sm">
                          <div>{formatDateTime(fd?.arrivalAt ?? null)}</div>
                          {(fd?.arrivalFlightNumber || fd?.arrivalAirport) && (
                            <div className="text-muted-foreground text-xs">
                              {fd.arrivalFlightNumber ?? '—'}
                              {fd.arrivalAirport ? ` · ${fd.arrivalAirport}` : ''}
                            </div>
                          )}
                        </TableCell>
                        <TableCell className="text-sm">
                          <div>{formatDateTime(fd?.departureAt ?? null)}</div>
                          {(fd?.departureFlightNumber || fd?.departureAirport) && (
                            <div className="text-muted-foreground text-xs">
                              {fd.departureFlightNumber ?? '—'}
                              {fd.departureAirport ? ` · ${fd.departureAirport}` : ''}
                            </div>
                          )}
                        </TableCell>
                        <TableCell>
                          {fd ? (
                            <button
                              type="button"
                              onClick={() =>
                                setStatusMutation.mutate({
                                  flightDetailId: fd.id,
                                  status: fd.status === 'PENDING' ? 'CONFIRMED' : 'PENDING',
                                })
                              }
                              className="cursor-pointer"
                              title="Click to toggle"
                            >
                              <Badge
                                variant={fd.status === 'CONFIRMED' ? 'default' : 'secondary'}
                                className="text-xs"
                              >
                                {fd.status === 'CONFIRMED' ? 'Confirmed' : 'Pending'}
                              </Badge>
                            </button>
                          ) : (
                            <Badge variant="outline" className="text-xs">
                              No info
                            </Badge>
                          )}
                        </TableCell>
                        <TableCell className="text-right">
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => setEditing(r as AttendeeRow)}
                          >
                            Edit
                          </Button>
                        </TableCell>
                      </TableRow>
                    )
                  })}
                </TableBody>
              </Table>
            </div>
          )}
        </CardContent>
      </Card>
      <FlightEditorSheet
        attendee={editing}
        programId={programId}
        open={!!editing}
        onClose={() => setEditing(null)}
      />
    </div>
  )
}
