"use client";

import { useEffect, useMemo, useState } from "react";
import useSWR from "swr";
import {
  BarChart3,
  Percent,
  Printer,
  TrendingDown,
  TrendingUp,
  Wallet,
} from "lucide-react";
import type { AnggaranItem, KeuanganSummary, TahunAnggaran } from "@/lib/types";
import { 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 { 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 {
  formatCompactRupiah,
  formatNumber,
  formatRupiah,
  labelJenisAnggaran,
} from "@/lib/utils";

function persen(realisasi: number, anggaran: number) {
  if (!anggaran) return 0;
  return Math.round((realisasi / anggaran) * 100);
}

const JENIS = ["PENDAPATAN", "BELANJA", "PEMBIAYAAN"] as const;

export default function KeuanganLaporanPage() {
  const { data: tahunList } = useSWR<TahunAnggaran[]>("/keuangan/tahun", fetcher);
  const [tahun, setTahun] = useState("");
  const [filterKode, setFilterKode] = useState("");

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

  const key = tahun
    ? `/keuangan/ringkasan?tahun=${tahun}`
    : "/keuangan/ringkasan";
  const { data: summary, isLoading } = useSWR<KeuanganSummary>(key, fetcher);

  const items = useMemo(
    () =>
      (summary?.items ?? [])
        .filter((item) => cocokKode(item.kode, filterKode))
        .sort((a, b) => bandingkanKode(a.kode, b.kode)),
    [summary?.items, filterKode],
  );

  const ringkasan = useMemo(() => {
    const totals: Record<AnggaranItem["jenis"], number> = {
      PENDAPATAN: 0,
      BELANJA: 0,
      PEMBIAYAAN: 0,
    };
    const realisasi: Record<AnggaranItem["jenis"], number> = {
      PENDAPATAN: 0,
      BELANJA: 0,
      PEMBIAYAAN: 0,
    };
    const bidangMap = new Map<string, { anggaran: number; realisasi: number }>();
    for (const item of items) {
      totals[item.jenis] += Number(item.anggaran);
      realisasi[item.jenis] += Number(item.realisasi);
      if (item.jenis === "BELANJA") {
        const nama = item.bidang ?? "Lainnya";
        const saatIni = bidangMap.get(nama) ?? { anggaran: 0, realisasi: 0 };
        saatIni.anggaran += Number(item.anggaran);
        saatIni.realisasi += Number(item.realisasi);
        bidangMap.set(nama, saatIni);
      }
    }
    return {
      totals,
      realisasi,
      bidang: [...bidangMap.entries()].map(([bidang, nilai]) => ({
        bidang,
        ...nilai,
      })),
    };
  }, [items]);

  const { totals, realisasi } = ringkasan;

  const donut = useMemo(
    () =>
      JENIS.map((jenis) => ({
        name: labelJenisAnggaran(jenis),
        value: totals[jenis],
      })),
    [totals],
  );

  const { bidang } = ringkasan;
  const totalBidangAnggaran = bidang.reduce((sum, item) => sum + item.anggaran, 0);
  const totalBidangRealisasi = bidang.reduce(
    (sum, item) => sum + item.realisasi,
    0,
  );

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Laporan"
        description="Grafik dan rincian realisasi pelaksanaan APBDes per bidang."
        action={
          <Button variant="outline" onClick={() => window.print()}>
            <Printer className="h-4 w-4" />
            Cetak
          </Button>
        }
      />

      <KeuanganTabs />

      <div className="hidden print:block">
        <h1 className="text-center text-lg font-bold uppercase">
          Pemerintah Desa Mulyadadi
        </h1>
        <p className="text-center text-sm">
          Kecamatan Cipari, Kabupaten Cilacap
        </p>
        <h2 className="mt-4 text-center text-base font-semibold">
          Laporan Realisasi APBDes Tahun Anggaran {summary?.tahun ?? "-"}
        </h2>
      </div>

      <div className="flex flex-wrap items-end gap-3 print:hidden">
        <div className="space-y-1.5">
          <Label className="text-xs uppercase tracking-wide text-muted-foreground">
            Tahun anggaran
          </Label>
          <Select
            value={tahun}
            onChange={(event) => setTahun(event.target.value)}
            className="w-48"
            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>
        <div className="space-y-1.5">
          <Label className="text-xs uppercase tracking-wide text-muted-foreground">
            Jenis anggaran
          </Label>
          <Select
            value={filterKode}
            onChange={(event) => setFilterKode(event.target.value)}
            className="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>
      </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>
      ) : !summary?.tahun ? (
        <Card>
          <CardContent className="py-16 text-center">
            <p className="font-semibold">Belum ada data anggaran</p>
            <p className="mt-1 text-sm text-muted-foreground">
              Tambahkan tahun anggaran dan rincian APBDes pada menu Input Data.
            </p>
          </CardContent>
        </Card>
      ) : (
        <>
          <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)} · ${persen(realisasi.PENDAPATAN, totals.PENDAPATAN)}%`}
              icon={TrendingUp}
              tone="emerald"
            />
            <StatCard
              title="Belanja"
              value={formatCompactRupiah(totals.BELANJA)}
              hint={`Realisasi ${formatCompactRupiah(realisasi.BELANJA)} · ${persen(realisasi.BELANJA, totals.BELANJA)}%`}
              icon={TrendingDown}
              tone="sky"
            />
            <StatCard
              title="Pembiayaan"
              value={formatCompactRupiah(totals.PEMBIAYAAN)}
              hint={`Realisasi ${formatCompactRupiah(realisasi.PEMBIAYAAN)}`}
              icon={Wallet}
              tone="amber"
            />
            <StatCard
              title="Realisasi belanja"
              value={`${persen(realisasi.BELANJA, totals.BELANJA)}%`}
              hint={`${formatNumber(items.length)} item anggaran`}
              icon={Percent}
              tone="violet"
            />
          </div>

          <div className="grid gap-4 lg:grid-cols-5">
            <Card className="lg:col-span-2">
              <CardHeader>
                <CardTitle>Komposisi anggaran</CardTitle>
              </CardHeader>
              <CardContent>
                <BudgetDonut data={donut} />
              </CardContent>
            </Card>
            <Card className="lg:col-span-3">
              <CardHeader>
                <CardTitle>Anggaran & realisasi per bidang</CardTitle>
              </CardHeader>
              <CardContent>
                <BudgetByBidang data={bidang} />
              </CardContent>
            </Card>
          </div>

          <Card>
            <CardHeader>
              <CardTitle>Rincian realisasi per bidang</CardTitle>
            </CardHeader>
            <CardContent className="p-0">
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Bidang</TableHead>
                      <TableHead className="text-right">Anggaran</TableHead>
                      <TableHead className="text-right">Realisasi</TableHead>
                      <TableHead className="text-right">Sisa</TableHead>
                      <TableHead className="text-right">%</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {bidang.map((item) => {
                      const sisa = item.anggaran - item.realisasi;
                      return (
                        <TableRow key={item.bidang}>
                          <TableCell className="font-medium">{item.bidang}</TableCell>
                          <TableCell className="text-right font-mono text-xs">
                            {formatRupiah(item.anggaran)}
                          </TableCell>
                          <TableCell className="text-right font-mono text-xs">
                            {formatRupiah(item.realisasi)}
                          </TableCell>
                          <TableCell className="text-right font-mono text-xs">
                            {formatRupiah(sisa)}
                          </TableCell>
                          <TableCell className="text-right text-xs font-semibold">
                            {persen(item.realisasi, item.anggaran)}%
                          </TableCell>
                        </TableRow>
                      );
                    })}
                    {!bidang.length && (
                      <TableRow>
                        <TableCell colSpan={5} className="py-10 text-center text-sm text-muted-foreground">
                          Belum ada item belanja per bidang.
                        </TableCell>
                      </TableRow>
                    )}
                  </TableBody>
                  {bidang.length > 0 && (
                    <TableBody className="border-t-2 border-border bg-muted/40">
                      <TableRow>
                        <TableCell className="font-semibold">Jumlah</TableCell>
                        <TableCell className="text-right font-mono text-xs font-semibold">
                          {formatRupiah(totalBidangAnggaran)}
                        </TableCell>
                        <TableCell className="text-right font-mono text-xs font-semibold">
                          {formatRupiah(totalBidangRealisasi)}
                        </TableCell>
                        <TableCell className="text-right font-mono text-xs font-semibold">
                          {formatRupiah(totalBidangAnggaran - totalBidangRealisasi)}
                        </TableCell>
                        <TableCell className="text-right text-xs font-semibold">
                          {persen(totalBidangRealisasi, totalBidangAnggaran)}%
                        </TableCell>
                      </TableRow>
                    </TableBody>
                  )}
                </Table>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Ringkasan per jenis</CardTitle>
            </CardHeader>
            <CardContent className="p-0">
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead>Jenis</TableHead>
                      <TableHead className="text-right">Anggaran</TableHead>
                      <TableHead className="text-right">Realisasi</TableHead>
                      <TableHead className="text-right">%</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {JENIS.map((jenis) => (
                      <TableRow key={jenis}>
                        <TableCell className="font-medium">
                          {labelJenisAnggaran(jenis)}
                        </TableCell>
                        <TableCell className="text-right font-mono text-xs">
                          {formatRupiah(totals[jenis])}
                        </TableCell>
                        <TableCell className="text-right font-mono text-xs">
                          {formatRupiah(realisasi[jenis])}
                        </TableCell>
                        <TableCell className="text-right text-xs font-semibold">
                          {persen(realisasi[jenis], totals[jenis])}%
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </div>
            </CardContent>
          </Card>

          <Card>
            <CardHeader>
              <CardTitle>Rincian APBDes</CardTitle>
            </CardHeader>
            <CardContent className="p-0">
              <div className="overflow-x-auto">
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-12">No</TableHead>
                      <TableHead className="w-28">Kode Rekening</TableHead>
                      <TableHead className="min-w-[240px]">Uraian</TableHead>
                      <TableHead className="text-right">Anggaran</TableHead>
                      <TableHead className="text-right">Realisasi</TableHead>
                      <TableHead className="text-right">Sisa</TableHead>
                      <TableHead className="text-right">%</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {items.map((item, index) => {
                      const pagu = Number(item.anggaran);
                      const real = Number(item.realisasi);
                      return (
                        <TableRow key={item.id}>
                          <TableCell className="text-xs text-muted-foreground">
                            {index + 1}
                          </TableCell>
                          <TableCell className="font-mono text-xs">
                            {item.kode}
                          </TableCell>
                          <TableCell className="text-sm">{item.uraian}</TableCell>
                          <TableCell className="whitespace-nowrap text-right font-mono text-xs">
                            {formatRupiah(pagu)}
                          </TableCell>
                          <TableCell className="whitespace-nowrap text-right font-mono text-xs">
                            {formatRupiah(real)}
                          </TableCell>
                          <TableCell className="whitespace-nowrap text-right font-mono text-xs">
                            {formatRupiah(pagu - real)}
                          </TableCell>
                          <TableCell className="text-right text-xs font-semibold">
                            {persen(real, pagu)}%
                          </TableCell>
                        </TableRow>
                      );
                    })}
                    {!items.length && (
                      <TableRow>
                        <TableCell
                          colSpan={7}
                          className="py-10 text-center text-sm text-muted-foreground"
                        >
                          Tidak ada item untuk filter ini.
                        </TableCell>
                      </TableRow>
                    )}
                  </TableBody>
                </Table>
              </div>
              <p className="border-t p-3 text-xs text-muted-foreground">
                {formatNumber(items.length)} item anggaran
                {filterKode ? ` · kode rekening ${filterKode}` : ""}
              </p>
            </CardContent>
          </Card>

          <p className="flex items-center gap-2 text-xs text-muted-foreground">
            <BarChart3 className="h-3.5 w-3.5" />
            Sumber data: rincian APBDes pada menu Input Data.
          </p>
        </>
      )}
    </div>
  );
}
