"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import useSWR from "swr";
import {
  Banknote,
  CalendarPlus,
  FilePenLine,
  Landmark,
  Plus,
  Trash2,
  TrendingDown,
  TrendingUp,
  Upload,
  Wallet,
} from "lucide-react";
import { toast } from "sonner";
import type {
  AnggaranItem,
  KeuanganSummary,
  TahunAnggaran,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { POHON_ANGGARAN, bandingkanKode, cocokKode } from "@/lib/anggaran";
import { PageHeader, StatCard } from "@/components/page-header";
import { KeuanganTabs } from "@/components/admin/keuangan-tabs";
import { BudgetByBidang, BudgetDonut } from "@/components/charts/budget-chart";
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 {
  formatCompactRupiah,
  formatNumber,
  formatRupiah,
  labelJenisAnggaran,
} from "@/lib/utils";

type ItemForm = {
  kode: string;
  uraian: string;
  jenis: string;
  bidang: string;
  sumberDana: string;
  anggaran: string;
  realisasi: string;
};

const emptyItem: ItemForm = {
  kode: "",
  uraian: "",
  jenis: "PENDAPATAN",
  bidang: "",
  sumberDana: "",
  anggaran: "",
  realisasi: "",
};

const STATUS_VARIANT: Record<string, "success" | "warning" | "secondary"> = {
  AKTIF: "success",
  DRAFT: "warning",
  TUTUP: "secondary",
};

export default function KeuanganPage() {
  const [tahun, setTahun] = useState("");
  const [filterKode, setFilterKode] = useState("");

  const { data: tahunList, mutate: mutateTahun } = useSWR<TahunAnggaran[]>(
    "/keuangan/tahun",
    fetcher,
  );
  const summaryKey = tahun
    ? `/keuangan/ringkasan?tahun=${tahun}`
    : "/keuangan/ringkasan";
  const {
    data: summary,
    isLoading,
    mutate: mutateSummary,
  } = useSWR<KeuanganSummary>(summaryKey, fetcher);

  const [itemOpen, setItemOpen] = useState(false);
  const [editingItem, setEditingItem] = useState<AnggaranItem | null>(null);
  const [itemForm, setItemForm] = useState<ItemForm>(emptyItem);
  const [saving, setSaving] = useState(false);

  const [tahunOpen, setTahunOpen] = useState(false);
  const [tahunForm, setTahunForm] = useState({
    tahun: "",
    status: "DRAFT",
    template: true,
  });

  const [deleteTarget, setDeleteTarget] = useState<AnggaranItem | null>(null);
  const [deleting, setDeleting] = useState(false);

  useEffect(() => {
    if (!tahun && tahunList?.length) {
      const aktif = tahunList.find((item) => item.status === "AKTIF");
      setTahun(String((aktif ?? tahunList[0]).tahun));
    }
  }, [tahun, tahunList]);

  const activeYear = useMemo(
    () => tahunList?.find((item) => String(item.tahun) === tahun) ?? null,
    [tahunList, tahun],
  );

  const items = useMemo(() => {
    const list = summary?.items ?? [];
    const terfilter = filterKode
      ? list.filter((item) => cocokKode(item.kode, filterKode))
      : list;
    return [...terfilter].sort((a, b) => bandingkanKode(a.kode, b.kode));
  }, [summary?.items, filterKode]);

  const totals = summary?.totals ?? { PENDAPATAN: 0, BELANJA: 0, PEMBIAYAAN: 0 };
  const realisasi = summary?.realisasi ?? { PENDAPATAN: 0, BELANJA: 0, PEMBIAYAAN: 0 };

  async function refresh() {
    await mutateTahun();
    await mutateSummary();
  }

  function openCreateItem() {
    if (!activeYear) {
      toast.error("Buat tahun anggaran terlebih dahulu");
      return;
    }
    setEditingItem(null);
    setItemForm(emptyItem);
    setItemOpen(true);
  }

  function openEditItem(item: AnggaranItem) {
    setEditingItem(item);
    setItemForm({
      kode: item.kode,
      uraian: item.uraian,
      jenis: item.jenis,
      bidang: item.bidang ?? "",
      sumberDana: item.sumberDana ?? "",
      anggaran: String(Number(item.anggaran)),
      realisasi: String(Number(item.realisasi)),
    });
    setItemOpen(true);
  }

  async function saveItem(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!activeYear) return;
    setSaving(true);
    try {
      const payload: Record<string, unknown> = {
        kode: itemForm.kode,
        uraian: itemForm.uraian,
        jenis: itemForm.jenis,
        anggaran: Number(itemForm.anggaran || 0),
        realisasi: Number(itemForm.realisasi || 0),
      };
      if (itemForm.bidang) payload.bidang = itemForm.bidang;
      if (itemForm.sumberDana) payload.sumberDana = itemForm.sumberDana;

      if (editingItem) {
        await apiSend(`/keuangan/items/${editingItem.id}`, "PATCH", payload);
        toast.success("Item anggaran diperbarui");
      } else {
        await apiSend("/keuangan/items", "POST", {
          ...payload,
          tahunId: activeYear.id,
        });
        toast.success("Item anggaran ditambahkan");
      }
      setItemOpen(false);
      setEditingItem(null);
      await refresh();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menyimpan item");
    } finally {
      setSaving(false);
    }
  }

  async function createTahun(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const nomorTahun = Number(tahunForm.tahun);
    setSaving(true);
    try {
      await apiSend("/keuangan/tahun", "POST", {
        tahun: nomorTahun,
        status: tahunForm.status,
        template: tahunForm.template,
      });
      toast.success(
        tahunForm.template
          ? `Template ${nomorTahun} dibuat dengan kode rekening standar`
          : "Tahun anggaran ditambahkan",
      );
      setTahunOpen(false);
      setTahunForm({ tahun: "", status: "DRAFT", template: true });
      setTahun(String(nomorTahun));
      await refresh();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal membuat tahun anggaran");
    } finally {
      setSaving(false);
    }
  }

  async function changeStatus(status: string) {
    if (!activeYear) return;
    try {
      await apiSend(`/keuangan/tahun/${activeYear.id}`, "PATCH", { status });
      toast.success(`Status ${activeYear.tahun} diubah menjadi ${status}`);
      await refresh();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal mengubah status");
    }
  }

  async function removeItem() {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await apiSend(`/keuangan/items/${deleteTarget.id}`, "DELETE");
      toast.success("Item anggaran dihapus");
      setDeleteTarget(null);
      await refresh();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menghapus item");
    } finally {
      setDeleting(false);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Input Data"
        description="Kelola tahun anggaran, rincian item APBDes, dan realisasi per bidang."
        action={
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" onClick={() => setTahunOpen(true)}>
              <CalendarPlus className="h-4 w-4" />
              Tambah Template
            </Button>
            <Button variant="outline" asChild>
              <Link href="/admin/keuangan/impor">
                <Upload className="h-4 w-4" />
                Impor
              </Link>
            </Button>
            <Button onClick={openCreateItem}>
              <Plus className="h-4 w-4" />
              Tambah Item
            </Button>
          </div>
        }
      />

      <KeuanganTabs />

      <div className="flex flex-col gap-3 rounded-xl border bg-card p-4 sm:flex-row sm:items-center sm:justify-between">
        <div className="flex flex-wrap items-center gap-3">
          <div className="flex items-center gap-2">
            <Label className="text-xs uppercase tracking-wide text-muted-foreground">
              Tahun
            </Label>
            <Select
              value={tahun}
              onChange={(event) => setTahun(event.target.value)}
              className="w-44"
              aria-label="Pilih tahun anggaran"
            >
              {(tahunList ?? []).map((item) => (
                <option key={item.id} value={item.tahun}>
                  {item.tahun} · {item.status}
                </option>
              ))}
              {!tahunList?.length && <option value="">Belum ada tahun</option>}
            </Select>
          </div>
          {activeYear && (
            <Badge variant={STATUS_VARIANT[activeYear.status] ?? "secondary"}>
              {activeYear.status}
            </Badge>
          )}
        </div>

        {activeYear && (
          <div className="flex items-center gap-2">
            <Label className="text-xs uppercase tracking-wide text-muted-foreground">
              Ubah status
            </Label>
            <Select
              value={activeYear.status}
              onChange={(event) => changeStatus(event.target.value)}
              className="w-36"
              aria-label="Ubah status tahun anggaran"
            >
              <option value="DRAFT">DRAFT</option>
              <option value="AKTIF">AKTIF</option>
              <option value="TUTUP">TUTUP</option>
            </Select>
          </div>
        )}
      </div>

      {isLoading ? (
        <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="Pendapatan"
              value={formatCompactRupiah(totals.PENDAPATAN)}
              hint={`Realisasi ${formatCompactRupiah(realisasi.PENDAPATAN)}`}
              icon={TrendingUp}
              tone="emerald"
            />
            <StatCard
              title="Belanja"
              value={formatCompactRupiah(totals.BELANJA)}
              hint={`Realisasi ${formatCompactRupiah(realisasi.BELANJA)}`}
              icon={TrendingDown}
              tone="sky"
            />
            <StatCard
              title="Pembiayaan"
              value={formatCompactRupiah(totals.PEMBIAYAAN)}
              hint={`Realisasi ${formatCompactRupiah(realisasi.PEMBIAYAAN)}`}
              icon={Banknote}
              tone="amber"
            />
            <StatCard
              title="Item anggaran"
              value={formatNumber(summary?.items.length ?? 0)}
              hint={`Tahun ${summary?.tahun ?? "-"}`}
              icon={Wallet}
              tone="violet"
            />
          </div>

          <div className="grid gap-4 lg:grid-cols-2">
            <Card>
              <CardHeader>
                <CardTitle>Komposisi Anggaran</CardTitle>
              </CardHeader>
              <CardContent>
                <BudgetDonut
                  data={[
                    { name: "Pendapatan", value: totals.PENDAPATAN },
                    { name: "Belanja", value: totals.BELANJA },
                    { name: "Pembiayaan", value: totals.PEMBIAYAAN },
                  ]}
                />
              </CardContent>
            </Card>
            <Card>
              <CardHeader>
                <CardTitle>Belanja per Bidang</CardTitle>
              </CardHeader>
              <CardContent>
                <BudgetByBidang data={summary?.byBidang ?? []} />
              </CardContent>
            </Card>
          </div>

          <Card>
            <CardContent className="p-0">
              <div className="flex flex-col gap-3 border-b p-4 sm:flex-row sm:items-center sm:justify-between">
                <div>
                  <div className="font-semibold">Rincian APBDes {summary?.tahun ?? ""}</div>
                  <div className="text-xs text-muted-foreground">
                    {formatRupiah(
                      totals.PENDAPATAN + totals.BELANJA + totals.PEMBIAYAAN,
                    )}{" "}
                    total anggaran
                  </div>
                </div>
                <Select
                  value={filterKode}
                  onChange={(event) => setFilterKode(event.target.value)}
                  className="w-full sm:w-80"
                  aria-label="Filter jenis anggaran"
                >
                  <option value="">Pilih Jenis Anggaran</option>
                  {POHON_ANGGARAN.map((item) => (
                    <option key={item.kode} value={item.kode}>
                      {item.label}
                    </option>
                  ))}
                </Select>
              </div>

              {items.length ? (
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-12">No</TableHead>
                      <TableHead className="w-24">Aksi</TableHead>
                      <TableHead className="w-32">Kode Rekening</TableHead>
                      <TableHead>Uraian</TableHead>
                      <TableHead className="text-right">Anggaran</TableHead>
                      <TableHead className="text-right">Realisasi</TableHead>
                      <TableHead>Jenis</TableHead>
                      <TableHead>Bidang / Sumber</TableHead>
                      <TableHead className="w-24">Serapan</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {items.map((item, index) => {
                      const anggaran = Number(item.anggaran);
                      const realisasiItem = Number(item.realisasi);
                      const percent =
                        anggaran > 0
                          ? Math.min(100, Math.round((realisasiItem / anggaran) * 100))
                          : 0;
                      return (
                        <TableRow key={item.id}>
                          <TableCell className="text-xs text-muted-foreground">
                            {index + 1}
                          </TableCell>
                          <TableCell>
                            <div className="flex gap-1">
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-8 w-8"
                                onClick={() => openEditItem(item)}
                                aria-label="Ubah item"
                              >
                                <FilePenLine className="h-4 w-4" />
                              </Button>
                              <Button
                                variant="ghost"
                                size="icon"
                                className="h-8 w-8 text-destructive hover:text-destructive"
                                onClick={() => setDeleteTarget(item)}
                                aria-label="Hapus item"
                              >
                                <Trash2 className="h-4 w-4" />
                              </Button>
                            </div>
                          </TableCell>
                          <TableCell className="font-mono text-xs">{item.kode}</TableCell>
                          <TableCell className="max-w-[240px] font-medium">
                            {item.uraian}
                          </TableCell>
                          <TableCell className="text-right font-medium">
                            {formatCompactRupiah(anggaran)}
                          </TableCell>
                          <TableCell className="text-right text-muted-foreground">
                            {formatCompactRupiah(realisasiItem)}
                          </TableCell>
                          <TableCell>
                            <Badge
                              variant={
                                item.jenis === "PENDAPATAN"
                                  ? "success"
                                  : item.jenis === "BELANJA"
                                    ? "info"
                                    : "warning"
                              }
                            >
                              {labelJenisAnggaran(item.jenis)}
                            </Badge>
                          </TableCell>
                          <TableCell>
                            <div className="text-sm">{item.bidang ?? "-"}</div>
                            <div className="text-xs text-muted-foreground">
                              {item.sumberDana ?? "-"}
                            </div>
                          </TableCell>
                          <TableCell>
                            <div className="flex items-center gap-2">
                              <div className="h-1.5 w-12 overflow-hidden rounded-full bg-muted">
                                <div
                                  className="h-full rounded-full bg-emerald-500"
                                  style={{ width: `${percent}%` }}
                                />
                              </div>
                              <span className="text-xs text-muted-foreground">
                                {percent}%
                              </span>
                            </div>
                          </TableCell>
                        </TableRow>
                      );
                    })}
                  </TableBody>
                </Table>
              ) : (
                <div className="py-16 text-center">
                  <Landmark className="mx-auto h-6 w-6 text-muted-foreground" />
                  <p className="mt-2 font-semibold">Belum ada item anggaran</p>
                  <p className="mt-1 text-sm text-muted-foreground">
                    Tambahkan item pendapatan, belanja, atau pembiayaan untuk tahun ini.
                  </p>
                </div>
              )}
            </CardContent>
          </Card>
        </>
      )}

      <Dialog open={itemOpen} onOpenChange={setItemOpen}>
        <DialogContent className="max-w-2xl">
          <DialogHeader>
            <DialogTitle>{editingItem ? "Ubah Item Anggaran" : "Tambah Item Anggaran"}</DialogTitle>
            <DialogDescription>
              Tahun anggaran {activeYear?.tahun ?? "-"} · isi nilai dalam rupiah.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={saveItem} className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-[1fr_2fr]">
              <div className="space-y-1.5">
                <Label>
                  Kode Rekening <span className="text-destructive">*</span>
                </Label>
                <Input
                  required
                  maxLength={30}
                  value={itemForm.kode}
                  onChange={(event) =>
                    setItemForm((current) => ({ ...current, kode: event.target.value }))
                  }
                  placeholder="4.1.1.01"
                />
              </div>
              <div className="space-y-1.5">
                <Label>
                  Uraian <span className="text-destructive">*</span>
                </Label>
                <Input
                  required
                  value={itemForm.uraian}
                  onChange={(event) =>
                    setItemForm((current) => ({ ...current, uraian: event.target.value }))
                  }
                  placeholder="Nama pos anggaran"
                />
              </div>
            </div>

            <div className="grid gap-4 sm:grid-cols-3">
              <div className="space-y-1.5">
                <Label>Jenis</Label>
                <Select
                  value={itemForm.jenis}
                  onChange={(event) =>
                    setItemForm((current) => ({ ...current, jenis: event.target.value }))
                  }
                >
                  <option value="PENDAPATAN">Pendapatan</option>
                  <option value="BELANJA">Belanja</option>
                  <option value="PEMBIAYAAN">Pembiayaan</option>
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label>Bidang</Label>
                <Input
                  value={itemForm.bidang}
                  onChange={(event) =>
                    setItemForm((current) => ({ ...current, bidang: event.target.value }))
                  }
                  placeholder="Penyelenggaraan Pemerintahan"
                />
              </div>
              <div className="space-y-1.5">
                <Label>Sumber dana</Label>
                <Input
                  value={itemForm.sumberDana}
                  onChange={(event) =>
                    setItemForm((current) => ({
                      ...current,
                      sumberDana: event.target.value,
                    }))
                  }
                  placeholder="Dana Desa"
                />
              </div>
            </div>

            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-1.5">
                <Label>
                  Anggaran (Rp) <span className="text-destructive">*</span>
                </Label>
                <Input
                  required
                  type="number"
                  min={0}
                  step="0.01"
                  value={itemForm.anggaran}
                  onChange={(event) =>
                    setItemForm((current) => ({
                      ...current,
                      anggaran: event.target.value,
                    }))
                  }
                />
              </div>
              <div className="space-y-1.5">
                <Label>Realisasi (Rp)</Label>
                <Input
                  type="number"
                  min={0}
                  step="0.01"
                  value={itemForm.realisasi}
                  onChange={(event) =>
                    setItemForm((current) => ({
                      ...current,
                      realisasi: event.target.value,
                    }))
                  }
                />
              </div>
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setItemOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : editingItem ? "Simpan Perubahan" : "Tambah Item"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={tahunOpen} onOpenChange={setTahunOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Tambah Template</DialogTitle>
            <DialogDescription>
              Buat tahun anggaran baru. Template akan mengisi kode rekening
              standar Permendagri sehingga tinggal mengisi nilainya saja.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={createTahun} className="space-y-4">
            <div className="space-y-1.5">
              <Label>
                Tahun <span className="text-destructive">*</span>
              </Label>
              <Input
                required
                type="number"
                min={2000}
                max={2100}
                value={tahunForm.tahun}
                onChange={(event) =>
                  setTahunForm((current) => ({ ...current, tahun: event.target.value }))
                }
                placeholder="2027"
              />
            </div>
            <div className="space-y-1.5">
              <Label>Status awal</Label>
              <Select
                value={tahunForm.status}
                onChange={(event) =>
                  setTahunForm((current) => ({ ...current, status: event.target.value }))
                }
              >
                <option value="DRAFT">DRAFT</option>
                <option value="AKTIF">AKTIF</option>
                <option value="TUTUP">TUTUP</option>
              </Select>
            </div>
            <Label className="flex items-center gap-2 text-sm font-normal">
              <input
                type="checkbox"
                checked={tahunForm.template}
                onChange={(event) =>
                  setTahunForm((current) => ({
                    ...current,
                    template: event.target.checked,
                  }))
                }
                className="h-4 w-4 rounded border-input"
              />
              Sertakan kode rekening standar (13 baris)
            </Label>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setTahunOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : "Tambah Template"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus item anggaran?</DialogTitle>
            <DialogDescription>
              Item <span className="font-semibold">{deleteTarget?.uraian}</span> akan dihapus
              dari APBDes {summary?.tahun}.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Batal
            </Button>
            <Button variant="destructive" onClick={removeItem} disabled={deleting}>
              {deleting ? "Menghapus…" : "Hapus"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
