"use client";

import { useState } from "react";
import useSWR from "swr";
import { Activity, Download, Home, Printer, RotateCcw, UserCheck, Users } from "lucide-react";
import type {
  Desa,
  RekapKelompok,
  StatistikKependudukan,
  Wilayah,
} from "@/lib/types";
import { fetcher } from "@/lib/api";
import { unduhCsv } from "@/lib/sekretariat";
import { PageHeader, StatCard } from "@/components/page-header";
import { AgeBar, ReligionDonut, RtBar, SexDonut } from "@/components/charts/population-charts";
import { BarList } from "@/components/charts/bar-list";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { formatDate, formatNumber, labelStatusDasar } from "@/lib/utils";

const KLASIFIKASI_LABELS: Record<string, string> = {
  PRASEJAHTERA: "Prasejahtera",
  KS1: "KS1",
  KS2: "KS2",
  KS3: "KS3",
  KS3_PLUS: "KS3+",
  LAINNYA: "Lainnya",
};

function strip(value: string | null | undefined, prefix: string) {
  if (!value) return "-";
  return value.replace(new RegExp(`^${prefix}\\s+`, "i"), "");
}

function desimal(value: number) {
  return new Intl.NumberFormat("id-ID", { maximumFractionDigits: 1 }).format(value);
}

const BLOK_REKAP: [keyof StatistikKependudukan["rekap"], string][] = [
  ["penduduk", "Statistik Penduduk"],
  ["keluarga", "Statistik Keluarga"],
  ["rtm", "Statistik Rumah Tangga"],
  ["bantuan", "Statistik Program Bantuan"],
];

