'use client'

import { useState, useMemo } from 'react'
import { trpc } from '@/lib/trpc/client'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Input } from '@/components/ui/input'
import { Switch } from '@/components/ui/switch'
import { Label } from '@/components/ui/label'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetDescription,
} from '@/components/ui/sheet'
import { LunchPickForm } from '@/components/applicant/lunch-pick-form'
import { Pencil, Download } from 'lucide-react'
import { toast } from 'sonner'

function formatAllergens(allergens: string[], other: string | null): string {
  return [...allergens.map((a) => a.replace('_', ' ').toLowerCase()), other]
    .filter(Boolean)
    .join(', ')
}

function DownloadCsvButton({ programId }: { programId: string }) {
  const utils = trpc.useUtils()
  const [pending, setPending] = useState(false)
  return (
    <Button
      variant="outline"
      size="sm"
      disabled={pending}
      onClick={async () => {
        setPending(true)
        try {
          const csv = await utils.client.lunch.exportManifestCsv.query({ programId })
          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 = 'lunch-manifest.csv'
          document.body.appendChild(a)
          a.click()
          document.body.removeChild(a)
          URL.revokeObjectURL(url)
        } catch (e) {
          toast.error((e as Error).message)
        } finally {
          setPending(false)
        }
      }}
    >
      <Download className="mr-1 h-4 w-4" /> Download CSV
    </Button>
  )
}

export function LunchManifest({
  programId,
  onEditExternal,
}: {
  programId: string
  onEditExternal?: (externalId: string) => void
}) {
  const { data } = trpc.lunch.getManifest.useQuery({ programId })
  const [search, setSearch] = useState('')
  const [missingOnly, setMissingOnly] = useState(false)
  const [editingMemberId, setEditingMemberId] = useState<string | null>(null)
  const editingMember = data?.members.find(
    (m) => m.attendingMemberId === editingMemberId,
  )

  type Row =
    | (NonNullable<typeof data>['members'][number] & { sortKey: string })
    | (NonNullable<typeof data>['externals'][number] & { sortKey: string })

  const rows: Row[] = useMemo(() => {
    if (!data) return []
    const all: Row[] = [
      ...data.members.map((m) => ({
        ...m,
        sortKey: `0-${m.project?.name ?? ''}-${m.name}`,
      })),
      ...data.externals.map((e) => ({
        ...e,
        sortKey: `1-${e.project?.name ?? ''}-${e.name}`,
      })),
    ]
    return all
      .filter(
        (r) =>
          !search ||
          (r.project?.name ?? '').toLowerCase().includes(search.toLowerCase()) ||
          r.name.toLowerCase().includes(search.toLowerCase()),
      )
      .filter((r) => !missingOnly || !r.dish)
      .sort((a, b) => a.sortKey.localeCompare(b.sortKey))
  }, [data, search, missingOnly])

  if (!data) return null

  // Aggregate dietary + allergen counts client-side for the summary chip
  const dietaryCounts: Record<string, number> = {}
  const allergenCounts: Record<string, number> = {}
  const allRows = [...data.members, ...data.externals]
  for (const r of allRows) {
    if (r.dish) {
      for (const t of r.dish.dietaryTags) {
        dietaryCounts[t] = (dietaryCounts[t] ?? 0) + 1
      }
    }
    for (const a of r.allergens) {
      allergenCounts[a] = (allergenCounts[a] ?? 0) + 1
    }
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="flex flex-wrap items-center gap-2">
          <span>Manifest</span>
          <Badge variant="outline">
            {data.summary.picked}/{data.summary.total} picked
            {data.summary.missing > 0 ? ` · ${data.summary.missing} missing` : ''}
          </Badge>
          {Object.entries(dietaryCounts).map(([tag, n]) => (
            <Badge key={tag} variant="secondary">
              {n} {tag.replace('_', ' ').toLowerCase()}
            </Badge>
          ))}
          {Object.entries(allergenCounts).map(([a, n]) => (
            <Badge key={a} variant="destructive">
              {n} {a.replace('_', ' ').toLowerCase()}
            </Badge>
          ))}
        </CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="flex flex-wrap items-center gap-4">
          <Input
            placeholder="Filter by team or name"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="max-w-xs"
          />
          <div className="flex items-center gap-2">
            <Switch
              id="missing-only"
              checked={missingOnly}
              onCheckedChange={setMissingOnly}
            />
            <Label htmlFor="missing-only">Missing picks only</Label>
          </div>
          <div className="ml-auto">
            <DownloadCsvButton programId={programId} />
          </div>
        </div>

        <div className="overflow-x-auto">
          <table className="w-full text-sm">
            <thead className="text-muted-foreground border-b text-left">
              <tr>
                <th className="py-2 font-medium">Team</th>
                <th className="font-medium">Attendee</th>
                <th className="font-medium">Type</th>
                <th className="font-medium">Dish</th>
                <th className="font-medium">Allergens</th>
                <th></th>
              </tr>
            </thead>
            <tbody>
              {rows.map((r) => {
                const id =
                  r.kind === 'MEMBER' ? r.attendingMemberId : r.externalId
                return (
                  <tr key={id} className="border-b">
                    <td className="py-2">{r.project?.name ?? '—'}</td>
                    <td>{r.name}</td>
                    <td>
                      <Badge variant="outline">
                        {r.kind === 'MEMBER' ? 'Member' : 'External'}
                      </Badge>
                    </td>
                    <td>
                      {r.dish ? (
                        r.dish.name
                      ) : (
                        <span className="text-muted-foreground">not picked</span>
                      )}
                    </td>
                    <td className="text-muted-foreground">
                      {formatAllergens(r.allergens, r.allergenOther)}
                    </td>
                    <td className="text-right">
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => {
                          if (r.kind === 'EXTERNAL') {
                            onEditExternal?.(r.externalId)
                          } else {
                            setEditingMemberId(r.attendingMemberId)
                          }
                        }}
                      >
                        <Pencil className="h-4 w-4" />
                      </Button>
                    </td>
                  </tr>
                )
              })}
              {rows.length === 0 && (
                <tr>
                  <td colSpan={6} className="text-muted-foreground py-6 text-center">
                    No rows match the current filter.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </CardContent>

      <Sheet
        open={!!editingMemberId}
        onOpenChange={(o) => { if (!o) setEditingMemberId(null) }}
      >
        <SheetContent side="right" className="w-full sm:max-w-md">
          <SheetHeader>
            <SheetTitle>Edit lunch pick</SheetTitle>
            {editingMember && (
              <SheetDescription>
                {editingMember.name} · {editingMember.project?.name}
              </SheetDescription>
            )}
          </SheetHeader>
          {editingMemberId && data?.event && (
            <div className="mt-6">
              <LunchPickForm
                attendingMemberId={editingMemberId}
                programId={programId}
                lunchEventId={data.event.id}
                canEdit
              />
            </div>
          )}
        </SheetContent>
      </Sheet>
    </Card>
  )
}
