"use client";

import { useEffect, useState } from "react";
import { CheckCircle2, Loader2, MapPin, TriangleAlert } from "lucide-react";
import { toast } from "sonner";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";

type Level = "provinsi" | "kabupaten" | "kecamatan" | "desa";
type Wilayah = { code: string; name: string };

export interface IdentitasWilayah {
  nama: string;
  kodeDesa: string;
  kecamatan: string;
  kabupaten: string;
  provinsi: string;
}

const emptyPick = { provinsi: "", kabupaten: "", kecamatan: "", desa: "" };

const emptyLists: Record<Level, Wilayah[]> = {
  provinsi: [],
  kabupaten: [],
  kecamatan: [],
  desa: [],
};

export function WilayahSync({
  onApply,
}: {
  onApply: (values: IdentitasWilayah) => void;
}) {
  const [pick, setPick] = useState(emptyPick);
  const [lists, setLists] = useState(emptyLists);
  const [loading, setLoading] = useState<Level | null>("provinsi");
  const [error, setError] = useState("");
  const [applied, setApplied] = useState("");

  useEffect(() => {
    load("provinsi");
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  async function load(level: Level, parent?: string) {
    setLoading(level);
    setError("");
    try {
      const query = parent ? `?parent=${encodeURIComponent(parent)}` : "";
      const response = await fetch(`/api/wilayah/${level}${query}`);
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const json = (await response.json()) as { data?: Wilayah[] };
      setLists((current) => ({ ...current, [level]: json.data ?? [] }));
    } catch {
      setError(
        "Gagal memuat data wilayah Kemendesa. Periksa koneksi internet lalu coba lagi.",
      );
    } finally {
      setLoading(null);
    }
  }

  async function handleProvinsi(code: string) {
    setPick({ provinsi: code, kabupaten: "", kecamatan: "", desa: "" });
    setLists((current) => ({ ...current, kabupaten: [], kecamatan: [], desa: [] }));
    setApplied("");
    if (code) await load("kabupaten", code);
  }

  async function handleKabupaten(code: string) {
    setPick((current) => ({ ...current, kabupaten: code, kecamatan: "", desa: "" }));
    setLists((current) => ({ ...current, kecamatan: [], desa: [] }));
    setApplied("");
    if (code) await load("kecamatan", code);
  }

  async function handleKecamatan(code: string) {
    setPick((current) => ({ ...current, kecamatan: code, desa: "" }));
    setLists((current) => ({ ...current, desa: [] }));
    setApplied("");
    if (code) await load("desa", code);
  }

  function handleDesa(code: string) {
    setPick((current) => ({ ...current, desa: code }));
    if (!code) {
      setApplied("");
      return;
    }

    const provinsi = lists.provinsi.find((item) => item.code === pick.provinsi);
    const kabupaten = lists.kabupaten.find((item) => item.code === pick.kabupaten);
    const kecamatan = lists.kecamatan.find((item) => item.code === pick.kecamatan);
    const desa = lists.desa.find((item) => item.code === code);
    if (!provinsi || !kabupaten || !kecamatan || !desa) return;

    onApply({
      nama: /^(desa|kelurahan)\s/i.test(desa.name) ? desa.name : `Desa ${desa.name}`,
      kodeDesa: desa.code,
      kecamatan: kecamatan.name,
      kabupaten: kabupaten.name,
      provinsi: provinsi.name,
    });
    setApplied(
      `${desa.name}, Kec. ${kecamatan.name}, ${kabupaten.name}, ${provinsi.name}`,
    );
    toast.success("Identitas wilayah terisi dari data Kemendesa");
  }

  const options = (level: Level, placeholder: string) => (
    <>
      <option value="">
        {loading === level ? "Memuat data…" : placeholder}
      </option>
      {lists[level].map((item) => (
        <option key={item.code} value={item.code}>
          {item.name}
        </option>
      ))}
    </>
  );

  return (
    <Card className="border-dashed bg-secondary/30">
      <CardHeader className="flex-row items-center gap-2 space-y-0">
        <MapPin className="h-4 w-4 text-primary" />
        <CardTitle>Sinkron Identitas Wilayah</CardTitle>
        <span className="ml-auto rounded-full bg-primary/10 px-2.5 py-0.5 text-[10px] font-semibold uppercase tracking-wider text-primary">
          API Kemendesa
        </span>
      </CardHeader>
      <CardContent className="space-y-4">
        <p className="text-sm text-muted-foreground">
          Pilih wilayah berjenjang untuk mengisi nama desa, kode desa, kecamatan,
          kabupaten, dan provinsi otomatis. Kontak dan kepala desa tetap diisi
          manual, lalu klik <span className="font-medium text-foreground">Simpan Perubahan</span>.
        </p>

        <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
          <div className="space-y-2">
            <Label htmlFor="wilayah-provinsi">Provinsi</Label>
            <Select
              id="wilayah-provinsi"
              value={pick.provinsi}
              disabled={loading === "provinsi"}
              onChange={(event) => void handleProvinsi(event.target.value)}
            >
              {options("provinsi", "Pilih provinsi")}
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="wilayah-kabupaten">Kabupaten / Kota</Label>
            <Select
              id="wilayah-kabupaten"
              value={pick.kabupaten}
              disabled={!pick.provinsi || loading === "kabupaten"}
              onChange={(event) => void handleKabupaten(event.target.value)}
            >
              {options("kabupaten", pick.provinsi ? "Pilih kabupaten/kota" : "Pilih provinsi dulu")}
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="wilayah-kecamatan">Kecamatan</Label>
            <Select
              id="wilayah-kecamatan"
              value={pick.kecamatan}
              disabled={!pick.kabupaten || loading === "kecamatan"}
              onChange={(event) => void handleKecamatan(event.target.value)}
            >
              {options("kecamatan", pick.kabupaten ? "Pilih kecamatan" : "Pilih kabupaten dulu")}
            </Select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="wilayah-desa">Desa / Kelurahan</Label>
            <Select
              id="wilayah-desa"
              value={pick.desa}
              disabled={!pick.kecamatan || loading === "desa"}
              onChange={(event) => handleDesa(event.target.value)}
            >
              {options("desa", pick.kecamatan ? "Pilih desa/kelurahan" : "Pilih kecamatan dulu")}
            </Select>
          </div>
        </div>

        {loading && (
          <p className="flex items-center gap-2 text-xs text-muted-foreground">
            <Loader2 className="h-3.5 w-3.5 animate-spin" />
            Mengambil data {loading} dari API Kemendesa…
          </p>
        )}

        {applied && !error && (
          <div className="flex flex-wrap items-center justify-between gap-3 rounded-lg bg-primary/10 px-3 py-2">
            <p className="flex items-start gap-2 text-xs font-medium text-primary">
              <CheckCircle2 className="mt-0.5 h-3.5 w-3.5 shrink-0" />
              {applied} — identitas terisi, simpan untuk menerapkan.
            </p>
            <Button type="submit" size="sm" className="h-8 shrink-0">
              Simpan
            </Button>
          </div>
        )}

        {error && (
          <p
            role="alert"
            className="flex items-start gap-2 rounded-lg bg-destructive/10 px-3 py-2 text-xs font-medium text-destructive"
          >
            <TriangleAlert className="mt-0.5 h-3.5 w-3.5 shrink-0" />
            {error}
          </p>
        )}
      </CardContent>
    </Card>
  );
}