export default function StatistikPage() {
  const [saring, setSaring] = useState({ dusunId: "", rwId: "", rtId: "" });
  const params = new URLSearchParams();
  for (const [key, value] of Object.entries(saring)) if (value) params.set(key, value);
  const { data, isLoading } = useSWR<StatistikKependudukan>(
    `/laporan/statistik${params.toString() ? `?${params.toString()}` : ""}`,
    fetcher,
  );
  const { data: desa } = useSWR<Desa>("/desa", fetcher);
  const { data: daftarWilayah } = useSWR<Wilayah[]>("/wilayah", fetcher);

  const namaDesa = strip(desa?.nama, "Desa");
  const kecamatan = strip(desa?.kecamatan, "Kecamatan");
  const kabupaten = strip(desa?.kabupaten, "Kabupaten");

  const regional = daftarWilayah ?? [];
  const pilihan = {
    dusunId: regional.filter((item) => item.level === "DUSUN"),
    rwId: regional.filter(
      (item) => item.level === "RW" && (!saring.dusunId || item.parentId === Number(saring.dusunId)),
    ),
    rtId: regional.filter(
      (item) => item.level === "RT" && (!saring.rwId || item.parentId === Number(saring.rwId)),
    ),
  };
  const adaSaringan = Boolean(saring.dusunId || saring.rwId || saring.rtId);

  function ubah(key: keyof typeof saring, value: string) {
    setSaring((sebelum) => ({
      ...sebelum,
      [key]: value,
      ...(key === "dusunId" ? { rwId: "", rtId: "" } : key === "rwId" ? { rtId: "" } : {}),
    }));
  }

  function unduh() {
    if (!data) return;
    unduhCsv(
      `statistik-kependudukan-${namaDesa}.csv`,
      ["Blok", "Jenis Kelompok", "Isian", "Laki-laki", "Perempuan", "Jumlah", "Persen"],
      barisRekapCsv(data.rekap),
    );
  }

  return (
    <div className="animate-fade-in space-y-6">
      <div className="no-print">
        <PageHeader
          title="Statistik Kependudukan"
          description="Indikator demografi Desa Mulyadadi: komposisi penduduk, usia, pendidikan, pekerjaan, agama, dan sebaran wilayah."
          action={
            <div className="flex flex-wrap gap-2">
              <Button variant="outline" onClick={unduh} disabled={!data}>
                <Download className="h-4 w-4" />
                Unduh CSV
              </Button>
              <Button onClick={() => window.print()}>
                <Printer className="h-4 w-4" />
                Cetak Statistik
              </Button>
            </div>
          }
        />

        <Card>
          <CardContent className="flex flex-wrap items-end gap-3 p-4">
            {(["dusunId", "rwId", "rtId"] as const).map((key) => (
              <div key={key} className="w-full sm:w-44">
                <Label htmlFor={key}>
                  {key === "dusunId" ? "Dusun" : key === "rwId" ? "RW" : "RT"}
                </Label>
                <Select
                  id={key}
                  className="mt-1.5"
                  value={saring[key]}
                  onChange={(event) => ubah(key, event.target.value)}
                >
                  <option value="">
                    {key === "dusunId" ? "Semua dusun" : key === "rwId" ? "Semua RW" : "Semua RT"}
                  </option>
                  {pilihan[key].map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.nama}
                    </option>
                  ))}
                </Select>
              </div>
            ))}
            {adaSaringan && (
              <Button variant="ghost" onClick={() => setSaring({ dusunId: "", rwId: "", rtId: "" })}>
                <RotateCcw className="h-4 w-4" />
                Reset
              </Button>
            )}
          </CardContent>
        </Card>
      </div>

      <div className="hidden print:block">
        <div className="border-b-2 border-black pb-2 text-center">
          <p className="text-sm font-semibold uppercase">
            Pemerintah Kabupaten {kabupaten} · Kecamatan {kecamatan}
          </p>
          <p className="text-xl font-bold uppercase">Desa {namaDesa}</p>
          <p className="mt-1 text-sm font-semibold">Statistik Kependudukan</p>
          <p className="text-xs">Dicetak {formatDate(new Date())}</p>
        </div>
      </div>

      {isLoading || !data ? (
        <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
          {Array.from({ length: 4 }).map((_, index) => (
            <div key={index} className="h-28 animate-pulse rounded-xl bg-muted" />
          ))}
        </div>
      ) : (
        <>
          <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            <StatCard
              title="Penduduk aktif"
              value={formatNumber(data.ringkasan.penduduk)}
              hint={`${formatNumber(data.ringkasan.rumahTangga)} rumah tangga`}
              icon={Users}
            />
            <StatCard
              title="Kartu keluarga"
              value={formatNumber(data.ringkasan.keluarga)}
              hint={`${formatNumber(data.ringkasan.lakiLaki)} L · ${formatNumber(data.ringkasan.perempuan)} P`}
              icon={Home}
              tone="sky"
            />
            <StatCard
              title="Rasio jenis kelamin"
              value={desimal(data.ringkasan.rasioJenisKelamin)}
              hint="Laki-laki per 100 perempuan"
              icon={UserCheck}
              tone="amber"
            />
            <StatCard
              title="Rasio ketergantungan"
              value={desimal(data.ringkasan.rasioKetergantungan)}
              hint="Usia non-produktif per 100 produktif"
              icon={Activity}
              tone="violet"
            />
          </div>

          <Card>
            <CardHeader>
              <CardTitle>Indikator Usia</CardTitle>
            </CardHeader>
            <CardContent className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
              {[
                { label: "Usia 0–14 tahun", value: data.ringkasan.usiaAnak },
                { label: "Usia produktif 15–64", value: data.ringkasan.usiaProduktif },
                { label: "Usia 65 tahun ke atas", value: data.ringkasan.usiaLansia },
                { label: "Rumah tangga", value: data.ringkasan.rumahTangga },
              ].map((item) => (
                <div key={item.label} className="rounded-xl bg-secondary/50 p-4">
                  <p className="text-xs font-medium uppercase tracking-wide text-muted-foreground">
                    {item.label}
                  </p>
                  <p className="mt-1.5 text-2xl font-bold tabular-nums">
                    {formatNumber(item.value)}
                  </p>
                </div>
              ))}
            </CardContent>
          </Card>

          <div className="grid gap-4 lg:grid-cols-2">
            <Card>
              <CardHeader>
                <CardTitle>Komposisi Jenis Kelamin</CardTitle>
              </CardHeader>
              <CardContent>
                <SexDonut
                  data={[
                    { name: "Laki-laki", value: data.ringkasan.lakiLaki },
                    { name: "Perempuan", value: data.ringkasan.perempuan },
                  ]}
                />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Piramida Kelompok Umur (5 tahun)</CardTitle>
              </CardHeader>
              <CardContent>
                <AgeBar data={data.byUmur5} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Komposisi Agama</CardTitle>
              </CardHeader>
              <CardContent>
                <ReligionDonut data={data.byAgama} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Sebaran Menurut RT</CardTitle>
              </CardHeader>
              <CardContent>
                <RtBar data={data.byRt} />
              </CardContent>
            </Card>
          </div>

          <div className="grid gap-4 lg:grid-cols-2">
            <Card>
              <CardHeader>
                <CardTitle>Kelompok Umur</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList data={data.byUmur} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Pendidikan Terakhir</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList data={data.byPendidikan} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Pekerjaan</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList data={data.byPekerjaan} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Status Perkawinan</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList data={data.byStatusKawin} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Klasifikasi Rumah Tangga</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList
                  data={data.byKlasifikasiRt}
                  labels={(value) => KLASIFIKASI_LABELS[value] ?? value}
                />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Golongan Darah</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList data={data.byGolonganDarah} />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Status Dasar Penduduk</CardTitle>
              </CardHeader>
              <CardContent>
                <BarList data={data.ringkasan.statusDasar} labels={labelStatusDasar} />
              </CardContent>
            </Card>
          </div>

          <div className="space-y-4">
            {BLOK_REKAP.map(([key, judul]) => (
              <RekapBagian key={key} judul={judul} daftar={data.rekap[key]} />
            ))}
          </div>

          <p className="text-xs text-muted-foreground">
            Sumber data: basis data kependudukan desa. Penduduk aktif adalah warga dengan
            status dasar hidup; rasio dihitung terhadap penduduk yang tanggal lahirnya terisi.
            Rekap dihitung dari seluruh isian penduduk aktif pada wilayah yang disaring.
          </p>
        </>
      )}
    </div>
  );
}

