"use client";

import { type FormEvent, useState, useTransition } from "react";
import { Pencil, Plus, Trash2 } from "lucide-react";
import { toast } from "sonner";

import { Button } from "@/components/ui/button";
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { getChildBirthdateRange } from "@/lib/child-birthdate";
import { createMyChild, deleteMyChild, updateMyChild } from "../actions";

export type MyChild = {
  id: string;
  firstName: string;
  lastName: string;
  dateOfBirth: string | null;
};

type ChildPayload = {
  firstName: string;
  lastName: string;
  dateOfBirth: string;
};

const emptyChildPayload: ChildPayload = {
  firstName: "",
  lastName: "",
  dateOfBirth: "",
};

export function MyChildrenManager({
  items,
  canManage,
}: {
  items: MyChild[];
  canManage: boolean;
}) {
  const [createOpen, setCreateOpen] = useState(false);
  const [createPayload, setCreatePayload] =
    useState<ChildPayload>(emptyChildPayload);
  const [editingChild, setEditingChild] = useState<MyChild | null>(null);
  const [editPayload, setEditPayload] =
    useState<ChildPayload>(emptyChildPayload);
  const [childToDelete, setChildToDelete] = useState<MyChild | null>(null);
  const [isPending, startTransition] = useTransition();

  function openEditor(child: MyChild) {
    setEditingChild(child);
    setEditPayload(payloadFromChild(child));
  }

  function handleCreate(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();

    startTransition(async () => {
      const result = await createMyChild(createPayload);
      if (result.error) {
        toast.error(result.error);
        return;
      }

      toast.success("Kind angelegt.");
      setCreatePayload(emptyChildPayload);
      setCreateOpen(false);
    });
  }

  function handleUpdate(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!editingChild) return;

    startTransition(async () => {
      const result = await updateMyChild(editingChild.id, editPayload);
      if (result.error) {
        toast.error(result.error);
        return;
      }

      toast.success("Kind aktualisiert.");
      setEditingChild(null);
    });
  }

  function handleDelete(child: MyChild) {
    startTransition(async () => {
      const result = await deleteMyChild(child.id);
      if (result.error) {
        toast.error(result.error);
        return;
      }

      toast.success("Kind entfernt.");
      setChildToDelete(null);
    });
  }

  return (
    <div className="space-y-3">
      {items.length === 0 ? (
        <p className="text-sm italic text-[var(--ink-faint)]">
          Keine Kinder verknüpft.
        </p>
      ) : (
        <div className="flex flex-col gap-2">
          {items.map((child) => (
            <div
              key={child.id}
              className="flex items-center justify-between gap-3 rounded-lg bg-[var(--surface-2)] p-[10px_12px]"
            >
              <div className="flex min-w-0 items-center gap-3">
                <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-[var(--accent-soft)] text-[11px] font-semibold text-[var(--accent-deep)]">
                  {getInitials(child)}
                </div>
                <div className="min-w-0">
                  <p className="truncate text-sm font-semibold text-[var(--ink)]">
                    {child.firstName} {child.lastName}
                  </p>
                  {child.dateOfBirth ? (
                    <p className="text-xs text-[var(--ink-soft)]">
                      Geboren am{" "}
                      {new Date(child.dateOfBirth).toLocaleDateString("de-DE")}
                    </p>
                  ) : (
                    <p className="text-xs italic text-[var(--ink-faint)]">
                      Geburtsdatum fehlt
                    </p>
                  )}
                </div>
              </div>
              <div className="flex shrink-0 items-center gap-1">
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7"
                  onClick={() => openEditor(child)}
                  disabled={isPending || !canManage}
                  aria-label="Kind bearbeiten"
                >
                  <Pencil className="h-4 w-4" />
                </Button>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon"
                  className="h-7 w-7 text-[var(--danger)] hover:bg-[var(--danger-soft)] hover:text-[var(--danger)]"
                  onClick={() => setChildToDelete(child)}
                  disabled={isPending || !canManage}
                  aria-label="Kind löschen"
                >
                  <Trash2 className="h-4 w-4" />
                </Button>
              </div>
            </div>
          ))}
        </div>
      )}

      {canManage ? (
        <Dialog
          open={createOpen}
          onOpenChange={(open) => {
            setCreateOpen(open);
            if (!open) setCreatePayload(emptyChildPayload);
          }}
        >
          <DialogTrigger asChild>
            <Button type="button" variant="pill" size="sm" className="w-full">
              <Plus className="h-4 w-4" />
              Kind hinzufügen
            </Button>
          </DialogTrigger>
          <DialogContent>
            <form onSubmit={handleCreate}>
              <DialogHeader>
                <DialogTitle>Kind hinzufügen</DialogTitle>
                <DialogDescription>
                  Dieses Kind wird mit deinem Haushalt verknüpft.
                </DialogDescription>
              </DialogHeader>
              <ChildFields
                idPrefix="create-child"
                value={createPayload}
                onChange={setCreatePayload}
              />
              <DialogFooter>
                <Button
                  type="button"
                  variant="ghost"
                  onClick={() => setCreateOpen(false)}
                  disabled={isPending}
                >
                  Abbrechen
                </Button>
                <Button type="submit" disabled={isPending}>
                  Speichern
                </Button>
              </DialogFooter>
            </form>
          </DialogContent>
        </Dialog>
      ) : (
        <p className="text-xs italic text-[var(--ink-faint)]">
          Dein Account ist noch keinem Haushalt zugeordnet.
        </p>
      )}

      <Dialog
        open={!!editingChild}
        onOpenChange={(open) => !open && setEditingChild(null)}
      >
        <DialogContent>
          <form onSubmit={handleUpdate}>
            <DialogHeader>
              <DialogTitle>Kind bearbeiten</DialogTitle>
            </DialogHeader>
            {editingChild && (
              <ChildFields
                idPrefix="edit-child"
                value={editPayload}
                onChange={setEditPayload}
              />
            )}
            <DialogFooter>
              <Button
                type="button"
                variant="ghost"
                onClick={() => setEditingChild(null)}
                disabled={isPending}
              >
                Abbrechen
              </Button>
              <Button type="submit" disabled={isPending}>
                Aktualisieren
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <ConfirmDialog
        open={!!childToDelete}
        onOpenChange={(open) => {
          if (!open) setChildToDelete(null);
        }}
        title="Kind entfernen?"
        description={
          childToDelete
            ? `${childToDelete.firstName} ${childToDelete.lastName} wird aus deinem Haushalt entfernt.`
            : "Dieses Kind wird aus deinem Haushalt entfernt."
        }
        confirmLabel="Entfernen"
        pendingLabel="Wird entfernt..."
        isPending={isPending}
        onConfirm={() => {
          if (childToDelete) handleDelete(childToDelete);
        }}
      />
    </div>
  );
}

