"use client";

import { useMemo, useState } from "react";
import { useParams } from "next/navigation";
import useSWR from "swr";
import type { Paginated, Penduduk } from "@/lib/types";
import { fetcher } from "@/lib/api";
import { formatDateShort } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { Select } from "@/components/ui/select";
import { StuntingNav } from "@/components/admin/stunting-nav";
import {
  SimpleCrud,
  type CrudColumn,
  type CrudField,
  type CrudRow,
} from "@/components/admin/simple-crud";

type Jenis = "ibu-hamil" | "anak" | "paud";

type KiaRingkas = {
  noKia?: string;
  perkiraanLahir?: string | null;
  ibu?: { nama?: string; tanggalLahir?: string | null };
  anak?: { nama?: string; jenisKelamin?: string; tanggalLahir?: string | null };
};

function kia(row: CrudRow): KiaRingkas {
  return (row.kia ?? {}) as KiaRingkas;
}

function totalIndikator(row: CrudRow, keys: string[]) {
  return keys.filter((key) => Boolean(row[key])).length;
}

function indikatorBadge(row: CrudRow, keys: string[], label: string) {
  const total = totalIndikator(row, keys);
  const lengkap = total === keys.length;
  return (
    <Badge variant={lengkap ? "success" : "secondary"}>
      {total}/{keys.length} {label}
    </Badge>
  );
}

const INDIKATOR_IBU = [
  "periksaKehamilan",
  "konsumsiPilFe",
  "periksaNifas",
  "konselingGizi",
  "kunjunganRumah",
  "airBersih",
  "jamban",
  "jaminanKesehatan",
];

const INDIKATOR_ANAK = [
  "imunisasiDasar",
  "pengukuranBerat",
  "pengukuranTinggi",
  "konselingGiziAyah",
  "konselingGiziIbu",
  "kunjunganRumah",
  "airBersih",
  "jamban",
  "aktaLahir",
  "jaminanKesehatan",
  "pengasuhanPaud",
];

const BULAN = [
  "Januari",
  "Februari",
  "Maret",
  "April",
  "Mei",
  "Juni",
  "Juli",
  "Agustus",
  "September",
  "Oktober",
  "November",
  "Desember",
];

const FIELDS_IBU: CrudField[] = [
  { name: "kiaId", label: "No Register KIA", type: "select", optionsKey: "kia", required: true, full: true },
  { name: "tanggalPeriksa", label: "Tanggal Periksa", type: "date", required: true },
  { name: "posyandu", label: "Posyandu", type: "select", optionsKey: "posyandu" },
  {
    name: "statusKehamilan",
    label: "Status Kehamilan",
    type: "select",
    options: [
      { value: "Normal (N)", label: "Normal (N)" },
      { value: "Risiko Tinggi (Risti)", label: "Risiko Tinggi (Risti)" },
      { value: "Kekurangan Energi Kronis (KEK)", label: "Kekurangan Energi Kronis (KEK)" },
    ],
  },
  { name: "usiaKehamilan", label: "Usia Kehamilan (Bulan)", type: "number" },
  { name: "tanggalMelahirkan", label: "Tanggal Melahirkan", type: "date" },
  { name: "butirPilFe", label: "Berapa butir pil Fe", type: "number" },
  { name: "periksaKehamilan", label: "Pemeriksaan Kehamilan", type: "checkbox" },
  { name: "konsumsiPilFe", label: "Dapat & Konsumsi Pil Fe", type: "checkbox" },
  { name: "periksaNifas", label: "Pemeriksaan Nifas", type: "checkbox" },
  { name: "konselingGizi", label: "Konseling Gizi (Kelas IH)", type: "checkbox" },
  { name: "kunjunganRumah", label: "Kunjungan Rumah", type: "checkbox" },
  { name: "airBersih", label: "Kepemilikan Akses Air Bersih", type: "checkbox" },
  { name: "jamban", label: "Kepemilikan Jamban", type: "checkbox" },
  { name: "jaminanKesehatan", label: "Jaminan Kesehatan", type: "checkbox" },
];