function barisRekapCsv(rekap: StatistikKependudukan["rekap"]) {
  const rows: (string | number | null)[][] = [];
  for (const [key, blok] of BLOK_REKAP) {
    for (const grup of rekap[key]) {
      const isi = grup.belumMengisi ? [...grup.baris, grup.belumMengisi] : grup.baris;
      for (const baris of isi) {
        rows.push([
          blok,
          grup.kategori,
          baris.nama,
          baris.lakiLaki ?? "",
          baris.perempuan ?? "",
          baris.jumlah,
          baris.persen,
        ]);
      }
      if (!isi.length) rows.push([blok, grup.kategori, "Belum ada data isian", "", "", 0, 0]);
      rows.push([blok, grup.kategori, "JUMLAH", "", "", grup.total, 100]);
    }
  }
  return rows;
}

function RekapBagian({ judul, daftar }: { judul: string; daftar: RekapKelompok[] }) {
  return (
    <Card>
      <CardHeader>
        <CardTitle>{judul}</CardTitle>
      </CardHeader>
      <CardContent className="grid gap-4 xl:grid-cols-2">
        {daftar.map((grup) => (
          <RekapGrup key={grup.kategori} grup={grup} />
        ))}
      </CardContent>
    </Card>
  );
}

function RekapGrup({ grup }: { grup: RekapKelompok }) {
  const jk = grup.adaJenisKelamin;
  const lakiLaki = grup.baris.reduce((total, baris) => total + (baris.lakiLaki ?? 0), 0);
  const perempuan = grup.baris.reduce((total, baris) => total + (baris.perempuan ?? 0), 0);
  const barisKosong = !grup.baris.length && !grup.belumMengisi;

  return (
    <div className="overflow-hidden rounded-xl border">
      <div className="flex items-center justify-between gap-2 bg-muted/50 px-3 py-2">
        <p className="text-sm font-semibold">{grup.kategori}</p>
        <p className="text-xs tabular-nums text-muted-foreground">
          {formatNumber(grup.total)} total
        </p>
      </div>
      <div className="overflow-x-auto">
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead className="w-10">No</TableHead>
              <TableHead>Isian</TableHead>
              {jk && <TableHead className="text-right">L</TableHead>}
              {jk && <TableHead className="text-right">P</TableHead>}
              <TableHead className="text-right">Jumlah</TableHead>
              <TableHead className="text-right">Persen</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {grup.baris.map((baris, index) => (
              <TableRow key={baris.nama}>
                <TableCell className="text-muted-foreground">{index + 1}</TableCell>
                <TableCell className="font-medium">{baris.nama}</TableCell>
                {jk && (
                  <TableCell className="text-right tabular-nums">
                    {formatNumber(baris.lakiLaki ?? 0)}
                  </TableCell>
                )}
                {jk && (
                  <TableCell className="text-right tabular-nums">
                    {formatNumber(baris.perempuan ?? 0)}
                  </TableCell>
                )}
                <TableCell className="text-right tabular-nums">{formatNumber(baris.jumlah)}</TableCell>
                <TableCell className="text-right tabular-nums">{desimal(baris.persen)}%</TableCell>
              </TableRow>
            ))}
            {grup.belumMengisi && (
              <TableRow className="bg-muted/30">
                <TableCell className="text-muted-foreground">
                  {grup.baris.length + 1}
                </TableCell>
                <TableCell className="font-medium text-muted-foreground">
                  {grup.belumMengisi.nama}
                </TableCell>
                {jk && (
                  <TableCell className="text-right tabular-nums">
                    {formatNumber(grup.belumMengisi.lakiLaki ?? 0)}
                  </TableCell>
                )}
                {jk && (
                  <TableCell className="text-right tabular-nums">
                    {formatNumber(grup.belumMengisi.perempuan ?? 0)}
                  </TableCell>
                )}
                <TableCell className="text-right tabular-nums">
                  {formatNumber(grup.belumMengisi.jumlah)}
                </TableCell>
                <TableCell className="text-right tabular-nums">
                  {desimal(grup.belumMengisi.persen)}%
                </TableCell>
              </TableRow>
            )}
            {barisKosong && (
              <TableRow>
                <TableCell colSpan={jk ? 6 : 4} className="text-sm text-muted-foreground">
                  Belum ada data isian pada kelompok ini.
                </TableCell>
              </TableRow>
            )}
            <TableRow className="border-t-2 font-semibold">
              <TableCell colSpan={jk ? 2 : 1}>JUMLAH</TableCell>
              {jk && <TableCell className="text-right tabular-nums">{formatNumber(lakiLaki)}</TableCell>}
              {jk && (
                <TableCell className="text-right tabular-nums">{formatNumber(perempuan)}</TableCell>
              )}
              <TableCell className="text-right tabular-nums">{formatNumber(grup.total)}</TableCell>
              <TableCell className="text-right tabular-nums">100%</TableCell>
            </TableRow>
          </TableBody>
        </Table>
      </div>
    </div>
  );
}
