"use client";

import { useEffect, useMemo, useState } from "react";
import useSWR from "swr";
import { Download, Info } from "lucide-react";
import { toast } from "sonner";
import { fetcher } from "@/lib/api";
import { unduhCsv } from "@/lib/sekretariat";
import { formatDateShort } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { PageHeader } from "@/components/page-header";
import { StuntingNav } from "@/components/admin/stunting-nav";
import type { CrudRow } from "@/components/admin/simple-crud";

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

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

const TAB: { value: Jenis; label: string }[] = [
  { value: "ibu-hamil", label: "Bulanan Ibu Hamil" },
  { value: "anak", label: "Bulanan Anak 0-2 Tahun" },
  { value: "paud", label: "Bulanan Anak 2-6 Tahun" },
];

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

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

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",
];

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

function persen(nilai: number, total: number) {
  return total ? Math.round((nilai / total) * 1000) / 10 : 0;
}

function ya(value: unknown) {
  return value ? <Badge variant="success">Ya</Badge> : <Badge variant="secondary">Tidak</Badge>;
}

function periksaTanggal(row: CrudRow, awal: string, akhir: string, tahun: string) {
  if (!row.tanggalPeriksa) return false;
  const date = new Date(String(row.tanggalPeriksa));
  if (Number.isNaN(date.getTime())) return false;
  const bulan = date.getMonth() + 1;
  if (tahun && date.getFullYear() !== Number(tahun)) return false;
  if (awal && bulan < Number(awal)) return false;
  if (akhir && bulan > Number(akhir)) return false;
  return true;
}