const KOLOM_IBU: CrudColumn[] = [
  { name: "noKia", label: "No KIA", render: (row) => kia(row).noKia ?? "-" },
  { name: "namaIbu", label: "Nama Ibu", render: (row) => kia(row).ibu?.nama ?? "-" },
  {
    name: "tanggalPeriksa",
    label: "Tanggal Periksa",
    render: (row) => (row.tanggalPeriksa ? formatDateShort(String(row.tanggalPeriksa)) : "-"),
  },
  { name: "statusKehamilan", label: "Status Kehamilan" },
  {
    name: "hpl",
    label: "Hari Perkiraan Lahir",
    render: (row) =>
      kia(row).perkiraanLahir ? formatDateShort(String(kia(row).perkiraanLahir)) : "-",
  },
  {
    name: "usiaPersalinan",
    label: "Usia Kehamilan dan Persalinan",
    render: (row) =>
      `${row.usiaKehamilan ? `${row.usiaKehamilan} bln` : "-"}${
        row.tanggalMelahirkan
          ? ` / ${formatDateShort(String(row.tanggalMelahirkan))}`
          : ""
      }`,
  },
  {
    name: "penerimaan",
    label: "Status Penerimaan Indikator",
    render: (row) => indikatorBadge(row, INDIKATOR_IBU, "indikator"),
  },
  { name: "usiaKehamilan", label: "Usia Kehamilan (Bulan)" },
  {
    name: "tanggalMelahirkan",
    label: "Tanggal Melahirkan",
    render: (row) => (row.tanggalMelahirkan ? formatDateShort(String(row.tanggalMelahirkan)) : "-"),
  },
  { name: "periksaKehamilan", label: "Pemeriksaan Kehamilan" },
  { name: "konsumsiPilFe", label: "Dapat & Konsumsi Pil Fe" },
  { name: "periksaNifas", label: "Pemeriksaan Nifas" },
  { name: "konselingGizi", label: "Konseling Gizi (Kelas IH)" },
  { name: "kunjunganRumah", label: "Kunjungan Rumah" },
  { name: "airBersih", label: "Kepemilikan Akses Air Bersih" },
  { name: "jamban", label: "Kepemilikan Jamban" },
  { name: "jaminanKesehatan", label: "Jaminan Kesehatan" },
];

const FIELDS_ANAK: CrudField[] = [
  { name: "kiaId", label: "No Register KIA", type: "select", optionsKey: "kia", required: true, full: true },
  { name: "tanggalPeriksa", label: "Tanggal Periksa", type: "date", required: true },
  { name: "posyandu", label: "Posyandu", type: "select", optionsKey: "posyandu" },
  {
    name: "statusGizi",
    label: "Status Gizi Anak",
    type: "select",
    options: [
      { value: "Sehat / Normal (N)", label: "Sehat / Normal (N)" },
      { value: "Gizi Kurang (GK)", label: "Gizi Kurang (GK)" },
      { value: "Gizi Buruk (GB)", label: "Gizi Buruk (GB)" },
      { value: "Stunting (S)", label: "Stunting (S)" },
    ],
  },
  { name: "umur", label: "Umur" },
  { name: "umurBulan", label: "Umur (Bulan)", type: "number" },
  {
    name: "statusTikar",
    label: "Hasil Status Tikar",
    type: "select",
    options: [
      { value: "Tidak Diukur (TD)", label: "Tidak Diukur (TD)" },
      { value: "Merah (M)", label: "Merah (M)" },
      { value: "Kuning (K)", label: "Kuning (K)" },
      { value: "Hijau (H)", label: "Hijau (H)" },
    ],
  },
  {
    name: "imunisasiCampak",
    label: "Imunisasi Campak",
    type: "select",
    options: [
      { value: "Belum", label: "Belum" },
      { value: "Sudah", label: "Sudah" },
    ],
  },
  { name: "beratBadan", label: "Berat Badan (kg)", type: "number" },
  { name: "tinggiBadan", label: "Tinggi Badan (cm)", type: "number" },
  { name: "keterangan", label: "Keterangan", type: "textarea" },
  { name: "imunisasiDasar", label: "Imunisasi Dasar", type: "checkbox" },
  { name: "pengukuranBerat", label: "Pengukuran Berat Badan", type: "checkbox" },
  { name: "pengukuranTinggi", label: "Pengukuran Tinggi Badan", type: "checkbox" },
  { name: "konselingGiziAyah", label: "Konseling Gizi Ayah", type: "checkbox" },
  { name: "konselingGiziIbu", label: "Konseling Gizi Ibu", type: "checkbox" },
  { name: "kunjunganRumah", label: "Kunjungan Rumah", type: "checkbox" },
  { name: "airBersih", label: "Kepemilikan Akses Air Bersih", type: "checkbox" },
  { name: "jamban", label: "Kepemilikan Jamban Sehat", type: "checkbox" },
  { name: "aktaLahir", label: "Akta Lahir", type: "checkbox" },
  { name: "jaminanKesehatan", label: "Jaminan Kesehatan", type: "checkbox" },
  { name: "pengasuhanPaud", label: "Pengasuhan (PAUD)", type: "checkbox" },
];

