'use client'

import { useState, useEffect } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Label } from '@/components/ui/label'
import {
  Select,
  SelectContent,
  SelectGroup,
  SelectItem,
  SelectLabel,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import { Checkbox } from '@/components/ui/checkbox'
import { Textarea } from '@/components/ui/textarea'
import { Badge } from '@/components/ui/badge'
import { Salad, Lock, CheckCircle2 } 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 NO_DISH = '__no_dish__'

function formatTag(t: string): string {
  return t.replace('_', ' ').toLowerCase()
}

export function LunchPickForm({
  attendingMemberId,
  programId,
  lunchEventId,
  canEdit,
  editingOnBehalfOf,
}: {
  attendingMemberId: string
  programId: string
  lunchEventId: string
  canEdit: boolean
  editingOnBehalfOf?: string | null
}) {
  const utils = trpc.useUtils()
  const { data: dishes } = trpc.lunch.listDishes.useQuery({ lunchEventId })
  const { data: row, refetch } = trpc.lunch.getMemberPick.useQuery({
    attendingMemberId,
  })
  const pick = row?.pick ?? null

  const [dishId, setDishId] = useState<string>('')
  const [allergens, setAllergens] = useState<Allergen[]>([])
  const [allergenOther, setAllergenOther] = useState<string>('')
  const [hydrated, setHydrated] = useState(false)

  useEffect(() => {
    if (!hydrated && pick) {
      setDishId(pick.dishId ?? '')
      setAllergens((pick.allergens as Allergen[]) ?? [])
      setAllergenOther(pick.allergenOther ?? '')
      setHydrated(true)
    }
  }, [pick, hydrated])

  const upsert = trpc.lunch.upsertPick.useMutation({
    onSuccess: () => {
      refetch()
      utils.lunch.getManifest.invalidate({ programId })
      toast.success('Lunch pick saved')
    },
    onError: (e) => toast.error(e.message),
  })

  function commit(next: {
    dishId?: string
    allergens?: Allergen[]
    allergenOther?: string
  }) {
    if (!canEdit) return
    upsert.mutate({
      attendingMemberId,
      dishId: (next.dishId ?? dishId) || null,
      allergens: next.allergens ?? allergens,
      allergenOther: (next.allergenOther ?? allergenOther) || null,
    })
  }

  if (!dishes) return null

  const grouped: Record<string, typeof dishes> = {}
  for (const d of dishes) {
    const key = d.dietaryTags.length > 0 ? d.dietaryTags[0] : 'OTHER'
    if (!grouped[key]) grouped[key] = []
    grouped[key].push(d)
  }

  return (
    <div className="space-y-3 rounded-md border-l-2 border-emerald-500/30 bg-emerald-500/5 p-3 text-sm">
      <div className="flex items-center gap-2">
        <Salad className="h-4 w-4 text-emerald-500" />
        <span className="font-medium">Lunch</span>
        {pick?.pickedAt && (
          <Badge variant="outline" className="gap-1">
            <CheckCircle2 className="h-3 w-3" /> picked
          </Badge>
        )}
        {!canEdit && (
          <Badge variant="secondary" className="gap-1">
            <Lock className="h-3 w-3" /> read-only
          </Badge>
        )}
        {editingOnBehalfOf && (
          <span className="text-muted-foreground text-xs">
            Editing on behalf of {editingOnBehalfOf}
          </span>
        )}
      </div>

      <div>
        <Label className="text-xs">Dish</Label>
        <Select
          value={dishId === '' ? NO_DISH : dishId}
          onValueChange={(v) => {
            const next = v === NO_DISH ? '' : v
            setDishId(next)
            commit({ dishId: next })
          }}
          disabled={!canEdit}
        >
          <SelectTrigger className="max-w-sm">
            <SelectValue placeholder="Pick a dish" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value={NO_DISH}>Not picked</SelectItem>
            {Object.entries(grouped).map(([group, items]) => (
              <SelectGroup key={group}>
                <SelectLabel>
                  {group === 'OTHER' ? 'All options' : formatTag(group)}
                </SelectLabel>
                {items.map((d) => (
                  <SelectItem key={d.id} value={d.id}>
                    {d.name}
                    {d.dietaryTags.length > 0 && (
                      <span className="text-muted-foreground ml-2 text-xs">
                        {d.dietaryTags.map(formatTag).join(', ')}
                      </span>
                    )}
                  </SelectItem>
                ))}
              </SelectGroup>
            ))}
          </SelectContent>
        </Select>
      </div>

      <div>
        <Label className="text-xs">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">
              <Checkbox
                checked={allergens.includes(a)}
                disabled={!canEdit}
                onCheckedChange={(v) => {
                  const next = v
                    ? [...allergens, a]
                    : allergens.filter((x) => x !== a)
                  setAllergens(next)
                  commit({ allergens: next })
                }}
              />
              <span className="text-xs">{formatTag(a)}</span>
            </label>
          ))}
        </div>
      </div>

      <div>
        <Label className="text-xs">Other allergens / notes</Label>
        <Textarea
          value={allergenOther}
          disabled={!canEdit}
          onChange={(e) => setAllergenOther(e.target.value)}
          onBlur={() => commit({ allergenOther })}
          rows={2}
        />
      </div>
    </div>
  )
}
