"use client";

import { useEffect, useState } from "react";
import useSWR from "swr";
import {
  Activity,
  CalendarRange,
  CloudDownload,
  ListChecks,
  Pencil,
  Plus,
  Target,
  Trash2,
  TrendingUp,
} from "lucide-react";
import {
  CartesianGrid,
  Cell,
  Legend,
  Line,
  LineChart,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { toast } from "sonner";
import type { StatusDesa, StatusDesaIndikator, StatusIdm } from "@/lib/types";
import { ApiError, apiGet, apiSend, fetcher } from "@/lib/api";
import { useSession } from "@/lib/use-session";
import { PageHeader, StatCard } from "@/components/page-header";
import { SdgsPanel } from "@/components/admin/sdgs-panel";
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 { 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";
import { cn } from "@/lib/utils";

const STATUS_OPTIONS: { value: StatusIdm; label: string; badge: string }[] = [
  { value: "TERTINGGAL", label: "Tertinggal", badge: "danger" },
  { value: "BERKEMBANG", label: "Berkembang", badge: "warning" },
  { value: "MAJU", label: "Maju", badge: "info" },
  { value: "MANDIRI", label: "Mandiri", badge: "success" },
];

const badgeVariant = (status: StatusIdm) =>
  (STATUS_OPTIONS.find((option) => option.value === status)?.badge ??
    "secondary") as "danger" | "warning" | "info" | "success" | "secondary";

const statusLabel = (status: StatusIdm | null) =>
  STATUS_OPTIONS.find((option) => option.value === status)?.label ?? "-";

type FormState = {
  tahun: string;
  status: StatusIdm;
  skorIdm: string;
  skorSosial: string;
  skorEkonomi: string;
  skorEkologi: string;
  targetStatus: StatusIdm | "";
  keterangan: string;
};

const emptyForm: FormState = {
  tahun: String(new Date().getFullYear()),
  status: "BERKEMBANG",
  skorIdm: "",
  skorSosial: "",
  skorEkonomi: "",
  skorEkologi: "",
  targetStatus: "",
  keterangan: "",
};

type StatusDesaTab = "idm" | "sdgs";

export default function StatusDesaPage() {
  const { user } = useSession();
  const isAdmin = user?.role === "ADMIN";
  const [tab, setTab] = useState<StatusDesaTab>("idm");

  useEffect(() => {
    const param = new URLSearchParams(window.location.search).get("tab");
    if (param === "sdgs") setTab("sdgs");
  }, []);

  function pilihTab(next: StatusDesaTab) {
    setTab(next);
    window.history.replaceState(
      null,
      "",
      next === "sdgs" ? "?tab=sdgs" : window.location.pathname,
    );
  }

  const { data, isLoading, mutate } = useSWR<StatusDesa[]>(
    "/status-desa",
    fetcher,
  );
  const daftar = data ?? [];
  const terbaru = daftar[0];

  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<StatusDesa | null>(null);
  const [form, setForm] = useState<FormState>(emptyForm);
  const [saving, setSaving] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<StatusDesa | null>(null);
  const [deleting, setDeleting] = useState(false);
  const [syncOpen, setSyncOpen] = useState(false);
  const [syncYear, setSyncYear] = useState(String(new Date().getFullYear()));
  const [syncing, setSyncing] = useState(false);
  const [detail, setDetail] = useState<{
    tahun: number;
    rows: StatusDesaIndikator[];
  } | null>(null);
  const [detailLoadingId, setDetailLoadingId] = useState<number | null>(null);
  const [selectedYear, setSelectedYear] = useState("");

  const hasDetail = daftar.some((item) => (item._count?.indikator ?? 0) > 0);
  const tahunAktif =
    daftar.find((item) => String(item.tahun) === selectedYear) ??
    terbaru;

  const chartData = [...daftar]
    .sort((a, b) => a.tahun - b.tahun)
    .map((item) => ({
      tahun: item.tahun,
      idm: Number((item.skorIdm * 100).toFixed(2)),
      sosial: item.skorSosial != null ? Number((item.skorSosial * 100).toFixed(2)) : null,
      ekonomi: item.skorEkonomi != null ? Number((item.skorEkonomi * 100).toFixed(2)) : null,
      ekologi: item.skorEkologi != null ? Number((item.skorEkologi * 100).toFixed(2)) : null,
    }));

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

  function openEdit(item: StatusDesa) {
    setEditing(item);
    setForm({
      tahun: String(item.tahun),
      status: item.status,
      skorIdm: String(item.skorIdm),
      skorSosial: item.skorSosial != null ? String(item.skorSosial) : "",
      skorEkonomi: item.skorEkonomi != null ? String(item.skorEkonomi) : "",
      skorEkologi: item.skorEkologi != null ? String(item.skorEkologi) : "",
      targetStatus: item.targetStatus ?? "",
      keterangan: item.keterangan ?? "",
    });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const payload = {
        tahun: Number(form.tahun),
        status: form.status,
        skorIdm: Number(form.skorIdm),
        ...(form.skorSosial ? { skorSosial: Number(form.skorSosial) } : {}),
        ...(form.skorEkonomi ? { skorEkonomi: Number(form.skorEkonomi) } : {}),
        ...(form.skorEkologi ? { skorEkologi: Number(form.skorEkologi) } : {}),
        ...(form.targetStatus ? { targetStatus: form.targetStatus } : {}),
        ...(form.keterangan ? { keterangan: form.keterangan } : {}),
      };
      if (editing) {
        await apiSend(`/status-desa/${editing.id}`, "PATCH", payload);
        toast.success("Status desa diperbarui");
      } else {
        await apiSend("/status-desa", "POST", payload);
        toast.success("Status desa 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(`/status-desa/${deleteTarget.id}`, "DELETE");
      toast.success("Status desa dihapus");
      setDeleteTarget(null);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menghapus data");
    } finally {
      setDeleting(false);
    }
  }

  async function syncIdm(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSyncing(true);
    try {
      const result = await apiSend<{ tahun: number; jumlahIndikator: number }>(
        "/status-desa/sync",
        "POST",
        { tahun: Number(syncYear) },
      );
      toast.success(
        `IDM ${result.tahun} disinkronkan (${result.jumlahIndikator} indikator)`,
      );
      setSyncOpen(false);
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal sinkron data IDM",
      );
    } finally {
      setSyncing(false);
    }
  }

  async function openDetail(item: StatusDesa) {
    setDetailLoadingId(item.id);
    try {
      const rows = await apiGet<StatusDesaIndikator[]>(
        `/status-desa/${item.id}/indikator`,
      );
      setDetail({ tahun: item.tahun, rows });
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal memuat rincian IDM",
      );
    } finally {
      setDetailLoadingId(null);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Status Desa"
        description={
          tab === "sdgs"
            ? "Capaian 18 tujuan Sustainable Development Goals Desa berdasarkan skor dari API Kemendesa."
            : "Indeks Desa Membangun (IDM) Desa Mulyadadi per tahun beserta dimensi sosial, ekonomi, dan ekologi."
        }
        action={
          tab === "idm" && isAdmin ? (
            <div className="flex flex-wrap gap-2">
              <Button
                variant="outline"
                onClick={() => {
                  setSyncYear(String(new Date().getFullYear()));
                  setSyncOpen(true);
                }}
              >
                <CloudDownload className="h-4 w-4" />
                Sinkron IDM
              </Button>
              <Button onClick={openCreate}>
                <Plus className="h-4 w-4" />
                Tambah Data
              </Button>
            </div>
          ) : undefined
        }
      />

      <div className="inline-flex rounded-xl border border-border bg-card p-1">
        {[
          { key: "idm" as const, label: "IDM", icon: Activity },
          { key: "sdgs" as const, label: "SDGs Desa", icon: Target },
        ].map((item) => (
          <button
            key={item.key}
            type="button"
            onClick={() => pilihTab(item.key)}
            className={cn(
              "inline-flex items-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors",
              tab === item.key
                ? "bg-primary text-primary-foreground shadow-sm"
                : "text-muted-foreground hover:bg-muted",
            )}
          >
            <item.icon className="h-4 w-4" />
            {item.label}
          </button>
        ))}
      </div>

      {tab === "sdgs" ? (
        <SdgsPanel isAdmin={isAdmin} />
      ) : (
        <>
      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
        <StatCard
          title="Skor IDM terbaru"
          value={terbaru ? terbaru.skorIdm.toFixed(4) : "-"}
          hint={terbaru ? `Tahun ${terbaru.tahun}` : "Belum ada data"}
          icon={Activity}
        />
        <StatCard
          title="Status IDM"
          value={terbaru ? statusLabel(terbaru.status) : "-"}
          hint={terbaru ? `Target: ${statusLabel(terbaru.targetStatus)}` : undefined}
          icon={TrendingUp}
          tone="sky"
        />
        <StatCard
          title="Target status"
          value={terbaru ? statusLabel(terbaru.targetStatus) : "-"}
          hint="Sasaran jangka menengah"
          icon={Target}
          tone="amber"
        />
        <StatCard
          title="Tahun terdata"
          value={daftar.length}
          hint={chartData.length ? `${chartData[0].tahun}–${chartData[chartData.length - 1].tahun}` : undefined}
          icon={CalendarRange}
          tone="violet"
        />
      </div>

      <div className="grid gap-4 lg:grid-cols-5">
        <Card className="lg:col-span-3">
          <CardHeader>
            <CardTitle>Perkembangan Skor IDM</CardTitle>
          </CardHeader>
          <CardContent>
            {chartData.length ? (
              <ResponsiveContainer width="100%" height={280}>
                <LineChart data={chartData} margin={{ top: 4, right: 12, left: -12, bottom: 0 }}>
                  <CartesianGrid strokeDasharray="3 3" stroke="#e8eeeb" />
                  <XAxis
                    dataKey="tahun"
                    tick={{ fontSize: 11, fill: "#64748b" }}
                    axisLine={false}
                    tickLine={false}
                  />
                  <YAxis
                    domain={[40, 100]}
                    tick={{ fontSize: 10, fill: "#64748b" }}
                    axisLine={false}
                    tickLine={false}
                  />
                  <Tooltip
                    contentStyle={{
                      borderRadius: 10,
                      border: "1px solid #e2e8e5",
                      fontSize: 12,
                    }}
                    formatter={(value, name) => [
                      `${Number(value ?? 0).toFixed(2)}`,
                      String(name),
                    ]}
                  />
                  <Legend iconType="circle" wrapperStyle={{ fontSize: 12 }} />
                  <Line
                    type="monotone"
                    dataKey="idm"
                    name="Skor IDM"
                    stroke="#059669"
                    strokeWidth={2.5}
                    dot={{ r: 3 }}
                  />
                  <Line
                    type="monotone"
                    dataKey="sosial"
                    name="Sosial"
                    stroke="#0284c7"
                    strokeWidth={1.5}
                    dot={{ r: 2 }}
                  />
                  <Line
                    type="monotone"
                    dataKey="ekonomi"
                    name="Ekonomi"
                    stroke="#d97706"
                    strokeWidth={1.5}
                    dot={{ r: 2 }}
                  />
                  <Line
                    type="monotone"
                    dataKey="ekologi"
                    name="Ekologi"
                    stroke="#7c3aed"
                    strokeWidth={1.5}
                    dot={{ r: 2 }}
                  />
                </LineChart>
              </ResponsiveContainer>
            ) : (
              <div className="flex h-[280px] items-center justify-center rounded-lg bg-muted/40 text-sm text-muted-foreground">
                Belum ada data status desa
              </div>
            )}
          </CardContent>
        </Card>

        <Card className="lg:col-span-2">
          <CardHeader className="flex-row items-center justify-between gap-2 space-y-0">
            <CardTitle>Rincian IDM</CardTitle>
            <Select
              className="h-8 w-28 text-xs"
              value={tahunAktif ? String(tahunAktif.tahun) : ""}
              onChange={(event) => setSelectedYear(event.target.value)}
              aria-label="Pilih tahun IDM"
            >
              {daftar.map((item) => (
                <option key={item.id} value={item.tahun}>
                  {item.tahun}
                </option>
              ))}
            </Select>
          </CardHeader>
          <CardContent className="space-y-4">
            {tahunAktif ? (
              <>
                <div className="grid grid-cols-3 gap-2">
                  <DonutSkor label="Sosial" value={tahunAktif.skorSosial} color="#0284c7" />
                  <DonutSkor label="Ekonomi" value={tahunAktif.skorEkonomi} color="#d97706" />
                  <DonutSkor label="Ekologi" value={tahunAktif.skorEkologi} color="#7c3aed" />
                </div>
                <div className="space-y-1 rounded-lg bg-muted/50 p-3">
                  <div className="flex items-center justify-between text-sm">
                    <span className="text-muted-foreground">Skor IDM</span>
                    <span className="font-mono font-semibold">
                      {tahunAktif.skorIdm.toFixed(4)}
                    </span>
                  </div>
                  <div className="flex items-center justify-between text-sm">
                    <span className="text-muted-foreground">Status</span>
                    <Badge variant={badgeVariant(tahunAktif.status)}>
                      {statusLabel(tahunAktif.status)}
                    </Badge>
                  </div>
                </div>
                <p className="rounded-lg bg-muted/50 p-3 text-sm text-muted-foreground">
                  {tahunAktif.keterangan ?? "Tidak ada catatan."}
                </p>
              </>
            ) : (
              <p className="text-sm text-muted-foreground">Belum ada data.</p>
            )}
          </CardContent>
        </Card>
      </div>

      <Card>
        <CardContent className="p-0">
          {isLoading ? (
            <div className="space-y-2 p-4">
              {Array.from({ length: 4 }).map((_, index) => (
                <div key={index} className="h-14 animate-pulse rounded-lg bg-muted" />
              ))}
            </div>
          ) : daftar.length ? (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Tahun</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Skor IDM</TableHead>
                  <TableHead>Sosial / Ekonomi / Ekologi</TableHead>
                  <TableHead>Target</TableHead>
                  <TableHead>Keterangan</TableHead>
                  {(isAdmin || hasDetail) && (
                    <TableHead className="text-right">Aksi</TableHead>
                  )}
                </TableRow>
              </TableHeader>
              <TableBody>
                {daftar.map((item) => (
                  <TableRow key={item.id}>
                    <TableCell className="font-semibold">{item.tahun}</TableCell>
                    <TableCell>
                      <Badge variant={badgeVariant(item.status)}>
                        {statusLabel(item.status)}
                      </Badge>
                    </TableCell>
                    <TableCell className="font-mono text-sm">
                      {item.skorIdm.toFixed(4)}
                    </TableCell>
                    <TableCell className="text-xs text-muted-foreground">
                      {item.skorSosial?.toFixed(3) ?? "-"} /{" "}
                      {item.skorEkonomi?.toFixed(3) ?? "-"} /{" "}
                      {item.skorEkologi?.toFixed(3) ?? "-"}
                    </TableCell>
                    <TableCell className="text-sm">
                      {statusLabel(item.targetStatus)}
                    </TableCell>
                    <TableCell className="max-w-[240px] truncate text-sm text-muted-foreground">
                      {item.keterangan ?? "-"}
                    </TableCell>
                    {(isAdmin || hasDetail) && (
                      <TableCell className="text-right">
                        <div className="flex justify-end gap-1">
                          {(item._count?.indikator ?? 0) > 0 && (
                            <Button
                              variant="ghost"
                              size="sm"
                              onClick={() => openDetail(item)}
                              disabled={detailLoadingId === item.id}
                              aria-label="Rincian indikator"
                            >
                              <ListChecks className="h-4 w-4" />
                            </Button>
                          )}
                          {isAdmin && (
                            <>
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => openEdit(item)}
                                aria-label="Ubah"
                              >
                                <Pencil className="h-4 w-4" />
                              </Button>
                              <Button
                                variant="ghost"
                                size="sm"
                                className="text-destructive hover:text-destructive"
                                onClick={() => setDeleteTarget(item)}
                                aria-label="Hapus"
                              >
                                <Trash2 className="h-4 w-4" />
                              </Button>
                            </>
                          )}
                        </div>
                      </TableCell>
                    )}
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          ) : (
            <div className="py-16 text-center">
              <p className="font-semibold">Belum ada data status desa</p>
              <p className="mt-1 text-sm text-muted-foreground">
                Tambahkan skor IDM per tahun untuk melihat perkembangan desa.
              </p>
            </div>
          )}
        </CardContent>
      </Card>

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-w-xl">
          <DialogHeader>
            <DialogTitle>{editing ? "Ubah Status Desa" : "Tambah Status Desa"}</DialogTitle>
            <DialogDescription>
              Masukkan skor IDM dalam skala 0–1. Nilai ditampilkan sebagai persentase pada grafik.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-2">
              <Field label="Tahun" required>
                <Input
                  type="number"
                  min={2000}
                  max={2100}
                  required
                  value={form.tahun}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, tahun: event.target.value }))
                  }
                />
              </Field>
              <Field label="Status IDM" required>
                <Select
                  value={form.status}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      status: event.target.value as StatusIdm,
                    }))
                  }
                >
                  {STATUS_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
              </Field>
              <Field label="Skor IDM" required>
                <Input
                  type="number"
                  min={0}
                  max={100}
                  step="0.0001"
                  required
                  value={form.skorIdm}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, skorIdm: event.target.value }))
                  }
                  placeholder="0.7462"
                />
              </Field>
              <Field label="Target status">
                <Select
                  value={form.targetStatus}
                  onChange={(event) =>
                    setForm((current) => ({
                      ...current,
                      targetStatus: event.target.value as StatusIdm | "",
                    }))
                  }
                >
                  <option value="">Tidak ditentukan</option>
                  {STATUS_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
              </Field>
              <Field label="Skor sosial">
                <Input
                  type="number"
                  min={0}
                  max={100}
                  step="0.0001"
                  value={form.skorSosial}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, skorSosial: event.target.value }))
                  }
                />
              </Field>
              <Field label="Skor ekonomi">
                <Input
                  type="number"
                  min={0}
                  max={100}
                  step="0.0001"
                  value={form.skorEkonomi}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, skorEkonomi: event.target.value }))
                  }
                />
              </Field>
              <Field label="Skor ekologi">
                <Input
                  type="number"
                  min={0}
                  max={100}
                  step="0.0001"
                  value={form.skorEkologi}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, skorEkologi: event.target.value }))
                  }
                />
              </Field>
            </div>
            <Field label="Keterangan">
              <Textarea
                rows={3}
                value={form.keterangan}
                onChange={(event) =>
                  setForm((current) => ({ ...current, keterangan: event.target.value }))
                }
              />
            </Field>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setFormOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : editing ? "Simpan Perubahan" : "Tambah Data"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={syncOpen} onOpenChange={setSyncOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Sinkron IDM dari Kemendesa</DialogTitle>
            <DialogDescription>
              Skor diambil dari API idm.kemendesa.go.id memakai kode desa pada
              Pengaturan.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={syncIdm} className="space-y-4">
            <Field label="Tahun IDM" required>
              <Input
                type="number"
                min={2000}
                max={2100}
                required
                value={syncYear}
                onChange={(event) => setSyncYear(event.target.value)}
              />
            </Field>
            <p className="rounded-lg bg-muted/50 p-3 text-xs leading-relaxed text-muted-foreground">
              Sinkronisasi menimpa data tahun yang sama dan menyimpan rincian
              indikatornya. Data tahun berjalan biasanya terbit setelah
              penetapan Kemendesa.
            </p>
            <DialogFooter>
              <Button
                type="button"
                variant="outline"
                onClick={() => setSyncOpen(false)}
              >
                Batal
              </Button>
              <Button type="submit" disabled={syncing}>
                {syncing ? "Menyinkronkan…" : "Sinkron Sekarang"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={!!detail} onOpenChange={(open) => !open && setDetail(null)}>
        <DialogContent className="max-w-6xl">
          <DialogHeader>
            <DialogTitle>Rincian Indikator IDM {detail?.tahun}</DialogTitle>
            <DialogDescription>
              {detail?.rows.length ?? 0} baris dari API Kemendesa. Baris tebal
              adalah ringkasan IKS, IKE, IKL, dan IDM.
            </DialogDescription>
          </DialogHeader>
          <div className="max-h-[65vh] overflow-auto rounded-lg border">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-10">No</TableHead>
                  <TableHead>Indikator IDM</TableHead>
                  <TableHead className="w-16">Skor</TableHead>
                  <TableHead>Keterangan</TableHead>
                  <TableHead>Kegiatan Yang Dapat Dilakukan</TableHead>
                  <TableHead className="w-20">+Nilai</TableHead>
                  <TableHead className="w-24">Pusat</TableHead>
                  <TableHead className="w-24">Provinsi</TableHead>
                  <TableHead className="w-24">Kabupaten</TableHead>
                  <TableHead className="w-24">Desa</TableHead>
                  <TableHead className="w-24">CSR</TableHead>
                  <TableHead className="w-24">Lainnya</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {detail?.rows.map((row) => (
                  <TableRow
                    key={row.id}
                    className={row.no == null ? "bg-secondary/60 font-semibold" : undefined}
                  >
                    <TableCell>{row.no ?? "-"}</TableCell>
                    <TableCell className="min-w-[160px]">{row.indikator}</TableCell>
                    <TableCell className="font-mono text-xs">
                      {row.skor ?? "-"}
                    </TableCell>
                    <TableCell className="min-w-[220px] text-xs">
                      {row.keterangan ?? "-"}
                    </TableCell>
                    <TableCell className="min-w-[180px] text-xs">
                      {row.kegiatan ?? "-"}
                    </TableCell>
                    <TableCell className="font-mono text-xs">
                      {row.nilai ?? "-"}
                    </TableCell>
                    <TableCell className="text-xs">{row.pusat ?? "-"}</TableCell>
                    <TableCell className="text-xs">{row.prov ?? "-"}</TableCell>
                    <TableCell className="text-xs">{row.kab ?? "-"}</TableCell>
                    <TableCell className="text-xs">{row.desa ?? "-"}</TableCell>
                    <TableCell className="text-xs">{row.csr ?? "-"}</TableCell>
                    <TableCell className="text-xs">{row.lainnya ?? "-"}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDetail(null)}>
              Tutup
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus status desa?</DialogTitle>
            <DialogDescription>
              Data IDM tahun {deleteTarget?.tahun} 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 DonutSkor({
  label,
  value,
  color,
}: {
  label: string;
  value: number | null;
  color: string;
}) {
  const pct = value != null ? Math.min(100, Math.max(0, value * 100)) : 0;
  const data = [
    { name: "Capaian", value: pct },
    { name: "Sisa", value: 100 - pct },
  ];
  return (
    <div className="rounded-lg border p-2 text-center">
      <ResponsiveContainer width="100%" height={84}>
        <PieChart>
          <Pie
            data={data}
            dataKey="value"
            innerRadius={26}
            outerRadius={38}
            startAngle={90}
            endAngle={-270}
            stroke="none"
            isAnimationActive={false}
          >
            <Cell fill={color} />
            <Cell fill="#e8eeeb" />
          </Pie>
        </PieChart>
      </ResponsiveContainer>
      <div className="text-[11px] text-muted-foreground">{label}</div>
      <div className="text-sm font-semibold">
        {value != null ? value.toFixed(3) : "-"}
      </div>
    </div>
  );
}

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