"use client";

import { useMemo, useState, useTransition } from "react";
import { EventParticipationStatus } from "@prisma/client";
import { format } from "date-fns";
import { de } from "date-fns/locale";
import { AlertTriangle, Check, X } from "lucide-react";
import { toast } from "sonner";

import { submitEventRsvp } from "@/actions/rsvp";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";

export type DashboardRsvpEventDto = {
  id: string;
  title: string;
  startDate: string;
  rsvpDeadline: string | null;
  children: {
    id: string;
    name: string;
    status: EventParticipationStatus | null;
  }[];
};

export function RsvpActionCard({ events }: { events: DashboardRsvpEventDto[] }) {
  if (events.length === 0) return null;

  return (
    <Card className="mb-8 border-amber-200 bg-amber-50/70">
      <CardHeader className="pb-3">
        <CardTitle className="flex items-center gap-2 text-lg text-amber-950">
          <AlertTriangle className="h-5 w-5 text-amber-700" />
          Aktion erforderlich
        </CardTitle>
        <CardDescription className="text-amber-900/80">
          Für diese Termine fehlt noch mindestens eine Rückmeldung deiner
          Familie.
        </CardDescription>
      </CardHeader>
      <CardContent className="grid gap-3">
        {events.map((event) => (
          <div
            key={event.id}
            className="flex flex-col gap-3 rounded-md border bg-background p-4 sm:flex-row sm:items-center sm:justify-between"
          >
            <div>
              <p className="font-medium">{event.title}</p>
              <p className="mt-1 text-sm text-muted-foreground">
                Rückmeldung bis{" "}
                {format(
                  new Date(event.rsvpDeadline ?? event.startDate),
                  "dd.MM.yyyy HH:mm",
                  { locale: de },
                )}
              </p>
            </div>
            <RsvpDialog event={event} />
          </div>
        ))}
      </CardContent>
    </Card>
  );
}

function RsvpDialog({ event }: { event: DashboardRsvpEventDto }) {
  const [open, setOpen] = useState(false);
  const [isPending, startTransition] = useTransition();
  const initialSelection = useMemo(
    () =>
      Object.fromEntries(
        event.children.map((child) => [child.id, child.status ?? ""]),
      ) as Record<string, EventParticipationStatus | "">,
    [event.children],
  );
  const [selection, setSelection] = useState(initialSelection);

  function submit() {
    const missingChild = event.children.find((child) => !selection[child.id]);
    if (missingChild) {
      toast.error(`Bitte Rückmeldung für ${missingChild.name} auswählen.`);
      return;
    }

    startTransition(async () => {
      for (const child of event.children) {
        const status = selection[child.id];
        if (!status) continue;

        const result = await submitEventRsvp({
          eventId: event.id,
          childId: child.id,
          status,
        });

        if (result.error) {
          toast.error(result.error);
          return;
        }
      }

      toast.success("Rückmeldung gespeichert.");
      setOpen(false);
    });
  }

  return (
    <Dialog
      open={open}
      onOpenChange={(nextOpen) => {
        setOpen(nextOpen);
        if (nextOpen) setSelection(initialSelection);
      }}
    >
      <DialogTrigger asChild>
        <Button size="sm">Jetzt abstimmen</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Rückmeldung für {event.title}</DialogTitle>
          <DialogDescription>
            Wähle pro Kind aus, ob es am Termin teilnimmt.
          </DialogDescription>
        </DialogHeader>

        <div className="grid gap-3 py-2">
          {event.children.map((child) => (
            <div key={child.id} className="rounded-md border p-4">
              <div className="mb-3 flex items-center justify-between gap-3">
                <p className="font-medium">{child.name}</p>
                {child.status && (
                  <Badge variant="outline">bereits gemeldet</Badge>
                )}
              </div>
              <div className="grid gap-2 sm:grid-cols-2">
                <label className="flex cursor-pointer items-center gap-2 rounded-md border p-3 text-sm hover:bg-muted/50">
                  <input
                    type="radio"
                    name={`rsvp-${child.id}`}
                    checked={
                      selection[child.id] ===
                      EventParticipationStatus.ATTENDING
                    }
                    onChange={() =>
                      setSelection((current) => ({
                        ...current,
                        [child.id]: EventParticipationStatus.ATTENDING,
                      }))
                    }
                  />
                  <Check className="h-4 w-4 text-emerald-600" />
                  Nimmt teil
                </label>
                <label className="flex cursor-pointer items-center gap-2 rounded-md border p-3 text-sm hover:bg-muted/50">
                  <input
                    type="radio"
                    name={`rsvp-${child.id}`}
                    checked={
                      selection[child.id] ===
                      EventParticipationStatus.NOT_ATTENDING
                    }
                    onChange={() =>
                      setSelection((current) => ({
                        ...current,
                        [child.id]: EventParticipationStatus.NOT_ATTENDING,
                      }))
                    }
                  />
                  <X className="h-4 w-4 text-rose-600" />
                  Nimmt nicht teil
                </label>
              </div>
            </div>
          ))}
        </div>

        <DialogFooter>
          <Button type="button" variant="ghost" onClick={() => setOpen(false)}>
            Abbrechen
          </Button>
          <Button type="button" disabled={isPending} onClick={submit}>
            {isPending ? "Speichern..." : "Rückmeldung speichern"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
