'use client'

import Link from 'next/link'
import { useMemo, useState } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
import { Skeleton } from '@/components/ui/skeleton'
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table'
import { Download, Settings as SettingsIcon, ShieldOff } from 'lucide-react'
import { VisaEditDialog, type VisaEditTarget } from './visa-edit-dialog'
import type { VisaStatus } from '@prisma/client'

interface Props {
  programId: string
}

const STATUS_BADGE: Record<
  VisaStatus,
  { label: string; variant: 'default' | 'secondary' | 'destructive' | 'outline' }
> = {
  NOT_NEEDED: { label: 'Not needed', variant: 'outline' },
  REQUESTED: { label: 'Requested', variant: 'secondary' },
  INVITATION_SENT: { label: 'Invitation sent', variant: 'secondary' },
  APPOINTMENT_BOOKED: { label: 'Appointment booked', variant: 'default' },
  GRANTED: { label: 'Granted', variant: 'default' },
  DENIED: { label: 'Denied', variant: 'destructive' },
}

type StatusFilter = 'all' | VisaStatus

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

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

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

type VisaRow = {
  status: VisaStatus
  nationality: string | null
  invitationSentAt: Date | null
  appointmentAt: Date | null
  decisionAt: Date | null
  notes: string | null
  project: { id: string; title: string }
  attendee: { id: string; user: { id: string; name: string | null; email: string } }
}

function buildVisaCsv(rows: VisaRow[]): string {
  const header = [
    'Project',
    'Attendee',
    'Email',
    'Nationality',
    'Status',
    'Invitation sent',
    'Appointment',
    'Decision',
    'Notes',
  ].join(',')
  const lines = rows.map((r) => {
    return [
      csvEscape(r.project.title),
      csvEscape(r.attendee.user.name ?? r.attendee.user.email),
      csvEscape(r.attendee.user.email),
      csvEscape(r.nationality),
      csvEscape(r.status),
      csvEscape(r.invitationSentAt ? new Date(r.invitationSentAt).toLocaleDateString() : ''),
      csvEscape(r.appointmentAt ? new Date(r.appointmentAt).toLocaleDateString() : ''),
      csvEscape(r.decisionAt ? new Date(r.decisionAt).toLocaleDateString() : ''),
      csvEscape(r.notes),
    ].join(',')
  })
  return [header, ...lines].join('\r\n')
}

export function VisasTab({ programId }: Props) {
  const [statusFilter, setStatusFilter] = useState<StatusFilter>('all')
  const [editTarget, setEditTarget] = useState<VisaEditTarget | null>(null)
  const [editOpen, setEditOpen] = useState(false)

  const { data, isLoading } = trpc.logistics.listVisaApplications.useQuery({ programId })

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

  const totals = useMemo(() => {
    const counts: Record<VisaStatus, number> = {
      NOT_NEEDED: 0,
      REQUESTED: 0,
      INVITATION_SENT: 0,
      APPOINTMENT_BOOKED: 0,
      GRANTED: 0,
      DENIED: 0,
    }
    for (const r of data ?? []) counts[r.status]++
    return counts
  }, [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-start justify-between gap-4">
            <div>
              <CardTitle className="text-base">Visa applications</CardTitle>
              <p className="text-muted-foreground mt-1 max-w-2xl text-xs">
                Process metadata only — invitation letters, passport copies, and visa decisions
                continue to flow over email and are never stored on this platform.
              </p>
            </div>
            <div className="flex items-center gap-2">
              <Button
                variant="outline"
                size="sm"
                disabled={!data || data.length === 0}
                onClick={() => {
                  if (!data) return
                  const csv = buildVisaCsv(data)
                  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 = 'visa-applications.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>
              <Button variant="outline" size="sm" asChild>
                <Link href="/admin/settings?tab=edition">
                  <SettingsIcon className="mr-2 h-3.5 w-3.5" />
                  Edition settings
                </Link>
              </Button>
            </div>
          </div>
          <div className="flex flex-wrap gap-1.5">
            <StatusPill value="all" label="All" count={(data ?? []).length} />
            <StatusPill value="REQUESTED" label="Requested" count={totals.REQUESTED} />
            <StatusPill
              value="INVITATION_SENT"
              label="Invitation sent"
              count={totals.INVITATION_SENT}
            />
            <StatusPill
              value="APPOINTMENT_BOOKED"
              label="Appointment booked"
              count={totals.APPOINTMENT_BOOKED}
            />
            <StatusPill value="GRANTED" label="Granted" count={totals.GRANTED} />
            <StatusPill value="DENIED" label="Denied" count={totals.DENIED} />
            <StatusPill value="NOT_NEEDED" label="Not needed" count={totals.NOT_NEEDED} />
          </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 ? (
            <div className="text-muted-foreground py-12 text-center text-sm">
              <ShieldOff className="mx-auto mb-2 h-6 w-6 opacity-60" />
              {statusFilter === 'all'
                ? 'No visa applications yet. They are auto-created when a team confirms with needsVisa=true.'
                : 'No applications match this filter.'}
            </div>
          ) : (
            <div className="overflow-hidden rounded-md border">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Project</TableHead>
                    <TableHead>Member</TableHead>
                    <TableHead>Nationality</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead>Next date</TableHead>
                    <TableHead>Notes</TableHead>
                    <TableHead className="text-right">Actions</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {filtered.map((r) => {
                    const badge = STATUS_BADGE[r.status]
                    const next = nextDate(r)
                    return (
                      <TableRow key={r.id}>
                        <TableCell className="font-medium">{r.project.title}</TableCell>
                        <TableCell>
                          <div className="text-sm">
                            {r.attendee.user.name ?? r.attendee.user.email}
                          </div>
                          <div className="text-muted-foreground text-xs">
                            {r.attendee.user.email}
                          </div>
                        </TableCell>
                        <TableCell className="text-sm">
                          {r.nationality ?? <span className="text-muted-foreground">—</span>}
                        </TableCell>
                        <TableCell>
                          <Badge variant={badge.variant} className="text-xs">
                            {badge.label}
                          </Badge>
                        </TableCell>
                        <TableCell className="text-sm">
                          {next.date ? (
                            <>
                              <div>{formatDateOnly(next.date)}</div>
                              <div className="text-muted-foreground text-xs">{next.label}</div>
                            </>
                          ) : (
                            <span className="text-muted-foreground">—</span>
                          )}
                        </TableCell>
                        <TableCell className="text-muted-foreground max-w-[18rem] truncate text-xs">
                          {r.notes ?? '—'}
                        </TableCell>
                        <TableCell className="text-right">
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => {
                              setEditTarget({
                                id: r.id,
                                status: r.status,
                                nationality: r.nationality,
                                invitationSentAt: r.invitationSentAt,
                                appointmentAt: r.appointmentAt,
                                decisionAt: r.decisionAt,
                                notes: r.notes,
                                attendeeName: r.attendee.user.name ?? r.attendee.user.email,
                                projectTitle: r.project.title,
                              })
                              setEditOpen(true)
                            }}
                          >
                            Edit
                          </Button>
                        </TableCell>
                      </TableRow>
                    )
                  })}
                </TableBody>
              </Table>
            </div>
          )}
        </CardContent>
      </Card>

      <VisaEditDialog
        open={editOpen}
        target={editTarget}
        programId={programId}
        onOpenChange={setEditOpen}
      />
    </div>
  )
}
