"use client";

import { useMemo, useState } from "react";
import useSWR from "swr";
import {
  Download,
  Eye,
  FilePenLine,
  Home,
  Plus,
  Printer,
  Search,
  SlidersHorizontal,
  Trash2,
  UserPlus,
  Users,
  X,
} from "lucide-react";
import { toast } from "sonner";
import type {
  Desa,
  KlasifikasiRumahTangga,
  Paginated,
  Penduduk,
  RumahTangga,
  Wilayah,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { cetakHtml, escapeHtml, kopDesa } from "@/lib/cetak";
import { unduhCsv } from "@/lib/sekretariat";
import { formatDateShort, hitungUmur, labelGender, labelHubungan } from "@/lib/utils";
import { useSession } from "@/lib/use-session";
import { PageHeader, StatCard } from "@/components/page-header";
import { FotoPenduduk } from "@/components/admin/foto-penduduk";
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 KLASIFIKASI_OPTIONS: { value: KlasifikasiRumahTangga; label: string }[] = [
  { value: "PRASEJAHTERA", label: "Pra-Sejahtera" },
  { value: "KS1", label: "KS I" },
  { value: "KS2", label: "KS II" },
  { value: "KS3", label: "KS III" },
  { value: "KS3_PLUS", label: "KS III Plus" },
  { value: "LAINNYA", label: "Lainnya" },
];

type FormState = {
  nomor: string;
  kepalaNama: string;
  nikKepala: string;
  alamat: string;
  rtId: string;
  jumlahAnggota: string;
  terdaftarDtks: string;
  bdt: string;
  klasifikasi: string;
  keterangan: string;
  aktif: boolean;
};

const emptyForm: FormState = {
  nomor: "",
  kepalaNama: "",
  nikKepala: "",
  alamat: "",
  rtId: "",
  jumlahAnggota: "1",
  terdaftarDtks: "",
  bdt: "",
  klasifikasi: "",
  keterangan: "",
  aktif: true,
};

function labelKlasifikasi(value: string | null) {
  return (
    KLASIFIKASI_OPTIONS.find((option) => option.value === value)?.label ?? "-"
  );
}

// Kolom DTKS OpenSID menggabungkan status terdaftar DTKS dan BDT.
function labelDtks(item: RumahTangga) {
  if (item.terdaftarDtks && item.bdt) return "DTKS + BDT";
  if (item.terdaftarDtks) return "DTKS";
  if (item.bdt) return "BDT";
  if (item.terdaftarDtks === null && item.bdt === null) return "-";
  return "Tidak";
}

const KOLOM_RUMAH_TANGGA_CSV = [
  "Nomor Rumah Tangga",
  "Kepala Rumah Tangga",
  "NIK",
  "Terdaftar DTKS",
  "Terdaftar BDT",
  "Jumlah KK",
  "Klasifikasi",
  "Jumlah Anggota",
  "Alamat",
  "Dusun",
  "RW",
  "RT",
  "Status",
  "Tanggal Terdaftar",
];

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

  const { data, isLoading, mutate } = useSWR<RumahTangga[]>(
    "/rumah-tangga",
    fetcher,
  );
  const { data: wilayah } = useSWR<Wilayah[]>("/wilayah", fetcher);
  const { data: desa } = useSWR<Desa>("/desa", fetcher);
  const { data: pendudukList } = useSWR<Paginated<Penduduk>>(
    "/penduduk?limit=200",
    fetcher,
  );
  const daftar = data ?? [];
  const allRegional = wilayah ?? [];
  const rtOptions = allRegional.filter((item) => item.level === "RT");
  const dusunOptions = allRegional.filter((item) => item.level === "DUSUN");

  const [search, setSearch] = useState("");
  const [rtFilter, setRtFilter] = useState("");
  const [klasifikasiFilter, setKlasifikasiFilter] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [detailId, setDetailId] = useState<number | null>(null);
  const [pendingAnggota, setPendingAnggota] = useState("");
  const [addingAnggota, setAddingAnggota] = useState(false);
  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<RumahTangga | null>(null);
  const [form, setForm] = useState<FormState>(emptyForm);
  const [saving, setSaving] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<RumahTangga | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [selected, setSelected] = useState<number[]>([]);
  const [aksiTerbuka, setAksiTerbuka] = useState(false);
  const [mengunduh, setMengunduh] = useState(false);
  const [saringAlamat, setSaringAlamat] = useState({ dusunId: "", rwId: "" });

  function rantaiWilayah(rtKey: number | null | undefined) {
    const rt = allRegional.find((item) => item.id === rtKey);
    const rw = rt ? allRegional.find((item) => item.id === rt.parentId) : undefined;
    const dusun = rw ? allRegional.find((item) => item.id === rw.parentId) : undefined;
    return {
      dusunId: String(dusun?.id ?? ""),
      rwId: String(rw?.id ?? ""),
      dusun: dusun?.nama ?? "",
      rw: rw?.nama ?? "",
      rt: rt?.nama ?? "",
    };
  }

  const rwFormOptions = allRegional.filter(
    (item) =>
      item.level === "RW" &&
      (!saringAlamat.dusunId || item.parentId === Number(saringAlamat.dusunId)),
  );
  const rtFormOptions = rtOptions.filter(
    (item) => !saringAlamat.rwId || item.parentId === Number(saringAlamat.rwId),
  );

  function pilihRt(id: string) {
    setForm((current) => ({ ...current, rtId: id }));
    const wilayahItem = rantaiWilayah(Number(id) || null);
    setSaringAlamat({ dusunId: wilayahItem.dusunId, rwId: wilayahItem.rwId });
  }

  function barisRumahTanggaCsv(item: RumahTangga) {
    const wilayahItem = rantaiWilayah(item.rtId);
    return [
      item.nomor,
      item.kepalaNama,
      item.nikKepala ?? "",
      item.terdaftarDtks === null ? "" : item.terdaftarDtks ? "Ya" : "Tidak",
      item.bdt === null ? "" : item.bdt ? "Ya" : "Tidak",
      String(item.jumlahKk ?? 0),
      labelKlasifikasi(item.klasifikasi),
      String(item.jumlahAnggota),
      item.alamat ?? "",
      wilayahItem.dusun,
      wilayahItem.rw,
      wilayahItem.rt,
      item.aktif ? "Aktif" : "Nonaktif",
      item.createdAt ? formatDateShort(item.createdAt) : "",
    ];
  }

  function cetakDaftar(rows: RumahTangga[], judul = "Daftar Rumah Tangga") {
    if (!rows.length) {
      toast.error("Belum ada data untuk dicetak");
      return;
    }
    const isi = `
      ${kopDesa(desa, judul)}
      <table><thead><tr><th>No</th><th>Nomor RT</th><th>Kepala Rumah Tangga</th><th>NIK</th><th>DTKS</th><th>Jumlah KK</th><th>Anggota</th><th>Klasifikasi</th><th>Alamat</th><th>Dusun</th><th>RW</th><th>RT</th></tr></thead>
      <tbody>${rows
        .map((item, index) => {
          const wilayahItem = rantaiWilayah(item.rtId);
          return `<tr><td class="num">${index + 1}</td><td>${escapeHtml(item.nomor)}</td><td>${escapeHtml(item.kepalaNama)}</td><td>${escapeHtml(item.nikKepala ?? "-")}</td><td>${escapeHtml(labelDtks(item))}</td><td class="num">${item.jumlahKk ?? 0}</td><td class="num">${item.jumlahAnggota}</td><td>${escapeHtml(labelKlasifikasi(item.klasifikasi))}</td><td>${escapeHtml(item.alamat ?? "-")}</td><td>${escapeHtml(wilayahItem.dusun || "-")}</td><td>${escapeHtml(wilayahItem.rw || "-")}</td><td>${escapeHtml(wilayahItem.rt || "-")}</td></tr>`;
        })
        .join("")}</tbody></table>`;
    if (!cetakHtml(judul, isi)) {
      toast.error("Izinkan pop-up untuk mencetak");
    }
  }

  function unduh(rows: RumahTangga[] = filtered) {
    if (!rows.length) {
      toast.error("Belum ada data untuk diunduh");
      return;
    }
    setMengunduh(true);
    unduhCsv(
      `rumah-tangga-${new Date().toISOString().slice(0, 10)}.csv`,
      KOLOM_RUMAH_TANGGA_CSV,
      rows.map(barisRumahTanggaCsv),
    );
    toast.success(`${rows.length} rumah tangga diunduh`);
    setMengunduh(false);
  }

  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(`/rumah-tangga/${id}`, "DELETE")));
      toast.success(`${selected.length} rumah tangga dihapus`);
      setSelected([]);
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menghapus data terpilih",
      );
    }
  }

  const { data: detail, mutate: mutateDetail } = useSWR<RumahTangga>(
    detailId ? `/rumah-tangga/${detailId}` : null,
    fetcher,
  );

  const filtered = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    return daftar.filter((item) => {
      if (
        keyword &&
        ![item.nomor, item.kepalaNama, item.nikKepala, item.alamat]
          .filter(Boolean)
          .some((value) => String(value).toLowerCase().includes(keyword))
      ) {
        return false;
      }
      if (rtFilter && String(item.rtId ?? "") !== rtFilter) return false;
      if (klasifikasiFilter && item.klasifikasi !== klasifikasiFilter) return false;
      if (statusFilter === "aktif" && !item.aktif) return false;
      if (statusFilter === "nonaktif" && item.aktif) return false;
      return true;
    });
  }, [daftar, search, rtFilter, klasifikasiFilter, statusFilter]);

  const adaFilter = Boolean(search || rtFilter || klasifikasiFilter || statusFilter);

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

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

  function cetakKartu(item: RumahTangga) {
    const anggota = item.anggota ?? [];
    const wilayahItem = rantaiWilayah(item.rtId);
    const isi = `
      ${kopDesa(desa, "Kartu Rumah Tangga")}
      <table class="info">
        <tr><td>Nomor Rumah Tangga</td><td>:</td><td><strong>${escapeHtml(item.nomor)}</strong></td></tr>
        <tr><td>Kepala Rumah Tangga</td><td>:</td><td>${escapeHtml(item.kepalaNama)}</td></tr>
        <tr><td>NIK</td><td>:</td><td>${escapeHtml(item.nikKepala ?? "-")}</td></tr>
        <tr><td>Alamat Sekarang</td><td>:</td><td>${escapeHtml(item.alamat ?? "-")}</td></tr>
        <tr><td>Dusun</td><td>:</td><td>${escapeHtml(wilayahItem.dusun || "-")}</td></tr>
        <tr><td>RW</td><td>:</td><td>${escapeHtml(wilayahItem.rw || "-")}</td></tr>
        <tr><td>RT</td><td>:</td><td>${escapeHtml(wilayahItem.rt || item.rt?.nama || "-")}</td></tr>
        <tr><td>Klasifikasi</td><td>:</td><td>${escapeHtml(labelKlasifikasi(item.klasifikasi))}</td></tr>
        <tr><td>Jumlah Anggota</td><td>:</td><td>${anggota.length || item.jumlahAnggota} orang</td></tr>
      </table>
      <table>
        <thead><tr><th>No</th><th>Nama</th><th>NIK</th><th>L/P</th><th>Umur</th><th>Hubungan Dalam Keluarga</th></tr></thead>
        <tbody>
          ${anggota
            .map(
              (warga, index) =>
                `<tr><td class="num">${index + 1}</td><td>${escapeHtml(warga.nama)}</td><td>${escapeHtml(warga.nik)}</td><td>${warga.jenisKelamin === "L" ? "L" : "P"}</td><td class="num">${escapeHtml(hitungUmur(warga.tanggalLahir))}</td><td>${escapeHtml(labelHubungan(warga.hubunganKeluarga))}</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(`Kartu Rumah Tangga ${item.nomor}`, isi)) {
      toast.error("Izinkan pop-up untuk mencetak kartu rumah tangga");
    }
  }

  function openCreate() {
    setEditing(null);
    setForm(emptyForm);
    setSaringAlamat({ dusunId: "", rwId: "" });
    setFormOpen(true);
  }

  function openEdit(item: RumahTangga) {
    setEditing(item);
    setForm({
      nomor: item.nomor,
      kepalaNama: item.kepalaNama,
      nikKepala: item.nikKepala ?? "",
      alamat: item.alamat ?? "",
      rtId: item.rtId ? String(item.rtId) : "",
      jumlahAnggota: String(item.jumlahAnggota ?? 1),
      terdaftarDtks:
        item.terdaftarDtks === null || item.terdaftarDtks === undefined
          ? ""
          : item.terdaftarDtks
            ? "true"
            : "false",
      bdt:
        item.bdt === null || item.bdt === undefined
          ? ""
          : item.bdt
            ? "true"
            : "false",
      klasifikasi: item.klasifikasi ?? "",
      keterangan: item.keterangan ?? "",
      aktif: item.aktif,
    });
    const wilayahItem = rantaiWilayah(item.rtId);
    setSaringAlamat({ dusunId: wilayahItem.dusunId, rwId: wilayahItem.rwId });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const payload = {
        nomor: form.nomor,
        kepalaNama: form.kepalaNama,
        jumlahAnggota: Number(form.jumlahAnggota) || 0,
        aktif: form.aktif,
        terdaftarDtks: form.terdaftarDtks === "" ? null : form.terdaftarDtks === "true",
        bdt: form.bdt === "" ? null : form.bdt === "true",
        ...(form.nikKepala ? { nikKepala: form.nikKepala } : {}),
        ...(form.alamat ? { alamat: form.alamat } : {}),
        ...(form.rtId ? { rtId: Number(form.rtId) } : {}),
        ...(form.klasifikasi ? { klasifikasi: form.klasifikasi } : {}),
        ...(form.keterangan ? { keterangan: form.keterangan } : {}),
      };
      if (editing) {
        await apiSend(`/rumah-tangga/${editing.id}`, "PATCH", payload);
        toast.success("Rumah tangga diperbarui");
      } else {
        await apiSend("/rumah-tangga", "POST", payload);
        toast.success("Rumah tangga 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(`/rumah-tangga/${deleteTarget.id}`, "DELETE");
      toast.success("Rumah tangga 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="Rumah Tangga"
        description="Pendataan rumah tangga desa beserta kepala rumah tangga, klasifikasi kesejahteraan, dan wilayah RT."
        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()} disabled={mengunduh}>
              <Download className="h-4 w-4" />
              {mengunduh ? "Mengunduh…" : "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 Rumah Tangga 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 Rumah Tangga
            </Button>
          </div>
        }
      />

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

      <Card>
        <CardContent className="space-y-4 p-5">
          <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 nomor, kepala, NIK, alamat…"
                className="pl-9"
              />
            </div>
            <div className="flex flex-wrap gap-2">
              <Select
                value={rtFilter}
                onChange={(event) => setRtFilter(event.target.value)}
                aria-label="Filter RT"
                className="w-full sm:w-40"
              >
                <option value="">Semua RT</option>
                {rtOptions.map((rt) => (
                  <option key={rt.id} value={rt.id}>
                    {rt.nama}
                  </option>
                ))}
              </Select>
              <Select
                value={klasifikasiFilter}
                onChange={(event) => setKlasifikasiFilter(event.target.value)}
                aria-label="Filter klasifikasi"
                className="w-full sm:w-44"
              >
                <option value="">Semua klasifikasi</option>
                {KLASIFIKASI_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("");
                    setRtFilter("");
                    setKlasifikasiFilter("");
                    setStatusFilter("");
                  }}
                >
                  Reset
                </Button>
              )}
            </div>
          </div>

          <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 rumah tangga"
                      />
                      <span>No</span>
                    </div>
                  </TableHead>
                  <TableHead>Aksi</TableHead>
                  <TableHead className="w-20">Foto</TableHead>
                  <TableHead>Nomor Rumah Tangga</TableHead>
                  <TableHead>Kepala Rumah Tangga</TableHead>
                  <TableHead>NIK</TableHead>
                  <TableHead>DTKS</TableHead>
                  <TableHead>Jumlah KK</TableHead>
                  <TableHead>Klasifikasi</TableHead>
                  <TableHead>Jumlah Anggota</TableHead>
                  <TableHead className="hidden lg:table-cell">Alamat</TableHead>
                  <TableHead className="hidden xl:table-cell">Dusun</TableHead>
                  <TableHead className="hidden xl:table-cell">RW</TableHead>
                  <TableHead>RT</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="hidden xl:table-cell">Tanggal Terdaftar</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {isLoading ? (
                  <TableRow>
                    <TableCell colSpan={16} className="py-10 text-center text-muted-foreground">
                      Memuat data…
                    </TableCell>
                  </TableRow>
                ) : filtered.length ? (
                  filtered.map((item, index) => {
                    const wilayahItem = rantaiWilayah(item.rtId);
                    const warga = item.anggota ?? [];
                    const kepalaRt =
                      warga.find((row) => item.nikKepala && row.nik === item.nikKepala) ??
                      warga[0];
                    return (
                      <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.nomor}`}
                            />
                            <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>
                          <FotoPenduduk
                            pendudukId={kepalaRt?.id ?? null}
                            nama={item.kepalaNama}
                            adaFoto={Boolean(kepalaRt?.foto)}
                            versi={kepalaRt?.foto}
                          />
                        </TableCell>
                        <TableCell className="font-medium">{item.nomor}</TableCell>
                        <TableCell>
                          <button
                            type="button"
                            onClick={() => setDetailId(item.id)}
                            className="text-left font-medium hover:text-emerald-700 hover:underline"
                          >
                            {item.kepalaNama}
                          </button>
                        </TableCell>
                        <TableCell className="font-mono text-xs">
                          {item.nikKepala ?? "-"}
                        </TableCell>
                        <TableCell>
                          {item.terdaftarDtks || item.bdt ? (
                            <Badge variant="info">{labelDtks(item)}</Badge>
                          ) : (
                            <span className="text-xs text-muted-foreground">
                              {labelDtks(item)}
                            </span>
                          )}
                        </TableCell>
                        <TableCell>{item.jumlahKk ?? 0} KK</TableCell>
                        <TableCell>{labelKlasifikasi(item.klasifikasi)}</TableCell>
                        <TableCell>{item.jumlahAnggota} orang</TableCell>
                        <TableCell className="hidden lg:table-cell max-w-[200px] truncate">
                          {item.alamat ?? "-"}
                        </TableCell>
                        <TableCell className="hidden xl:table-cell">
                          {wilayahItem.dusun || "-"}
                        </TableCell>
                        <TableCell className="hidden xl:table-cell">
                          {wilayahItem.rw || "-"}
                        </TableCell>
                        <TableCell>{wilayahItem.rt || "-"}</TableCell>
                        <TableCell>
                          <Badge variant={item.aktif ? "success" : "secondary"}>
                            {item.aktif ? "Aktif" : "Nonaktif"}
                          </Badge>
                        </TableCell>
                        <TableCell className="hidden xl:table-cell text-muted-foreground">
                          {item.createdAt ? formatDateShort(item.createdAt) : "-"}
                        </TableCell>
                      </TableRow>
                    );
                  })
                ) : (
                  <TableRow>
                    <TableCell
                      colSpan={16}
                      className="py-12 text-center text-muted-foreground"
                    >
                      {search
                        ? "Tidak ada rumah tangga yang cocok dengan pencarian."
                        : "Belum ada data rumah tangga."}
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>
              {editing ? "Ubah Rumah Tangga" : "Tambah Rumah Tangga"}
            </DialogTitle>
            <DialogDescription>
              Catat identitas rumah tangga dan wilayah tempat tinggalnya.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-2">
              <Field label="Nomor Rumah Tangga" required>
                <Input
                  required
                  value={form.nomor}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, nomor: event.target.value }))
                  }
                  placeholder="RT-013"
                />
              </Field>
              <Field label="Kepala Rumah Tangga" required>
                <Input
                  required
                  value={form.kepalaNama}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      kepalaNama: event.target.value,
                    }))
                  }
                />
              </Field>
              <Field label="NIK">
                <Input
                  value={form.nikKepala}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      nikKepala: event.target.value,
                    }))
                  }
                  placeholder="16 digit"
                />
              </Field>
              <Field label="Jumlah Anggota">
                <Input
                  type="number"
                  min={0}
                  value={form.jumlahAnggota}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      jumlahAnggota: event.target.value,
                    }))
                  }
                />
              </Field>
              <Field label="Terdaftar DTKS">
                <Select
                  value={form.terdaftarDtks}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      terdaftarDtks: event.target.value,
                    }))
                  }
                >
                  <option value="">Belum diketahui</option>
                  <option value="true">Ya</option>
                  <option value="false">Tidak</option>
                </Select>
              </Field>
              <Field label="Terdaftar BDT">
                <Select
                  value={form.bdt}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      bdt: event.target.value,
                    }))
                  }
                >
                  <option value="">Belum diketahui</option>
                  <option value="true">Ya</option>
                  <option value="false">Tidak</option>
                </Select>
              </Field>
              <Field label="Klasifikasi">
                <Select
                  value={form.klasifikasi}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      klasifikasi: event.target.value,
                    }))
                  }
                >
                  <option value="">Belum ditentukan</option>
                  {KLASIFIKASI_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
              </Field>
              <Field label="Alamat Sekarang">
                <Input
                  value={form.alamat}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, alamat: event.target.value }))
                  }
                />
              </Field>
            </div>

            <div className="grid gap-4 sm:grid-cols-3">
              <Field label="Dusun">
                <Select
                  value={saringAlamat.dusunId}
                  onChange={(event) => {
                    setSaringAlamat({ dusunId: event.target.value, rwId: "" });
                    setForm((current) => ({ ...current, rtId: "" }));
                  }}
                >
                  <option value="">Pilih dusun</option>
                  {dusunOptions.map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.nama}
                    </option>
                  ))}
                </Select>
              </Field>
              <Field label="RW">
                <Select
                  value={saringAlamat.rwId}
                  onChange={(event) => {
                    setSaringAlamat((current) => ({ ...current, rwId: event.target.value }));
                    setForm((current) => ({ ...current, rtId: "" }));
                  }}
                >
                  <option value="">Pilih RW</option>
                  {rwFormOptions.map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.nama}
                    </option>
                  ))}
                </Select>
              </Field>
              <Field label="RT">
                <Select value={form.rtId} onChange={(event) => pilihRt(event.target.value)}>
                  <option value="">Pilih RT</option>
                  {rtFormOptions.map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.nama}
                    </option>
                  ))}
                </Select>
              </Field>
            </div>

            <Field label="Keterangan">
              <Textarea
                rows={3}
                value={form.keterangan}
                onChange={(event) =>
                  setForm((current) => ({
                    ...current,
                    keterangan: event.target.value,
                  }))
                }
              />
            </Field>

            <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"
              />
              Rumah tangga 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 Rumah Tangga</DialogTitle>
            <DialogDescription>
              {detail
                ? `${detail.nomor} · ${detail.kepalaNama} · ${labelKlasifikasi(detail.klasifikasi)}`
                : "Memuat data rumah tangga…"}
            </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="flex flex-col gap-2 rounded-xl border bg-muted/40 p-3 sm:flex-row sm:items-end">
                  <div className="flex-1 space-y-1.5">
                    <Label>Tambah anggota</Label>
                    <Select
                      value={pendingAnggota}
                      onChange={(event) => setPendingAnggota(event.target.value)}
                    >
                      <option value="">Pilih penduduk</option>
                      {(pendudukList?.data ?? [])
                        .filter(
                          (warga) =>
                            !(detail.anggota ?? []).some(
                              (anggota) => anggota.id === warga.id,
                            ),
                        )
                        .map((warga) => (
                          <option key={warga.id} value={warga.id}>
                            {warga.nama} · {warga.nik}
                          </option>
                        ))}
                    </Select>
                  </div>
                  <Button
                    type="button"
                    onClick={addAnggota}
                    disabled={!pendingAnggota || 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>Jenis Kelamin</TableHead>
                        <TableHead>Umur</TableHead>
                        <TableHead>Hubungan Dalam Keluarga</TableHead>
                        {canMutate && <TableHead className="w-10" />}
                      </TableRow>
                    </TableHeader>
                    <TableBody>
                      {detail.anggota.map((warga) => (
                        <TableRow key={warga.id}>
                          <TableCell className="font-medium">{warga.nama}</TableCell>
                          <TableCell className="font-mono text-xs">{warga.nik}</TableCell>
                          <TableCell>{labelGender(warga.jenisKelamin)}</TableCell>
                          <TableCell>{hitungUmur(warga.tanggalLahir)}</TableCell>
                          <TableCell className="text-muted-foreground">
                            {labelHubungan(warga.hubunganKeluarga)}
                          </TableCell>
                          {canMutate && (
                            <TableCell>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-7 w-7 text-destructive hover:text-destructive"
                                aria-label="Lepas anggota"
                                onClick={() => removeAnggota(warga.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 Rumah Tangga
            </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 && cetakKartu(detail)} disabled={!detail}>
              <Printer className="h-4 w-4" />
              Cetak Kartu RTM
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus rumah tangga?</DialogTitle>
            <DialogDescription>
              Rumah tangga{" "}
              <span className="font-semibold">{deleteTarget?.nomor}</span> ({deleteTarget?.kepalaNama}) 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>
  );
}
