'use client'

import { useState, useImperativeHandle, forwardRef } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Textarea } from '@/components/ui/textarea'
import { Label } from '@/components/ui/label'
import { Checkbox } from '@/components/ui/checkbox'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog'
import { Badge } from '@/components/ui/badge'
import { Plus, Pencil, Trash2, Mail, MailCheck, Utensils } from 'lucide-react'
import { toast } from 'sonner'

const ALLERGENS = [
  'GLUTEN',
  'CRUSTACEANS',
  'EGGS',
  'FISH',
  'PEANUTS',
  'SOYBEANS',
  'MILK',
  'TREE_NUTS',
  'CELERY',
  'MUSTARD',
  'SESAME',
  'SULPHITES',
  'LUPIN',
  'MOLLUSCS',
] as const
type Allergen = (typeof ALLERGENS)[number]

const STANDALONE = '__standalone__'
const NO_DISH = '__no_dish__'

type Editing = { mode: 'new' } | { mode: 'edit'; id: string } | null

export type LunchExternalsHandle = {
  openEditDialog: (id: string) => void
}

export const LunchExternals = forwardRef<
  LunchExternalsHandle,
  { programId: string; lunchEventId: string }
>(function LunchExternals({ programId, lunchEventId }, ref) {
  const utils = trpc.useUtils()
  const { data: externals } = trpc.lunch.listExternals.useQuery({ lunchEventId })
  const { data: dishes } = trpc.lunch.listDishes.useQuery({ lunchEventId })
  const { data: projects } = trpc.program.listFinalistProjects.useQuery({
    programId,
  })

  const [editing, setEditing] = useState<Editing>(null)

  useImperativeHandle(
    ref,
    () => ({
      openEditDialog: (id: string) => setEditing({ mode: 'edit', id }),
    }),
    [],
  )

  const invalidateAll = () => {
    utils.lunch.listExternals.invalidate({ lunchEventId })
    utils.lunch.getManifest.invalidate({ programId })
  }

  const create = trpc.lunch.createExternal.useMutation({
    onSuccess: invalidateAll,
    onError: (e) => toast.error(e.message),
  })
  const update = trpc.lunch.updateExternal.useMutation({
    onSuccess: invalidateAll,
    onError: (e) => toast.error(e.message),
  })
  const del = trpc.lunch.deleteExternal.useMutation({
    onSuccess: invalidateAll,
    onError: (e) => toast.error(e.message),
  })
  const sendInvite = trpc.lunch.sendExternalInvite.useMutation({
    onSuccess: () => {
      invalidateAll()
      toast.success('Dish invite sent')
    },
    onError: (e) => toast.error(e.message),
  })

  const editingRow =
    editing?.mode === 'edit'
      ? (externals?.find((e) => e.id === editing.id) ?? null)
      : null

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex items-center justify-between">
          <span>External attendees</span>
          <Button size="sm" onClick={() => setEditing({ mode: 'new' })}>
            <Plus className="mr-1 h-4 w-4" /> Add external
          </Button>
        </CardTitle>
      </CardHeader>
      <CardContent>
        {externals?.length === 0 && (
          <p className="text-muted-foreground text-sm">
            No external attendees yet. Add jurors, dignitaries, or per-team plus-ones.
          </p>
        )}
        {externals && externals.length > 0 && (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <tbody>
                {externals.map((e) => (
                  <tr key={e.id} className="border-b last:border-b-0">
                    <td className="py-2 font-medium">{e.name}</td>
                    <td className="text-muted-foreground">
                      {e.project?.title ?? 'Standalone'}
                    </td>
                    <td className="text-muted-foreground">{e.roleNote ?? ''}</td>
                    <td>
                      {e.dishId ? (
                        <Badge variant="secondary" className="gap-1">
                          <Utensils className="h-3 w-3" /> Picked
                        </Badge>
                      ) : !e.email ? (
                        <Badge variant="outline" className="text-muted-foreground">
                          No email
                        </Badge>
                      ) : e.inviteSentAt ? (
                        <Badge variant="outline" className="gap-1">
                          <MailCheck className="h-3 w-3" /> Invited
                        </Badge>
                      ) : (
                        <Badge variant="outline" className="text-muted-foreground">
                          Not invited
                        </Badge>
                      )}
                    </td>
                    <td className="text-right">
                      {e.email && !e.dishId && (
                        <Button
                          size="sm"
                          variant="ghost"
                          title={e.inviteSentAt ? 'Resend dish invite' : 'Send dish invite'}
                          disabled={
                            sendInvite.isPending &&
                            sendInvite.variables?.externalId === e.id
                          }
                          onClick={() => sendInvite.mutate({ externalId: e.id })}
                        >
                          <Mail className="h-4 w-4" />
                        </Button>
                      )}
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => setEditing({ mode: 'edit', id: e.id })}
                      >
                        <Pencil className="h-4 w-4" />
                      </Button>
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => {
                          if (confirm(`Delete external attendee "${e.name}"?`)) {
                            del.mutate({ externalId: e.id })
                          }
                        }}
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </CardContent>

      {editing && (
        <ExternalDialog
          mode={editing.mode}
          initial={editingRow}
          dishes={dishes ?? []}
          projects={projects ?? []}
          submitting={create.isPending || update.isPending}
          onClose={() => setEditing(null)}
          onSubmit={(values) => {
            if (editing.mode === 'new') {
              create.mutate(
                { lunchEventId, ...values },
                { onSuccess: () => setEditing(null) },
              )
            } else {
              update.mutate(
                { externalId: editing.id, ...values },
                { onSuccess: () => setEditing(null) },
              )
            }
          }}
        />
      )}
    </Card>
  )
})

function ExternalDialog({
  mode,
  initial,
  dishes,
  projects,
  submitting,
  onClose,
  onSubmit,
}: {
  mode: 'new' | 'edit'
  initial: {
    name: string
    email: string | null
    projectId: string | null
    roleNote: string | null
    dishId: string | null
    allergens: string[]
    allergenOther: string | null
  } | null
  dishes: Array<{ id: string; name: string }>
  projects: Array<{ id: string; title: string }>
  submitting: boolean
  onClose: () => void
  onSubmit: (values: {
    name: string
    email?: string
    projectId?: string | null
    roleNote?: string
    dishId?: string | null
    allergens: Allergen[]
    allergenOther?: string | null
  }) => void
}) {
  const [name, setName] = useState(initial?.name ?? '')
  const [email, setEmail] = useState(initial?.email ?? '')
  const [projectId, setProjectId] = useState(initial?.projectId ?? '')
  const [roleNote, setRoleNote] = useState(initial?.roleNote ?? '')
  const [dishId, setDishId] = useState(initial?.dishId ?? '')
  const [allergens, setAllergens] = useState<Allergen[]>(
    (initial?.allergens as Allergen[]) ?? [],
  )
  const [allergenOther, setAllergenOther] = useState(initial?.allergenOther ?? '')

  return (
    <Dialog open onOpenChange={(o) => { if (!o) onClose() }}>
      <DialogContent className="max-w-2xl">
        <DialogHeader>
          <DialogTitle>
            {mode === 'new' ? 'Add external attendee' : 'Edit external attendee'}
          </DialogTitle>
        </DialogHeader>
        <div className="space-y-4">
          <div>
            <Label>Name *</Label>
            <Input value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div>
            <Label>Email (optional)</Label>
            <Input
              type="email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
          <div>
            <Label>Project (optional)</Label>
            <Select
              value={projectId === '' ? STANDALONE : projectId}
              onValueChange={(v) => setProjectId(v === STANDALONE ? '' : v)}
            >
              <SelectTrigger>
                <SelectValue />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={STANDALONE}>Standalone</SelectItem>
                {projects.map((p) => (
                  <SelectItem key={p.id} value={p.id}>
                    {p.title}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div>
            <Label>Role / note (optional)</Label>
            <Input
              value={roleNote}
              onChange={(e) => setRoleNote(e.target.value)}
              placeholder="e.g. Foundation rep, Speaker, Sponsor"
            />
          </div>
          <div>
            <Label>Dish</Label>
            <Select
              value={dishId === '' ? NO_DISH : dishId}
              onValueChange={(v) => setDishId(v === NO_DISH ? '' : v)}
            >
              <SelectTrigger>
                <SelectValue placeholder="Not picked" />
              </SelectTrigger>
              <SelectContent>
                <SelectItem value={NO_DISH}>Not picked</SelectItem>
                {dishes.map((d) => (
                  <SelectItem key={d.id} value={d.id}>
                    {d.name}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
          </div>
          <div>
            <Label>Allergens</Label>
            <div className="grid grid-cols-2 gap-2 sm:grid-cols-3">
              {ALLERGENS.map((a) => (
                <label key={a} className="flex items-center gap-2 text-sm">
                  <Checkbox
                    checked={allergens.includes(a)}
                    onCheckedChange={(v) =>
                      setAllergens(
                        v ? [...allergens, a] : allergens.filter((x) => x !== a),
                      )
                    }
                  />
                  {a.replace('_', ' ').toLowerCase()}
                </label>
              ))}
            </div>
          </div>
          <div>
            <Label>Other allergens / notes (optional)</Label>
            <Textarea
              value={allergenOther}
              onChange={(e) => setAllergenOther(e.target.value)}
            />
          </div>
        </div>
        <DialogFooter>
          <Button variant="outline" onClick={onClose}>
            Cancel
          </Button>
          <Button
            disabled={!name.trim() || submitting}
            onClick={() =>
              onSubmit({
                name: name.trim(),
                email: email.trim() || undefined,
                projectId: projectId || null,
                roleNote: roleNote.trim() || undefined,
                dishId: dishId || null,
                allergens,
                allergenOther: allergenOther.trim() || null,
              })
            }
          >
            Save
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}
