"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import Link from "next/link";
import useSWR from "swr";
import {
  AlertTriangle,
  CheckCircle2,
  Download,
  FileSpreadsheet,
  Upload,
} from "lucide-react";
import { toast } from "sonner";
import type { TahunAnggaran } from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import {
  TEMPLATE_IMPOR_CSV,
  parseImporAnggaran,
  type AnggaranImporRow,
} from "@/lib/keuangan-import";
import { PageHeader, StatCard } from "@/components/page-header";
import { KeuanganTabs } from "@/components/admin/keuangan-tabs";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
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 {
  formatNumber,
  formatRupiah,
  labelJenisAnggaran,
} from "@/lib/utils";

const JENIS_VARIANT: Record<string, "success" | "warning" | "info"> = {
  PENDAPATAN: "success",
  BELANJA: "warning",
  PEMBIAYAAN: "info",
};

export default function KeuanganImporPage() {
  const { data: tahunList, mutate: mutateTahun } = useSWR<TahunAnggaran[]>(
    "/keuangan/tahun",
    fetcher,
  );
  const [tahun, setTahun] = useState("");
  const [fileName, setFileName] = useState("");
  const [rows, setRows] = useState<AnggaranImporRow[]>([]);
  const [errors, setErrors] = useState<string[]>([]);
  const [importing, setImporting] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  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 totalAnggaran = rows.reduce((sum, row) => sum + row.anggaran, 0);
  const totalRealisasi = rows.reduce((sum, row) => sum + row.realisasi, 0);

  function unduhTemplate() {
    const blob = new Blob([`\uFEFF${TEMPLATE_IMPOR_CSV}`], {
      type: "text/csv;charset=utf-8",
    });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = "template-impor-apbdes.csv";
    link.click();
    URL.revokeObjectURL(url);
  }

  async function bacaBerkas(event: React.ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    if (!file) return;
    const text = await file.text();
    const hasil = parseImporAnggaran(text);
    setFileName(file.name);
    setRows(hasil.rows);
    setErrors(hasil.errors);
    if (!hasil.rows.length) {
      toast.error("Tidak ada baris valid pada berkas");
    } else {
      toast.success(`${hasil.rows.length} baris siap diimpor`);
    }
    if (fileRef.current) fileRef.current.value = "";
  }

  async function impor() {
    if (!activeYear) {
      toast.error("Pilih tahun anggaran terlebih dahulu");
      return;
    }
    if (!rows.length) {
      toast.error("Unggah berkas CSV terlebih dahulu");
      return;
    }
    setImporting(true);
    try {
      const result = await apiSend<{
        ditambah: number;
        diperbarui: number;
        dilewati: number;
      }>("/keuangan/impor", "POST", {
        tahunId: activeYear.id,
        items: rows,
      });
      toast.success(
        `${formatNumber(result.ditambah)} item baru, ${formatNumber(result.diperbarui)} item diperbarui`,
      );
      setRows([]);
      setErrors([]);
      setFileName("");
      await mutateTahun();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal impor data");
    } finally {
      setImporting(false);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Impor Data"
        description="Unggah rincian APBDes dari berkas CSV. Item dengan kode rekening yang sama akan diperbarui otomatis."
        action={
          <Button variant="outline" asChild>
            <Link href="/admin/keuangan">
              <FileSpreadsheet className="h-4 w-4" />
              Buka Input Data
            </Link>
          </Button>
        }
      />

      <KeuanganTabs />

      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
        <StatCard
          title="Baris siap impor"
          value={formatNumber(rows.length)}
          hint={fileName || "Belum ada berkas"}
          icon={Upload}
          tone="sky"
        />
        <StatCard
          title="Baris bermasalah"
          value={formatNumber(errors.length)}
          hint="Tidak akan diimpor"
          icon={AlertTriangle}
          tone="amber"
        />
        <StatCard
          title="Total anggaran"
          value={formatRupiah(totalAnggaran)}
          hint="Dari baris valid"
          icon={FileSpreadsheet}
        />
        <StatCard
          title="Total realisasi"
          value={formatRupiah(totalRealisasi)}
          hint="Dari baris valid"
          icon={CheckCircle2}
          tone="violet"
        />
      </div>

      <Card>
        <CardHeader>
          <CardTitle>Berkas impor</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid gap-4 md:grid-cols-3">
            <div className="space-y-1.5">
              <Label className="text-xs">Tahun anggaran</Label>
              <Select
                value={tahun}
                onChange={(event) => setTahun(event.target.value)}
                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 md:col-span-2">
              <Label className="text-xs">Berkas CSV</Label>
              <div className="flex flex-wrap items-center gap-2">
                <Input
                  ref={fileRef}
                  type="file"
                  accept=".csv,text/csv"
                  onChange={bacaBerkas}
                  className="max-w-sm cursor-pointer"
                />
                <Button variant="outline" type="button" onClick={unduhTemplate}>
                  <Download className="h-4 w-4" />
                  Template CSV
                </Button>
              </div>
              <p className="text-xs text-muted-foreground">
                Kolom: Kode, Uraian, Jenis (PENDAPATAN/BELANJA/PEMBIAYAAN),
                Bidang, Sumber Dana, Anggaran, Realisasi. Pemisah koma atau
                titik koma.
              </p>
            </div>
          </div>

          {errors.length > 0 && (
            <div className="rounded-lg border border-amber-200 bg-amber-50 p-3 text-sm text-amber-900">
              <p className="font-semibold">
                {errors.length} baris dilewati
              </p>
              <ul className="mt-1 max-h-32 list-disc space-y-0.5 overflow-y-auto pl-5 text-xs">
                {errors.slice(0, 20).map((pesan) => (
                  <li key={pesan}>{pesan}</li>
                ))}
                {errors.length > 20 && <li>… dan {errors.length - 20} lainnya</li>}
              </ul>
            </div>
          )}

          <div className="flex flex-wrap items-center justify-between gap-3">
            <p className="text-sm text-muted-foreground">
              {activeYear
                ? `Impor ke tahun anggaran ${activeYear.tahun}`
                : "Buat tahun anggaran terlebih dahulu"}
            </p>
            <Button onClick={impor} disabled={!rows.length || importing || !activeYear}>
              <Upload className="h-4 w-4" />
              {importing ? "Mengimpor…" : `Impor ${rows.length || ""} Baris`}
            </Button>
          </div>
        </CardContent>
      </Card>

      {rows.length > 0 && (
        <Card>
          <CardHeader>
            <CardTitle>Pratinjau {fileName || "berkas"}</CardTitle>
          </CardHeader>
          <CardContent className="p-0">
            <div className="overflow-x-auto">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Kode</TableHead>
                    <TableHead className="min-w-[220px]">Uraian</TableHead>
                    <TableHead>Jenis</TableHead>
                    <TableHead>Bidang</TableHead>
                    <TableHead>Sumber Dana</TableHead>
                    <TableHead className="text-right">Anggaran</TableHead>
                    <TableHead className="text-right">Realisasi</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {rows.slice(0, 50).map((row, index) => (
                    <TableRow key={`${row.kode}-${index}`}>
                      <TableCell className="font-mono text-xs">{row.kode}</TableCell>
                      <TableCell className="text-sm">{row.uraian}</TableCell>
                      <TableCell>
                        <Badge variant={JENIS_VARIANT[row.jenis] ?? "secondary"}>
                          {labelJenisAnggaran(row.jenis)}
                        </Badge>
                      </TableCell>
                      <TableCell className="text-xs">{row.bidang ?? "-"}</TableCell>
                      <TableCell className="text-xs">{row.sumberDana ?? "-"}</TableCell>
                      <TableCell className="whitespace-nowrap text-right font-mono text-xs">
                        {formatRupiah(row.anggaran)}
                      </TableCell>
                      <TableCell className="whitespace-nowrap text-right font-mono text-xs">
                        {formatRupiah(row.realisasi)}
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </div>
            {rows.length > 50 && (
              <p className="border-t p-3 text-center text-xs text-muted-foreground">
                Menampilkan 50 dari {formatNumber(rows.length)} baris.
              </p>
            )}
          </CardContent>
        </Card>
      )}
    </div>
  );
}