export default function RekapitulasiStuntingPage() {
  const [jenis, setJenis] = useState<Jenis>("ibu-hamil");
  useEffect(() => {
    const param = new URLSearchParams(window.location.search).get("jenis");
    if (param === "ibu-hamil" || param === "anak" || param === "paud") setJenis(param);
  }, []);

  const sekarang = new Date();
  const [awal, setAwal] = useState("1");
  const [akhir, setAkhir] = useState(String(sekarang.getMonth() + 1));
  const [tahun, setTahun] = useState(String(sekarang.getFullYear()));
  const [posyandu, setPosyandu] = useState("");
  const [panduan, setPanduan] = useState(false);

  const { data: ibuHamil } = useSWR<CrudRow[]>("/master/kia-ibu-hamil", fetcher);
  const { data: anak } = useSWR<CrudRow[]>("/master/kia-anak", fetcher);
  const { data: paud } = useSWR<CrudRow[]>("/master/kia-paud", fetcher);
  const { data: posyanduList } = useSWR<CrudRow[]>("/master/posyandu", fetcher);

  const sumber = jenis === "ibu-hamil" ? ibuHamil : jenis === "anak" ? anak : paud;

  const rows = useMemo(
    () =>
      (sumber ?? []).filter(
        (row) =>
          periksaTanggal(row, awal, akhir, tahun) &&
          (!posyandu || String(row.posyandu ?? "") === posyandu),
      ),
    [sumber, awal, akhir, tahun, posyandu],
  );

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

  function ekspor() {
    if (!rows.length) {
      toast.error("Tidak ada data untuk diekspor");
      return;
    }
    const header =
      jenis === "ibu-hamil"
        ? ["No", "No KIA", "Nama Ibu", "Status Kehamilan", "Usia Kehamilan", "Tanggal Melahirkan", "Diterima", "Seharusnya", "%"]
        : jenis === "anak"
          ? ["No", "No KIA", "Nama Anak", "Jenis Kelamin", "Umur (Bulan)", "Status Gizi", "Diterima", "Seharusnya", "%"]
          : ["No", "No KIA", "Nama Anak", "Kategori Usia", "2-<3 Tahun", "3-6 Tahun", "Status Bulan Ini"];
    const values = rows.map((row, index) => {
      const data = kia(row);
      if (jenis === "ibu-hamil") {
        const total = diterima(row, INDIKATOR_IBU);
        return [
          index + 1,
          data.noKia ?? "",
          data.ibu?.nama ?? "",
          String(row.statusKehamilan ?? ""),
          String(row.usiaKehamilan ?? ""),
          String(row.tanggalMelahirkan ?? "").slice(0, 10),
          total,
          INDIKATOR_IBU.length,
          persen(total, INDIKATOR_IBU.length),
        ].map(String);
      }
      if (jenis === "anak") {
        const total = diterima(row, INDIKATOR_ANAK);
        return [
          index + 1,
          data.noKia ?? "",
          data.anak?.nama ?? "",
          data.anak?.jenisKelamin ?? "",
          String(row.umurBulan ?? ""),
          String(row.statusGizi ?? ""),
          total,
          INDIKATOR_ANAK.length,
          persen(total, INDIKATOR_ANAK.length),
        ].map(String);
      }
      return [
        index + 1,
        data.noKia ?? "",
        data.anak?.nama ?? "",
        String(row.kategoriUsia ?? ""),
        row.parenting ? "Ya" : "Tidak",
        row.kelasPaud ? "Ya" : "Tidak",
        String(row[BULAN[sekarang.getMonth()].toLowerCase()] ?? ""),
      ].map(String);
    });
    unduhCsv(`rekapitulasi-${jenis}`, header, values);
    toast.success(`${rows.length} data diekspor`);
  }

  return (
    <div className="space-y-5">
      <StuntingNav active="rekapitulasi" />
      <PageHeader
        title="Rekapitulasi Stunting"
        description="Rekapitulasi bulanan pemantauan ibu hamil, anak, dan layanan PAUD."
        action={
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" onClick={() => setPanduan(true)}>
              <Info className="h-4 w-4" />
              Panduan Lengkap
            </Button>
            <Button variant="outline" onClick={ekspor}>
              <Download className="h-4 w-4" />
              Ekspor ke excel
            </Button>
          </div>
        }
      />

      <div className="flex flex-wrap gap-2">
        {TAB.map((item) => (
          <Button
            key={item.value}
            variant={jenis === item.value ? "default" : "outline"}
            size="sm"
            onClick={() => setJenis(item.value)}
          >
            {item.label}
          </Button>
        ))}
      </div>

      <Card>
        <CardContent className="space-y-4 p-4">
          <div className="flex flex-col gap-3 sm:flex-row sm:items-end">
            <div className="space-y-1.5">
              <Label htmlFor="awal-bulan">Awal Bulan</Label>
              <Select
                id="awal-bulan"
                value={awal}
                onChange={(event) => setAwal(event.target.value)}
                className="w-40"
              >
                {BULAN.map((nama, index) => (
                  <option key={nama} value={String(index + 1)}>
                    {nama}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="akhir-bulan">Akhir Bulan</Label>
              <Select
                id="akhir-bulan"
                value={akhir}
                onChange={(event) => setAkhir(event.target.value)}
                className="w-40"
              >
                {BULAN.map((nama, index) => (
                  <option key={nama} value={String(index + 1)}>
                    {nama}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="tahun">Tahun</Label>
              <Select
                id="tahun"
                value={tahun}
                onChange={(event) => setTahun(event.target.value)}
                className="w-28"
              >
                {tahunOptions.map((item) => (
                  <option key={item} value={String(item)}>
                    {item}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="posyandu">Posyandu</Label>
              <Select
                id="posyandu"
                value={posyandu}
                onChange={(event) => setPosyandu(event.target.value)}
                className="w-48"
              >
                <option value="">-- Semua Posyandu --</option>
                {(posyanduList ?? []).map((row) => (
                  <option key={String(row.id)} value={String(row.nama ?? "")}>
                    {String(row.nama ?? "")}
                  </option>
                ))}
              </Select>
            </div>
          </div>

          <div className="overflow-x-auto rounded-lg border">
            {jenis === "ibu-hamil" ? (
              <Table>
                <TableHeader>
                  <TableRow>
                    {[
                      "No",
                      "No KIA",
                      "Nama Ibu",
                      "Status Kehamilan",
                      "Usia Kehamilan dan Persalinan",
                      "Status Penerimaan Indikator",
                      "Tingkat Konvergensi Indikator",
                      "Usia (Bulan)",
                      "Tanggal Melahirkan",
                      "Periksa Kehamilan",
                      "Pil Fe",
                      "Periksa Nifas",
                      "Konseling Gizi",
                      "Kunjungan Rumah",
                      "Air Bersih",
                      "Jamban",
                      "Jaminan Kesehatan",
                      "Diterima",
                      "Seharusnya",
                      "%",
                    ].map((label) => (
                      <TableHead key={label}>{label}</TableHead>
                    ))}
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rows.map((row, index) => {
                    const data = kia(row);
                    const total = diterima(row, INDIKATOR_IBU);
                    return (
                      <TableRow key={String(row.id)}>
                        <TableCell>{index + 1}</TableCell>
                        <TableCell>{data.noKia ?? "-"}</TableCell>
                        <TableCell className="font-medium">{data.ibu?.nama ?? "-"}</TableCell>
                        <TableCell>{String(row.statusKehamilan ?? "-")}</TableCell>
                        <TableCell>
                          {row.usiaKehamilan ? `${row.usiaKehamilan} bln` : "-"}
                          {row.tanggalMelahirkan
                            ? ` / ${formatDateShort(String(row.tanggalMelahirkan))}`
                            : ""}
                        </TableCell>
                        <TableCell>
                          <Badge variant={total === INDIKATOR_IBU.length ? "success" : "secondary"}>
                            {total}/{INDIKATOR_IBU.length}
                          </Badge>
                        </TableCell>
                        <TableCell>{persen(total, INDIKATOR_IBU.length)}%</TableCell>
                        <TableCell>{String(row.usiaKehamilan ?? "-")}</TableCell>
                        <TableCell>
                          {row.tanggalMelahirkan
                            ? formatDateShort(String(row.tanggalMelahirkan))
                            : "-"}
                        </TableCell>
                        <TableCell>{ya(row.periksaKehamilan)}</TableCell>
                        <TableCell>{ya(row.konsumsiPilFe)}</TableCell>
                        <TableCell>{ya(row.periksaNifas)}</TableCell>
                        <TableCell>{ya(row.konselingGizi)}</TableCell>
                        <TableCell>{ya(row.kunjunganRumah)}</TableCell>
                        <TableCell>{ya(row.airBersih)}</TableCell>
                        <TableCell>{ya(row.jamban)}</TableCell>
                        <TableCell>{ya(row.jaminanKesehatan)}</TableCell>
                        <TableCell>{total}</TableCell>
                        <TableCell>{INDIKATOR_IBU.length}</TableCell>
                        <TableCell>{persen(total, INDIKATOR_IBU.length)}%</TableCell>
                      </TableRow>
                    );
                  })}
                  {!rows.length && (
                    <TableRow>
                      <TableCell colSpan={20} className="py-8 text-center text-muted-foreground">
                        Belum ada data rekapitulasi pada periode ini.
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            ) : jenis === "anak" ? (
              <Table>
                <TableHeader>
                  <TableRow>
                    {[
                      "No",
                      "No KIA",
                      "Nama Anak",
                      "Jenis Kelamin",
                      "Profil Anak",
                      "Indikator Layanan Kesehatan & Pengasuhan",
                      "Tingkat Konvergensi Indikator",
                      "Umur & Kategori",
                      "Status Gizi",
                      "Imunisasi",
                      "Berat Badan",
                      "Tinggi Badan",
                      "Konseling Gizi",
                      "Kunjungan Rumah",
                      "Air Bersih",
                      "Jamban",
                      "Akta Lahir",
                      "Jaminan Kesehatan",
                      "Pengasuhan (PAUD)",
                      "Diterima",
                      "Seharusnya",
                      "%",
                    ].map((label) => (
                      <TableHead key={label}>{label}</TableHead>
                    ))}
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rows.map((row, index) => {
                    const data = kia(row);
                    const total = diterima(row, INDIKATOR_ANAK);
                    return (
                      <TableRow key={String(row.id)}>
                        <TableCell>{index + 1}</TableCell>
                        <TableCell>{data.noKia ?? "-"}</TableCell>
                        <TableCell className="font-medium">{data.anak?.nama ?? "-"}</TableCell>
                        <TableCell>{data.anak?.jenisKelamin ?? "-"}</TableCell>
                        <TableCell>
                          {data.anak?.tanggalLahir
                            ? formatDateShort(String(data.anak.tanggalLahir))
                            : "-"}
                        </TableCell>
                        <TableCell>
                          <Badge variant={total === INDIKATOR_ANAK.length ? "success" : "secondary"}>
                            {total}/{INDIKATOR_ANAK.length}
                          </Badge>
                        </TableCell>
                        <TableCell>{persen(total, INDIKATOR_ANAK.length)}%</TableCell>
                        <TableCell>
                          {row.umur ? String(row.umur) : "-"}
                          {row.umurBulan ? ` (${String(row.umurBulan)} bln)` : ""}
                        </TableCell>
                        <TableCell>{String(row.statusGizi ?? "-")}</TableCell>
                        <TableCell>{String(row.imunisasiCampak ?? "-")}</TableCell>
                        <TableCell>{row.beratBadan ? `${row.beratBadan} kg` : "-"}</TableCell>
                        <TableCell>{row.tinggiBadan ? `${row.tinggiBadan} cm` : "-"}</TableCell>
                        <TableCell>{ya(row.konselingGiziAyah || row.konselingGiziIbu)}</TableCell>
                        <TableCell>{ya(row.kunjunganRumah)}</TableCell>
                        <TableCell>{ya(row.airBersih)}</TableCell>
                        <TableCell>{ya(row.jamban)}</TableCell>
                        <TableCell>{ya(row.aktaLahir)}</TableCell>
                        <TableCell>{ya(row.jaminanKesehatan)}</TableCell>
                        <TableCell>{ya(row.pengasuhanPaud)}</TableCell>
                        <TableCell>{total}</TableCell>
                        <TableCell>{INDIKATOR_ANAK.length}</TableCell>
                        <TableCell>{persen(total, INDIKATOR_ANAK.length)}%</TableCell>
                      </TableRow>
                    );
                  })}
                  {!rows.length && (
                    <TableRow>
                      <TableCell colSpan={22} className="py-8 text-center text-muted-foreground">
                        Belum ada data rekapitulasi pada periode ini.
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            ) : (
              <Table>
                <TableHeader>
                  <TableRow>
                    {[
                      "No",
                      "No KIA",
                      "Nama Anak",
                      "Jenis Kelamin",
                      "Kategori Usia PAUD",
                      "Status Kehadiran Layanan PAUD per Bulan",
                      "2 - < 3 Tahun (Parenting)",
                      "3 - 6 Tahun (Kelas PAUD)",
                      BULAN[sekarang.getMonth()],
                    ].map((label) => (
                      <TableHead key={label}>{label}</TableHead>
                    ))}
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rows.map((row, index) => {
                    const data = kia(row);
                    const statusBulan = String(row[BULAN[sekarang.getMonth()].toLowerCase()] ?? "");
                    return (
                      <TableRow key={String(row.id)}>
                        <TableCell>{index + 1}</TableCell>
                        <TableCell>{data.noKia ?? "-"}</TableCell>
                        <TableCell className="font-medium">{data.anak?.nama ?? "-"}</TableCell>
                        <TableCell>{data.anak?.jenisKelamin ?? "-"}</TableCell>
                        <TableCell>{String(row.kategoriUsia ?? "-")}</TableCell>
                        <TableCell>{statusBulan || "-"}</TableCell>
                        <TableCell>{row.parenting ? "Ya" : "-"}</TableCell>
                        <TableCell>{row.kelasPaud ? "Ya" : "-"}</TableCell>
                        <TableCell>
                          {statusBulan ? (
                            <Badge variant={statusBulan === "Mengikuti" ? "success" : "secondary"}>
                              {statusBulan}
                            </Badge>
                          ) : (
                            "-"
                          )}
                        </TableCell>
                      </TableRow>
                    );
                  })}
                  {!rows.length && (
                    <TableRow>
                      <TableCell colSpan={9} className="py-8 text-center text-muted-foreground">
                        Belum ada data rekapitulasi pada periode ini.
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            )}
          </div>
        </CardContent>
      </Card>

      <Dialog open={panduan} onOpenChange={setPanduan}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>Panduan Rekapitulasi</DialogTitle>
            <DialogDescription>
              Panduan membaca indikator konvergensi pencegahan stunting.
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-2 text-sm text-muted-foreground">
            <p>
              <strong className="text-foreground">Diterima</strong> adalah jumlah
              indikator layanan yang terpenuhi pada satu catatan pemeriksaan.
            </p>
            <p>
              <strong className="text-foreground">Seharusnya</strong> adalah jumlah
              indikator minimal yang harus diterima sesuai kategori sasaran.
            </p>
            <p>
              <strong className="text-foreground">Persentase</strong> dihitung dari
              perbandingan keduanya.
            </p>
          </div>
          <DialogFooter>
            <Button onClick={() => setPanduan(false)}>Tutup</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