const KOLOM_ANAK: CrudColumn[] = [
  { name: "noKia", label: "No KIA", render: (row) => kia(row).noKia ?? "-" },
  { name: "namaAnak", label: "Nama Anak", render: (row) => kia(row).anak?.nama ?? "-" },
  {
    name: "tanggalPeriksa",
    label: "Tanggal Periksa",
    render: (row) => (row.tanggalPeriksa ? formatDateShort(String(row.tanggalPeriksa)) : "-"),
  },
  { name: "jenisKelamin", label: "Jenis Kelamin", render: (row) => kia(row).anak?.jenisKelamin ?? "-" },
  {
    name: "tanggalLahir",
    label: "Tanggal Lahir Anak",
    render: (row) =>
      kia(row).anak?.tanggalLahir ? formatDateShort(String(kia(row).anak?.tanggalLahir)) : "-",
  },
  { name: "statusGizi", label: "Status Gizi Anak" },
  { name: "beratBadan", label: "Berat Badan Anak" },
  { name: "tinggiBadan", label: "Tinggi Badan Anak" },
  { name: "keterangan", label: "Keterangan" },
  {
    name: "umurTikar",
    label: "Umur dan Status Tikar",
    render: (row) => `${row.umur ?? "-"} / ${row.statusTikar ?? "-"}`,
  },
  {
    name: "indikator",
    label: "Indikator Layanan",
    render: (row) => indikatorBadge(row, INDIKATOR_ANAK, "layanan"),
  },
  { name: "umurBulan", label: "Umur (Bulan)" },
  { name: "statusTikar", label: "Hasil (M/K/H)" },
  { name: "imunisasiDasar", label: "Pemberian Imunisasi Dasar" },
  { name: "pengukuranBerat", label: "Pengukuran Berat Badan" },
  { name: "pengukuranTinggi", label: "Pengukuran Tinggi Badan" },
  { name: "konselingGiziAyah", label: "Konseling Gizi Ayah" },
  { name: "konselingGiziIbu", label: "Konseling Gizi Ibu" },
  { name: "kunjunganRumah", label: "Kunjungan Rumah" },
  { name: "airBersih", label: "Kepemilikan Akses Air Bersih" },
  { name: "jamban", label: "Kepemilikan Jamban Sehat" },
  { name: "aktaLahir", label: "Akta Lahir" },
  { name: "jaminanKesehatan", label: "Jaminan Kesehatan" },
  { name: "pengasuhanPaud", label: "Pengasuhan (PAUD)" },
];

const STATUS_PAUD = [
  { value: "Belum", label: "Belum" },
  { value: "Mengikuti", label: "Mengikuti" },
  { value: "Tidak Mengikuti", label: "Tidak Mengikuti" },
];

const FIELDS_PAUD: CrudField[] = [
  { name: "kiaId", label: "No Register KIA", type: "select", optionsKey: "kia", required: true, full: true },
  { name: "tanggalPeriksa", label: "Tanggal Periksa", type: "date", required: true },
  { name: "posyandu", label: "Posyandu", type: "select", optionsKey: "posyandu" },
  {
    name: "kategoriUsia",
    label: "Kategori Usia",
    type: "select",
    options: [
      { value: "Anak Usia 2 - < 3 Tahun", label: "Anak Usia 2 - < 3 Tahun" },
      { value: "Anak Usia 3 - 6 Tahun", label: "Anak Usia 3 - 6 Tahun" },
    ],
  },
  { name: "parenting", label: "Parenting (2 - < 3 Tahun)", type: "checkbox" },
  { name: "kelasPaud", label: "Kelas PAUD (3 - 6 Tahun)", type: "checkbox" },
  ...BULAN.map((nama) => ({
    name: nama.toLowerCase(),
    label: nama,
    type: "select" as const,
    options: STATUS_PAUD,
  })),
];

