"use client";

import { useEffect, useMemo, useState } from "react";
import useSWR from "swr";
import { Save } from "lucide-react";
import { toast } from "sonner";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { cn } from "@/lib/utils";

interface SettingRow {
  id: number;
  kunci: string;
  nilai: string | null;
  grup: string | null;
}

const KUNCI_LABEL = "surat.penduduk_luar_label";
const KUNCI_ISIAN = "surat.penduduk_luar_isian";

interface PilihanIsian {
  id: string;
  label: string;
  wajib?: boolean;
}

const PILIHAN_ISIAN: PilihanIsian[] = [
  { id: "nama", label: "Nama Lengkap", wajib: true },
  { id: "no_ktp", label: "NIK", wajib: true },
  { id: "tempat_lahir", label: "Tempat Lahir" },
  { id: "tanggal_lahir", label: "Tanggal Lahir" },
  { id: "jenis_kelamin", label: "Jenis Kelamin" },
  { id: "agama", label: "Agama" },
  { id: "pendidikan_kk", label: "Pendidikan" },
  { id: "pekerjaan", label: "Pekerjaan" },
  { id: "warga_negara", label: "Warga Negara" },
  { id: "alamat", label: "Alamat" },
  { id: "golongan_darah", label: "Golongan Darah" },
  { id: "status_perkawinan", label: "Status Perkawinan" },
  { id: "tanggal_perkawinan", label: "Tanggal Perkawinan" },
  { id: "shdk", label: "Status Hubungan Dalam Keluarga" },
  { id: "no_paspor", label: "No. Paspor" },
  { id: "no_kitas", label: "No. KITAS / KITAP" },
  { id: "nama_ayah", label: "Nama Ayah" },
  { id: "nama_ibu", label: "Nama Ibu" },
];

const ISIAN_LENGKAP = [
  ...PILIHAN_ISIAN.map((item) => item.label),
  "No. KK",
  "Kepala Keluarga",
];

const ISIAN_WAJIB = PILIHAN_ISIAN.filter((item) => item.wajib).map((item) => item.id);

function PratinjauIsian({ judul, items }: { judul: string; items: string[] }) {
  return (
    <div className="overflow-hidden rounded-lg border">
      <div className="border-b bg-primary px-3 py-2 text-xs font-semibold text-primary-foreground">
        {judul}
      </div>
      <div className="grid gap-1 p-3 sm:grid-cols-2">
        {items.map((item) => (
          <div key={item} className="flex items-center gap-2 text-xs">
            <span className="h-1.5 w-1.5 shrink-0 rounded-full bg-muted-foreground" />
            {item}
          </div>
        ))}
      </div>
    </div>
  );
}

export function FormPendudukLuar() {
  const { data, mutate } = useSWR<SettingRow[]>("/pengaturan-sistem?grup=surat", fetcher);
  const [label, setLabel] = useState("");
  const [isian, setIsian] = useState<string[]>(ISIAN_WAJIB);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    const stored = new Map((data ?? []).map((row) => [row.kunci, row.nilai ?? ""]));
    setLabel(stored.get(KUNCI_LABEL) ?? "");
    const tersimpan = (stored.get(KUNCI_ISIAN) ?? "")
      .split(",")
      .map((item) => item.trim())
      .filter(Boolean);
    setIsian([...new Set([...ISIAN_WAJIB, ...tersimpan])]);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [data]);

  const isianTerpilih = useMemo(
    () =>
      PILIHAN_ISIAN.filter((item) => isian.includes(item.id)).map((item) => item.label),
    [isian],
  );

  function toggle(id: string, checked: boolean) {
    setIsian((current) => {
      const next = new Set(current);
      if (checked) next.add(id);
      else next.delete(id);
      ISIAN_WAJIB.forEach((wajib) => next.add(wajib));
      return PILIHAN_ISIAN.filter((item) => next.has(item.id)).map((item) => item.id);
    });
  }

  async function simpan() {
    setSaving(true);
    try {
      await apiSend("/pengaturan-sistem", "PUT", {
        items: [
          { kunci: KUNCI_LABEL, nilai: label, grup: "surat" },
          { kunci: KUNCI_ISIAN, nilai: isian.join(","), grup: "surat" },
        ],
      });
      toast.success("Form penduduk luar disimpan");
      await mutate();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menyimpan form penduduk luar",
      );
    } finally {
      setSaving(false);
    }
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Form Penduduk Luar</CardTitle>
        <CardDescription>
          Label dan isian yang diminta dari penduduk di luar desa saat mengajukan surat.
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-5">
        <div className="grid gap-4 sm:grid-cols-2">
          <div className="space-y-1.5">
            <Label htmlFor="penduduk-luar-label">Label</Label>
            <Input
              id="penduduk-luar-label"
              value={label}
              minLength={3}
              maxLength={20}
              onChange={(event) => setLabel(event.target.value)}
              placeholder="PENDUDUK LUAR [desa]"
            />
            <p className="text-[11px] text-muted-foreground">
              Isi dengan <code className="rounded bg-muted px-1">[desa]</code> untuk
              menyesuaikan sebutan desa berdasarkan pengaturan aplikasi.
            </p>
          </div>
        </div>

        <div className="space-y-2">
          <Label>Pilihan Input</Label>
          <div className="grid gap-2 sm:grid-cols-2 lg:grid-cols-3">
            {PILIHAN_ISIAN.map((item) => (
              <label
                key={item.id}
                className={cn(
                  "flex items-center gap-2 rounded-lg border border-input px-3 py-2 text-xs",
                  item.wajib && "bg-muted",
                )}
              >
                <input
                  type="checkbox"
                  checked={isian.includes(item.id)}
                  disabled={item.wajib}
                  onChange={(event) => toggle(item.id, event.target.checked)}
                  className="h-4 w-4 accent-[hsl(var(--primary))]"
                />
                {item.label}
              </label>
            ))}
          </div>
        </div>

        <div className="grid gap-4 lg:grid-cols-2">
          <PratinjauIsian judul="PENDUDUK LUAR DESA" items={isianTerpilih} />
          <PratinjauIsian judul="PENDUDUK LUAR DESA (LENGKAP)" items={ISIAN_LENGKAP} />
        </div>

        <div className="flex justify-end">
          <Button type="button" onClick={simpan} disabled={saving}>
            <Save className="h-4 w-4" /> {saving ? "Menyimpan…" : "Simpan"}
          </Button>
        </div>
      </CardContent>
    </Card>
  );
}
