"use client";

import { useMemo, useState } from "react";
import useSWR from "swr";
import {
  Download,
  Eye,
  FilePenLine,
  Layers,
  Plus,
  Printer,
  Search,
  SlidersHorizontal,
  Trash2,
  UserCheck,
  UserPlus,
  Users,
  X,
} from "lucide-react";
import { toast } from "sonner";
import type {
  Desa,
  KategoriKelompok,
  Kelompok,
  Paginated,
  Penduduk,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { cetakHtml, escapeHtml, kopDesa } from "@/lib/cetak";
import { unduhCsv } from "@/lib/sekretariat";
import { labelGender } from "@/lib/utils";
import { useSession } from "@/lib/use-session";
import { PageHeader, StatCard } from "@/components/page-header";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Textarea } from "@/components/ui/textarea";

const KATEGORI_OPTIONS: { value: KategoriKelompok; label: string }[] = [
  { value: "TANI", label: "Pertanian" },
  { value: "NELAYAN", label: "Perikanan" },
  { value: "PETERNAK", label: "Peternakan" },
  { value: "UMKM", label: "UMKM" },
  { value: "PKK", label: "PKK" },
  { value: "KARANG_TARUNA", label: "Karang Taruna" },
  { value: "KEAGAMAAN", label: "Keagamaan" },
  { value: "PENDIDIKAN", label: "Pendidikan" },
  { value: "LAINNYA", label: "Lainnya" },
];

type FormState = {
  kode: string;
  nama: string;
  kategori: KategoriKelompok;
  ketua: string;
  jumlahAnggota: string;
  alamat: string;
  tahunBerdiri: string;
  keterangan: string;
  aktif: boolean;
};

const emptyForm: FormState = {
  kode: "",
  nama: "",
  kategori: "TANI",
  ketua: "",
  jumlahAnggota: "0",
  alamat: "",
  tahunBerdiri: "",
  keterangan: "",
  aktif: true,
};

function labelKategori(value: KategoriKelompok) {
  return KATEGORI_OPTIONS.find((option) => option.value === value)?.label ?? value;
}

const KOLOM_KELOMPOK_CSV = [
  "Kode Kelompok",
  "Nama Kelompok",
  "Kategori Kelompok",
  "Ketua Kelompok",
  "Jumlah Anggota Kelompok",
  "Alamat",
  "Tahun Berdiri",
  "Status",
  "Keterangan",
];