const KOLOM_PAUD: CrudColumn[] = [
  { name: "noKia", label: "No KIA", render: (row) => kia(row).noKia ?? "-" },
  { name: "namaAnak", label: "Nama Anak", render: (row) => kia(row).anak?.nama ?? "-" },
  {
    name: "tanggalPeriksa",
    label: "Tanggal Periksa",
    render: (row) => (row.tanggalPeriksa ? formatDateShort(String(row.tanggalPeriksa)) : "-"),
  },
  { name: "jenisKelamin", label: "Jenis Kelamin", render: (row) => kia(row).anak?.jenisKelamin ?? "-" },
  { name: "kategoriUsia", label: "Usia Menurut Kategori" },
  {
    name: "layanan",
    label:
      "Mengikuti Layanan PAUD (Parenting bagi Orang Tua Anak Usia 2 - < 3 Tahun) atau Kelas PAUD bagi Anak 3 - 6 Tahun",
    render: (row) =>
      row.kategoriUsia === "Anak Usia 2 - < 3 Tahun"
        ? row.parenting
          ? "Parenting"
          : "Belum"
        : row.kelasPaud
          ? "Kelas PAUD"
          : "Belum",
  },
  {
    name: "usia23",
    label: "Anak Usia 2 - < 3 Tahun",
    render: (row) => (row.parenting ? <Badge variant="success">Ya</Badge> : "-"),
  },
  {
    name: "usia36",
    label: "Anak Usia 3 - 6 Tahun",
    render: (row) => (row.kelasPaud ? <Badge variant="success">Ya</Badge> : "-"),
  },
  ...BULAN.map((nama) => ({
    name: nama.toLowerCase(),
    label: nama,
    render: (row: CrudRow) => {
      const value = String(row[nama.toLowerCase()] ?? "");
      if (!value) return "-";
      return (
        <Badge variant={value === "Mengikuti" ? "success" : "secondary"}>
          {value}
        </Badge>
      );
    },
  })),
];

const CONFIG: Record<
  Jenis,
  {
    entity: string;
    title: string;
    description: string;
    fields: CrudField[];
    columns: CrudColumn[];
    fileName: string;
  }
> = {
  "ibu-hamil": {
    entity: "kia-ibu-hamil",
    title: "Stunting Bulanan Ibu Hamil",
    description: "Pemantauan bulanan ibu hamil dari posyandu desa.",
    fields: FIELDS_IBU,
    columns: KOLOM_IBU,
    fileName: "pemantauan-ibu-hamil",
  },
  anak: {
    entity: "kia-anak",
    title: "Stunting Bulanan Anak",
    description: "Pemantauan bulanan anak usia 0-2 tahun.",
    fields: FIELDS_ANAK,
    columns: KOLOM_ANAK,
    fileName: "pemantauan-anak",
  },
  paud: {
    entity: "kia-paud",
    title: "Stunting Sasaran Paud Anak",
    description: "Pemantauan kehadiran layanan PAUD anak usia 2-6 tahun.",
    fields: FIELDS_PAUD,
    columns: KOLOM_PAUD,
    fileName: "pemantauan-paud",
  },
};

function nilaiEkspor(row: CrudRow, column: CrudColumn): string {
  const data = kia(row);
  switch (column.name) {
    case "noKia":
      return data.noKia ?? "";
    case "namaIbu":
      return data.ibu?.nama ?? "";
    case "namaAnak":
      return data.anak?.nama ?? "";
    case "jenisKelamin":
      return data.anak?.jenisKelamin ?? "";
    case "tanggalLahir":
      return String(data.anak?.tanggalLahir ?? "").slice(0, 10);
    case "hpl":
      return String(data.perkiraanLahir ?? "").slice(0, 10);
    case "usiaPersalinan":
      return `${row.usiaKehamilan ?? ""}${
        row.tanggalMelahirkan
          ? ` / ${String(row.tanggalMelahirkan).slice(0, 10)}`
          : ""
      }`.trim();
    case "penerimaan":
      return `${totalIndikator(row, INDIKATOR_IBU)}/8`;
    case "indikator":
      return `${totalIndikator(row, INDIKATOR_ANAK)}/11`;
    case "umurTikar":
      return `${row.umur ?? ""} / ${row.statusTikar ?? ""}`;
    case "layanan":
      return row.kategoriUsia === "Anak Usia 2 - < 3 Tahun"
        ? row.parenting
          ? "Parenting"
          : "Belum"
        : row.kelasPaud
          ? "Kelas PAUD"
          : "Belum";
    case "usia23":
      return row.parenting ? "Ya" : "";
    case "usia36":
      return row.kelasPaud ? "Ya" : "";
    default: {
      const value = row[column.name];
      if (typeof value === "boolean") return value ? "Ya" : "Tidak";
      return String(value ?? "");
    }
  }
}