function ChildFields({
  idPrefix,
  value,
  onChange,
}: {
  idPrefix: string;
  value: ChildPayload;
  onChange: (value: ChildPayload) => void;
}) {
  const birthdateRange = getChildBirthdateRange();

  return (
    <div className="grid gap-4 py-4">
      <div className="grid gap-2">
        <Label
          htmlFor={`${idPrefix}-firstName`}
          className="text-xs font-semibold text-[var(--ink-soft)]"
        >
          Vorname
        </Label>
        <Input
          id={`${idPrefix}-firstName`}
          name="firstName"
          value={value.firstName}
          onChange={(event) =>
            onChange({ ...value, firstName: event.target.value })
          }
          required
        />
      </div>
      <div className="grid gap-2">
        <Label
          htmlFor={`${idPrefix}-lastName`}
          className="text-xs font-semibold text-[var(--ink-soft)]"
        >
          Nachname
        </Label>
        <Input
          id={`${idPrefix}-lastName`}
          name="lastName"
          value={value.lastName}
          onChange={(event) =>
            onChange({ ...value, lastName: event.target.value })
          }
          required
        />
      </div>
      <div className="grid gap-2">
        <Label
          htmlFor={`${idPrefix}-dateOfBirth`}
          className="text-xs font-semibold text-[var(--ink-soft)]"
        >
          Geburtsdatum
        </Label>
        <Input
          id={`${idPrefix}-dateOfBirth`}
          name="dateOfBirth"
          type="date"
          min={birthdateRange.min}
          max={birthdateRange.max}
          value={value.dateOfBirth}
          onChange={(event) =>
            onChange({ ...value, dateOfBirth: event.target.value })
          }
        />
      </div>
    </div>
  );
}

function payloadFromChild(child: MyChild): ChildPayload {
  return {
    firstName: child.firstName,
    lastName: child.lastName,
    dateOfBirth: child.dateOfBirth ?? "",
  };
}

function getInitials(child: MyChild) {
  return `${child.firstName[0] ?? ""}${child.lastName[0] ?? ""}`.toUpperCase();
}