export default function KelompokPage() {
  const { user } = useSession();
  const canMutate = user?.role === "ADMIN" || user?.role === "OPERATOR";

  const { data, isLoading, mutate } = useSWR<Kelompok[]>("/kelompok", fetcher);
  const { data: pendudukList } = useSWR<Paginated<Penduduk>>(
    "/penduduk?limit=200",
    fetcher,
  );
  const { data: desa } = useSWR<Desa>("/desa", fetcher);
  const daftar = data ?? [];

  const [search, setSearch] = useState("");
  const [kategoriFilter, setKategoriFilter] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [detailId, setDetailId] = useState<number | null>(null);
  const [pendingPenduduk, setPendingPenduduk] = useState("");
  const [pendingJabatan, setPendingJabatan] = useState("Anggota");
  const [addingAnggota, setAddingAnggota] = useState(false);
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<Kelompok | null>(null);
  const [form, setForm] = useState<FormState>(emptyForm);
  const [saving, setSaving] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Kelompok | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [selected, setSelected] = useState<number[]>([]);
  const [aksiTerbuka, setAksiTerbuka] = useState(false);

  const { data: detail, mutate: mutateDetail } = useSWR<Kelompok>(
    detailId ? `/kelompok/${detailId}` : null,
    fetcher,
  );

  const filtered = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    return daftar.filter((item) => {
      if (
        keyword &&
        ![item.nama, item.ketua, item.alamat, labelKategori(item.kategori)]
          .filter(Boolean)
          .some((value) => String(value).toLowerCase().includes(keyword))
      ) {
        return false;
      }
      if (kategoriFilter && item.kategori !== kategoriFilter) return false;
      if (statusFilter === "aktif" && !item.aktif) return false;
      if (statusFilter === "nonaktif" && item.aktif) return false;
      return true;
    });
  }, [daftar, search, kategoriFilter, statusFilter]);

  const adaFilter = Boolean(search || kategoriFilter || statusFilter);

  function barisKelompokCsv(item: Kelompok) {
    return [
      item.kode ?? "",
      item.nama,
      labelKategori(item.kategori),
      item.ketua ?? "",
      String(item.jumlahAnggota),
      item.alamat ?? "",
      item.tahunBerdiri ? String(item.tahunBerdiri) : "",
      item.aktif ? "Aktif" : "Nonaktif",
      item.keterangan ?? "",
    ];
  }

  function cetakDaftar(rows: Kelompok[], judul = "Daftar Kelompok Masyarakat") {
    if (!rows.length) {
      toast.error("Belum ada data untuk dicetak");
      return;
    }
    const isi = `
      ${kopDesa(desa, judul)}
      <table><thead><tr><th>No</th><th>Kode</th><th>Nama Kelompok</th><th>Kategori</th><th>Ketua</th><th>Jumlah Anggota</th><th>Alamat</th><th>Status</th></tr></thead>
      <tbody>${rows
        .map(
          (item, index) =>
            `<tr><td class="num">${index + 1}</td><td>${escapeHtml(item.kode ?? "-")}</td><td>${escapeHtml(item.nama)}</td><td>${escapeHtml(labelKategori(item.kategori))}</td><td>${escapeHtml(item.ketua ?? "-")}</td><td class="num">${item.jumlahAnggota}</td><td>${escapeHtml(item.alamat ?? "-")}</td><td>${item.aktif ? "Aktif" : "Nonaktif"}</td></tr>`,
        )
        .join("")}</tbody></table>`;
    if (!cetakHtml(judul, isi)) {
      toast.error("Izinkan pop-up untuk mencetak");
    }
  }

  function unduh(rows: Kelompok[] = filtered) {
    if (!rows.length) {
      toast.error("Belum ada data untuk diunduh");
      return;
    }
    unduhCsv(
      `kelompok-masyarakat-${new Date().toISOString().slice(0, 10)}.csv`,
      KOLOM_KELOMPOK_CSV,
      rows.map(barisKelompokCsv),
    );
    toast.success(`${rows.length} kelompok diunduh`);
  }

  function toggleSemua() {
    const ids = filtered.map((item) => item.id);
    setSelected((current) =>
      ids.length && ids.every((id) => current.includes(id)) ? [] : ids,
    );
  }

  function toggleSatu(id: number) {
    setSelected((current) =>
      current.includes(id) ? current.filter((x) => x !== id) : [...current, id],
    );
  }

  function dataTerpilih() {
    return filtered.filter((item) => selected.includes(item.id));
  }

  async function hapusTerpilih() {
    if (!selected.length) return;
    setAksiTerbuka(false);
    try {
      await Promise.all(selected.map((id) => apiSend(`/kelompok/${id}`, "DELETE")));
      toast.success(`${selected.length} kelompok dihapus`);
      setSelected([]);
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menghapus data terpilih",
      );
    }
  }

  async function addAnggota() {
    if (!detailId || !pendingPenduduk) return;
    setAddingAnggota(true);
    try {
      await apiSend(`/kelompok/${detailId}/anggota`, "POST", {
        pendudukId: Number(pendingPenduduk),
        ...(pendingJabatan ? { jabatan: pendingJabatan } : {}),
      });
      toast.success("Anggota kelompok ditambahkan");
      setPendingPenduduk("");
      setPendingJabatan("Anggota");
      await mutateDetail();
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menambah anggota",
      );
    } finally {
      setAddingAnggota(false);
    }
  }

  async function removeAnggota(anggotaId: number) {
    if (!detailId) return;
    try {
      await apiSend(`/kelompok/${detailId}/anggota/${anggotaId}`, "DELETE");
      toast.success("Anggota dilepas dari kelompok");
      await mutateDetail();
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal melepas anggota",
      );
    }
  }

  function cetakAnggota(item: Kelompok) {
    const anggota = item.anggota ?? [];
    const isi = `
      ${kopDesa(desa, "Daftar Anggota Kelompok")}
      <table class="info">
        <tr><td>Nama Kelompok</td><td>:</td><td><strong>${escapeHtml(item.nama)}</strong></td></tr>
        <tr><td>Kategori</td><td>:</td><td>${escapeHtml(labelKategori(item.kategori))}</td></tr>
        <tr><td>Ketua</td><td>:</td><td>${escapeHtml(item.ketua ?? "-")}</td></tr>
        <tr><td>Tahun Berdiri</td><td>:</td><td>${escapeHtml(item.tahunBerdiri ?? "-")}</td></tr>
        <tr><td>Alamat</td><td>:</td><td>${escapeHtml(item.alamat ?? "-")}</td></tr>
      </table>
      <table>
        <thead><tr><th>No</th><th>Nama</th><th>NIK</th><th>L/P</th><th>Jabatan</th></tr></thead>
        <tbody>
          ${anggota
            .map(
              (row, index) =>
                `<tr><td class="num">${index + 1}</td><td>${escapeHtml(row.penduduk.nama)}</td><td>${escapeHtml(row.penduduk.nik)}</td><td>${row.penduduk.jenisKelamin === "L" ? "L" : "P"}</td><td>${escapeHtml(row.jabatan ?? "Anggota")}</td></tr>`,
            )
            .join("")}
        </tbody>
      </table>
      <div class="ttd">
        <div>
          <div>${escapeHtml((desa?.kecamatan ?? "Cipari").toUpperCase())}, ${new Date().toLocaleDateString("id-ID", { day: "2-digit", month: "long", year: "numeric" })}</div>
          <div>Kepala Desa ${escapeHtml((desa?.nama ?? "Mulyadadi").replace(/^Desa\s+/i, ""))}</div>
          <div class="ruang"></div>
          <div><strong>${escapeHtml(desa?.kepalaDesa ?? "-")}</strong></div>
        </div>
      </div>
    `;
    if (!cetakHtml(`Anggota ${item.nama}`, isi)) {
      toast.error("Izinkan pop-up untuk mencetak daftar anggota");
    }
  }

  function openCreate() {
    setEditing(null);
    setForm(emptyForm);
    setFormOpen(true);
  }

  function openEdit(item: Kelompok) {
    setEditing(item);
    setForm({
      kode: item.kode ?? "",
      nama: item.nama,
      kategori: item.kategori,
      ketua: item.ketua ?? "",
      jumlahAnggota: String(item.jumlahAnggota ?? 0),
      alamat: item.alamat ?? "",
      tahunBerdiri: item.tahunBerdiri ? String(item.tahunBerdiri) : "",
      keterangan: item.keterangan ?? "",
      aktif: item.aktif,
    });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const payload = {
        kode: form.kode.trim() || null,
        nama: form.nama,
        kategori: form.kategori,
        jumlahAnggota: Number(form.jumlahAnggota) || 0,
        aktif: form.aktif,
        ...(form.ketua ? { ketua: form.ketua } : {}),
        ...(form.alamat ? { alamat: form.alamat } : {}),
        ...(form.tahunBerdiri ? { tahunBerdiri: Number(form.tahunBerdiri) } : {}),
        ...(form.keterangan ? { keterangan: form.keterangan } : {}),
      };
      if (editing) {
        await apiSend(`/kelompok/${editing.id}`, "PATCH", payload);
        toast.success("Data kelompok diperbarui");
      } else {
        await apiSend("/kelompok", "POST", payload);
        toast.success("Kelompok ditambahkan");
      }
      setFormOpen(false);
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menyimpan data",
      );
    } finally {
      setSaving(false);
    }
  }

  async function remove() {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await apiSend(`/kelompok/${deleteTarget.id}`, "DELETE");
      toast.success("Kelompok dihapus");
      setDeleteTarget(null);
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menghapus data",
      );
    } finally {
      setDeleting(false);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Kelompok"
        description="Kelompok masyarakat desa seperti kelompok tani, peternak, UMKM, PKK, Karang Taruna, dan keagamaan."
        action={
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" onClick={() => cetakDaftar(filtered)}>
              <Printer className="h-4 w-4" />
              Cetak
            </Button>
            <Button variant="outline" onClick={() => unduh()}>
              <Download className="h-4 w-4" />
              Unduh
            </Button>
            {canMutate && (
              <div className="relative">
                <Button
                  variant="outline"
                  onClick={() => setAksiTerbuka((open) => !open)}
                  disabled={!selected.length}
                >
                  <SlidersHorizontal className="h-4 w-4" />
                  Pilih Aksi Lainnya
                  {selected.length > 0 && (
                    <span className="ml-1 rounded-full bg-white/25 px-1.5 text-xs">
                      {selected.length}
                    </span>
                  )}
                </Button>
                {aksiTerbuka && (
                  <div className="absolute right-0 z-20 mt-1 w-56 rounded-lg border bg-card p-1 shadow-lg">
                    <button
                      type="button"
                      className="block w-full rounded-md px-3 py-2 text-left text-sm hover:bg-muted"
                      onClick={() => {
                        setAksiTerbuka(false);
                        cetakDaftar(dataTerpilih(), "Daftar Kelompok Terpilih");
                      }}
                    >
                      Cetak Data Terpilih
                    </button>
                    <button
                      type="button"
                      className="block w-full rounded-md px-3 py-2 text-left text-sm hover:bg-muted"
                      onClick={() => {
                        setAksiTerbuka(false);
                        unduh(dataTerpilih());
                      }}
                    >
                      Unduh Data Terpilih
                    </button>
                    <button
                      type="button"
                      className="block w-full rounded-md px-3 py-2 text-left text-sm text-destructive hover:bg-muted"
                      onClick={hapusTerpilih}
                    >
                      Hapus Data Terpilih
                    </button>
                  </div>
                )}
              </div>
            )}
            <Button onClick={openCreate} disabled={!canMutate}>
              <Plus className="h-4 w-4" />
              Tambah Kelompok
            </Button>
          </div>
        }
      />

      <div className="grid gap-4 sm:grid-cols-3">
        <StatCard title="Total kelompok" value={daftar.length} icon={Layers} />
        <StatCard
          title="Kelompok aktif"
          value={daftar.filter((item) => item.aktif).length}
          icon={UserCheck}
          tone="sky"
        />
        <StatCard
          title="Total anggota"
          value={daftar.reduce((total, item) => total + item.jumlahAnggota, 0)}
          icon={Users}
          tone="amber"
        />
      </div>

      <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
        <div className="relative w-full lg:max-w-sm">
          <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
          <Input
            value={search}
            onChange={(event) => setSearch(event.target.value)}
            placeholder="Cari nama, ketua, kategori…"
            className="pl-9"
          />
        </div>
        <div className="flex flex-wrap gap-2">
          <Select
            value={kategoriFilter}
            onChange={(event) => setKategoriFilter(event.target.value)}
            aria-label="Filter kategori"
            className="w-full sm:w-44"
          >
            <option value="">Semua kategori</option>
            {KATEGORI_OPTIONS.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </Select>
          <Select
            value={statusFilter}
            onChange={(event) => setStatusFilter(event.target.value)}
            aria-label="Filter status"
            className="w-full sm:w-36"
          >
            <option value="">Semua status</option>
            <option value="aktif">Aktif</option>
            <option value="nonaktif">Nonaktif</option>
          </Select>
          {adaFilter && (
            <Button
              type="button"
              variant="ghost"
              onClick={() => {
                setSearch("");
                setKategoriFilter("");
                setStatusFilter("");
              }}
            >
              Bersihkan
            </Button>
          )}
        </div>
      </div>

      <Card>
        <CardContent className="p-5">
          <div className="overflow-x-auto">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-16">
                    <div className="flex items-center gap-2">
                      <input
                        type="checkbox"
                        checked={
                          filtered.length > 0 &&
                          filtered.every((item) => selected.includes(item.id))
                        }
                        onChange={toggleSemua}
                        disabled={!canMutate}
                        aria-label="Pilih semua kelompok"
                      />
                      <span>No</span>
                    </div>
                  </TableHead>
                  <TableHead>Aksi</TableHead>
                  <TableHead>Kode Kelompok</TableHead>
                  <TableHead>Nama Kelompok</TableHead>
                  <TableHead>Kategori Kelompok</TableHead>
                  <TableHead>Ketua Kelompok</TableHead>
                  <TableHead>Jumlah Anggota Kelompok</TableHead>
                  <TableHead className="hidden lg:table-cell">Alamat</TableHead>
                  <TableHead>Tahun Berdiri</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="hidden xl:table-cell">Keterangan</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {isLoading ? (
                  <TableRow>
                    <TableCell
                      colSpan={11}
                      className="py-10 text-center text-muted-foreground"
                    >
                      Memuat data…
                    </TableCell>
                  </TableRow>
                ) : filtered.length ? (
                  filtered.map((item, index) => (
                    <TableRow key={item.id}>
                      <TableCell>
                        <div className="flex items-center gap-2">
                          <input
                            type="checkbox"
                            checked={selected.includes(item.id)}
                            onChange={() => toggleSatu(item.id)}
                            disabled={!canMutate}
                            aria-label={`Pilih ${item.nama}`}
                          />
                          <span className="text-xs text-muted-foreground">
                            {index + 1}
                          </span>
                        </div>
                      </TableCell>
                      <TableCell>
                        <div className="flex gap-1">
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-8 w-8"
                            aria-label="Lihat anggota"
                            onClick={() => setDetailId(item.id)}
                          >
                            <Eye className="h-4 w-4" />
                          </Button>
                          {canMutate && (
                            <>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-8 w-8"
                                aria-label="Ubah"
                                onClick={() => openEdit(item)}
                              >
                                <FilePenLine className="h-4 w-4" />
                              </Button>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-8 w-8 text-destructive hover:text-destructive"
                                aria-label="Hapus"
                                onClick={() => setDeleteTarget(item)}
                              >
                                <Trash2 className="h-4 w-4" />
                              </Button>
                            </>
                          )}
                        </div>
                      </TableCell>
                      <TableCell className="font-mono text-xs">
                        {item.kode ?? "-"}
                      </TableCell>
                      <TableCell>
                        <button
                          type="button"
                          onClick={() => setDetailId(item.id)}
                          className="text-left font-medium hover:text-emerald-700 hover:underline"
                        >
                          {item.nama}
                        </button>
                      </TableCell>
                      <TableCell>{labelKategori(item.kategori)}</TableCell>
                      <TableCell>{item.ketua ?? "-"}</TableCell>
                      <TableCell>
                        <Badge variant="secondary">{item.jumlahAnggota} orang</Badge>
                      </TableCell>
                      <TableCell className="hidden lg:table-cell max-w-[220px] truncate">
                        {item.alamat ?? "-"}
                      </TableCell>
                      <TableCell>{item.tahunBerdiri ?? "-"}</TableCell>
                      <TableCell>
                        <Badge variant={item.aktif ? "success" : "secondary"}>
                          {item.aktif ? "Aktif" : "Nonaktif"}
                        </Badge>
                      </TableCell>
                      <TableCell className="hidden xl:table-cell max-w-[260px] truncate text-muted-foreground">
                        {item.keterangan ?? "-"}
                      </TableCell>
                    </TableRow>
                  ))
                ) : (
                  <TableRow>
                    <TableCell
                      colSpan={11}
                      className="py-12 text-center text-muted-foreground"
                    >
                      {search
                        ? "Tidak ada kelompok yang cocok dengan pencarian."
                        : "Belum ada data kelompok."}
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>{editing ? "Ubah Kelompok" : "Tambah Kelompok"}</DialogTitle>
            <DialogDescription>
              Catat identitas kelompok masyarakat beserta pengurus dan anggotanya.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-2">
              <Field label="Kode Kelompok">
                <Input
                  value={form.kode}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, kode: event.target.value }))
                  }
                  maxLength={20}
                  placeholder="TK-001"
                />
              </Field>
              <Field label="Nama Kelompok" required>
                <Input
                  required
                  value={form.nama}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, nama: event.target.value }))
                  }
                  placeholder="Kelompok Tani Sido Makmur"
                />
              </Field>
              <Field label="Kategori Kelompok">
                <Select
                  value={form.kategori}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      kategori: event.target.value as KategoriKelompok,
                    }))
                  }
                >
                  {KATEGORI_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
              </Field>
              <Field label="Ketua Kelompok">
                <Input
                  value={form.ketua}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, ketua: event.target.value }))
                  }
                />
              </Field>
              <Field label="Jumlah Anggota Kelompok">
                <Input
                  type="number"
                  min={0}
                  value={form.jumlahAnggota}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      jumlahAnggota: event.target.value,
                    }))
                  }
                />
              </Field>
              <Field label="Tahun Berdiri">
                <Input
                  type="number"
                  min={1900}
                  max={2100}
                  value={form.tahunBerdiri}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      tahunBerdiri: event.target.value,
                    }))
                  }
                  placeholder="2012"
                />
              </Field>
              <Field label="Alamat">
                <Input
                  value={form.alamat}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, alamat: event.target.value }))
                  }
                />
              </Field>
              <Field label="Keterangan" className="sm:col-span-2">
                <Textarea
                  rows={3}
                  value={form.keterangan}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      keterangan: event.target.value,
                    }))
                  }
                />
              </Field>
            </div>

            <label className="flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={form.aktif}
                onChange={(event) =>
                  setForm((current) => ({ ...current, aktif: event.target.checked }))
                }
                className="h-4 w-4 rounded border-input accent-emerald-600"
              />
              Kelompok aktif
            </label>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setFormOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : "Simpan"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={detailId !== null} onOpenChange={(open) => !open && setDetailId(null)}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>Anggota Kelompok</DialogTitle>
            <DialogDescription>
              {detail
                ? `${detail.nama} · ${labelKategori(detail.kategori)}`
                : "Memuat data kelompok…"}
            </DialogDescription>
          </DialogHeader>

          {!detail ? (
            <div className="space-y-2">
              {Array.from({ length: 4 }).map((_, index) => (
                <div key={index} className="h-10 animate-pulse rounded-lg bg-muted" />
              ))}
            </div>
          ) : (
            <div className="space-y-4">
              {canMutate && (
                <div className="grid gap-2 rounded-xl border bg-muted/40 p-3 sm:grid-cols-[1fr_auto_auto] sm:items-end">
                  <div className="space-y-1.5">
                    <Label>Tambah anggota</Label>
                    <Select
                      value={pendingPenduduk}
                      onChange={(event) => setPendingPenduduk(event.target.value)}
                    >
                      <option value="">Pilih penduduk</option>
                      {(pendudukList?.data ?? [])
                        .filter(
                          (warga) =>
                            !(detail.anggota ?? []).some(
                              (row) => row.penduduk.id === warga.id,
                            ),
                        )
                        .map((warga) => (
                          <option key={warga.id} value={warga.id}>
                            {warga.nama} · {warga.nik}
                          </option>
                        ))}
                    </Select>
                  </div>
                  <div className="space-y-1.5">
                    <Label>Jabatan</Label>
                    <Select
                      value={pendingJabatan}
                      onChange={(event) => setPendingJabatan(event.target.value)}
                    >
                      <option value="Ketua">Ketua</option>
                      <option value="Sekretaris">Sekretaris</option>
                      <option value="Bendahara">Bendahara</option>
                      <option value="Anggota">Anggota</option>
                    </Select>
                  </div>
                  <Button
                    type="button"
                    onClick={addAnggota}
                    disabled={!pendingPenduduk || addingAnggota}
                  >
                    <UserPlus className="h-4 w-4" />
                    {addingAnggota ? "Menambahkan…" : "Tambahkan"}
                  </Button>
                </div>
              )}

              {detail.anggota?.length ? (
                <div className="overflow-hidden rounded-lg border">
                  <Table>
                    <TableHeader>
                      <TableRow>
                        <TableHead>Nama</TableHead>
                        <TableHead>NIK</TableHead>
                        <TableHead>L/P</TableHead>
                        <TableHead>Jabatan</TableHead>
                        {canMutate && <TableHead className="w-10" />}
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {detail.anggota.map((row) => (
                        <TableRow key={row.id}>
                          <TableCell className="font-medium">
                            {row.penduduk.nama}
                          </TableCell>
                          <TableCell className="font-mono text-xs">
                            {row.penduduk.nik}
                          </TableCell>
                          <TableCell>{labelGender(row.penduduk.jenisKelamin)}</TableCell>
                          <TableCell>
                            <Badge variant="secondary">{row.jabatan ?? "Anggota"}</Badge>
                          </TableCell>
                          {canMutate && (
                            <TableCell>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-7 w-7 text-destructive hover:text-destructive"
                                aria-label="Lepas anggota"
                                onClick={() => removeAnggota(row.id)}
                              >
                                <X className="h-4 w-4" />
                              </Button>
                            </TableCell>
                          )}
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </div>
              ) : (
                <div className="rounded-xl border border-dashed p-8 text-center">
                  <Users className="mx-auto h-6 w-6 text-muted-foreground" />
                  <p className="mt-2 text-sm font-medium">Belum ada anggota</p>
                  <p className="text-xs text-muted-foreground">
                    Tambahkan penduduk melalui pilihan di atas.
                  </p>
                </div>
              )}
            </div>
          )}

          <DialogFooter>
            <Button variant="outline" onClick={() => setDetailId(null)}>
              Kembali Ke Daftar Kelompok
            </Button>
            {canMutate && (
              <Button
                variant="outline"
                disabled={!detail}
                onClick={() => {
                  if (!detail) return;
                  setDetailId(null);
                  openEdit(detail);
                }}
              >
                <FilePenLine className="h-4 w-4" />
                Ubah
              </Button>
            )}
            <Button onClick={() => detail && cetakAnggota(detail)} disabled={!detail}>
              <Printer className="h-4 w-4" />
              Cetak Daftar Anggota
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus kelompok?</DialogTitle>
            <DialogDescription>
              Kelompok <span className="font-semibold">{deleteTarget?.nama}</span> akan
              dihapus permanen.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Batal
            </Button>
            <Button variant="destructive" onClick={remove} disabled={deleting}>
              {deleting ? "Menghapus…" : "Hapus"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

function Field({
  label,
  required,
  className,
  children,
}: {
  label: string;
  required?: boolean;
  className?: string;
  children: React.ReactNode;
}) {
  return (
    <div className={`space-y-1.5 ${className ?? ""}`}>
      <Label>
        {label}
        {required && <span className="ml-0.5 text-destructive">*</span>}
      </Label>
      {children}
    </div>
  );
}