export default function PemantauanStuntingPage() {
  const params = useParams();
  const jenis = String(params.jenis ?? "ibu-hamil") as Jenis;
  const config = CONFIG[jenis] ?? CONFIG["ibu-hamil"];

  const { data: kiaList } = useSWR<CrudRow[]>("/master/kia", fetcher);
  const { data: posyandu } = useSWR<CrudRow[]>("/master/posyandu", fetcher);
  const { data: penduduk } = useSWR<Paginated<Penduduk>>("/penduduk?limit=200", fetcher);
  const daftarKia = kiaList ?? [];
  const daftarPosyandu = posyandu ?? [];
  const daftarPenduduk = penduduk?.data ?? [];

  const sekarang = new Date();
  const [bulan, setBulan] = useState(String(sekarang.getMonth() + 1));
  const [tahun, setTahun] = useState(String(sekarang.getFullYear()));
  const [posyanduFilter, setPosyanduFilter] = useState("");

  const tahunList = useMemo(() => {
    const years = new Set<number>([sekarang.getFullYear()]);
    for (let index = 0; index < 6; index += 1) years.add(sekarang.getFullYear() - index);
    return [...years].sort((a, b) => b - a);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  function labelKia(row: CrudRow) {
    const data = kia(row);
    return `${data.noKia ?? "-"} — ${data.anak?.nama ?? data.ibu?.nama ?? ""}`;
  }

  const options = {
    kia: daftarKia.map((row) => ({
      value: String(row.id),
      label: labelKia(row),
    })),
    posyandu: daftarPosyandu.map((row) => ({
      value: String(row.nama ?? ""),
      label: String(row.nama ?? ""),
    })),
  };

  return (
    <div className="space-y-5">
      <StuntingNav active={`/admin/kesehatan/stunting/pemantauan/${jenis}`} />
      <SimpleCrud
        title={config.title}
        description={config.description}
        entity={config.entity}
        fields={config.fields}
        columns={config.columns}
        searchPlaceholder="Cari nama, nomor KIA, atau posyandu…"
        createLabel="Tambah"
        showNo
        selectable
        actionOnLeft
        canWrite
        options={options}
        filter={(row) => {
          if (bulan || tahun) {
            if (!row.tanggalPeriksa) return false;
            const date = new Date(String(row.tanggalPeriksa));
            if (Number.isNaN(date.getTime())) return false;
            if (bulan && date.getMonth() + 1 !== Number(bulan)) return false;
            if (tahun && date.getFullYear() !== Number(tahun)) return false;
          }
          if (posyanduFilter && String(row.posyandu ?? "") !== posyanduFilter) return false;
          return true;
        }}
        toolbar={
          <>
            <Select
              value={bulan}
              onChange={(event) => setBulan(event.target.value)}
              aria-label="Pilih Bulan"
              className="w-full sm:w-36"
            >
              <option value="">-- Pilih Bulan --</option>
              {BULAN.map((nama, index) => (
                <option key={nama} value={String(index + 1)}>
                  {nama}
                </option>
              ))}
            </Select>
            <Select
              value={tahun}
              onChange={(event) => setTahun(event.target.value)}
              aria-label="Pilih Tahun"
              className="w-full sm:w-28"
            >
              <option value="">-- Pilih Tahun --</option>
              {tahunList.map((item) => (
                <option key={item} value={String(item)}>
                  {item}
                </option>
              ))}
            </Select>
            <Select
              value={posyanduFilter}
              onChange={(event) => setPosyanduFilter(event.target.value)}
              aria-label="Pilih Posyandu"
              className="w-full sm:w-44"
            >
              <option value="">-- Pilih Posyandu --</option>
              {daftarPosyandu.map((row) => (
                <option key={String(row.id)} value={String(row.nama ?? "")}>
                  {String(row.nama ?? "")}
                </option>
              ))}
            </Select>
          </>
        }
        ekspor={{
          fileName: config.fileName,
          header: config.columns.map((column) => column.label),
          values: (row) => config.columns.map((column) => nilaiEkspor(row, column)),
        }}
        cetak={(rows) => ({
          judul: config.title,
          isi: `
            <table>
              <thead><tr><th>No</th>${config.columns
                .map((column) => `<th>${column.label}</th>`)
                .join("")}</tr></thead>
              <tbody>
                ${rows
                  .map((row, index) => {
                    const data = kia(row);
                    const cells: string[] = [];
                    for (const column of config.columns) {
                      if (column.name === "noKia") cells.push(String(data.noKia ?? "-"));
                      else if (column.name === "namaIbu") cells.push(String(data.ibu?.nama ?? "-"));
                      else if (column.name === "namaAnak") cells.push(String(data.anak?.nama ?? "-"));
                      else {
                        const value = row[column.name];
                        cells.push(
                          typeof value === "boolean"
                            ? value
                              ? "Ya"
                              : "Tidak"
                            : String(value ?? "-"),
                        );
                      }
                    }
                    return `<tr><td class="num">${index + 1}</td>${cells
                      .map((cell) => `<td>${cell}</td>`)
                      .join("")}</tr>`;
                  })
                  .join("")}
              </tbody>
            </table>
          `,
        })}
      />
    </div>
  );
}
