"use client";

import Link from "next/link";
import useSWR from "swr";
import { FilePlus2, Printer, Settings2, Wrench } from "lucide-react";
import { toast } from "sonner";
import type { Desa } from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { cetakHtml, escapeHtml, kopDesa } from "@/lib/cetak";
import {
  SimpleCrud,
  type CrudColumn,
  type CrudField,
  type CrudRow,
} from "@/components/admin/simple-crud";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Select } from "@/components/ui/select";
import { useState } from "react";
import {
  Cell,
  Legend,
  Pie,
  PieChart,
  ResponsiveContainer,
  Tooltip,
} from "recharts";

interface Jenis {
  id: number;
  nama: string;
  kode: string | null;
  lampiran: string | null;
}

const NAMA_BULAN = [
  "Januari",
  "Februari",
  "Maret",
  "April",
  "Mei",
  "Juni",
  "Juli",
  "Agustus",
  "September",
  "Oktober",
  "November",
  "Desember",
];

function useJenis() {
  const { data } = useSWR<Jenis[]>("/master/jenis-surat-dinas", fetcher);
  return data ?? [];
}

export function jenisFields(jenis: Jenis[]): CrudField[] {
  return [
    {
      name: "jenisId",
      label: "Jenis Surat",
      type: "select",
      options: [{ value: "", label: "— Tanpa Jenis —" }].concat(
        jenis.map((item) => ({ value: String(item.id), label: item.nama })),
      ),
    },
    { name: "nomor", label: "Nomor Surat", required: true },
    { name: "tanggal", label: "Tanggal", type: "date", required: true },
    { name: "pengirim", label: "Pengirim" },
    { name: "alamat", label: "Alamat Tujuan", full: true },
    { name: "perihal", label: "Perihal", required: true, full: true },
    { name: "isi", label: "Isi Surat", type: "textarea" },
    { name: "lampiran", label: "Lampiran" },
  ];
}

function hari(value: unknown) {
  return value ? String(value).slice(0, 10) : "";
}

export function SuratDinasList({
  title = "Daftar Surat Dinas",
  description = "Surat dinas keluar yang dibuat oleh pemerintah desa.",
  create = true,
  arsip = false,
}: {
  title?: string;
  description?: string;
  create?: boolean;
  arsip?: boolean;
}) {
  const jenis = useJenis();
  const { data: semua, mutate } = useSWR<CrudRow[]>("/master/surat-dinas", fetcher);
  const { data: desa } = useSWR<Desa>("/desa", fetcher);
  const [jenisId, setJenisId] = useState("");
  const [tahun, setTahun] = useState("");
  const [bulan, setBulan] = useState("");
  const [perbaikiOpen, setPerbaikiOpen] = useState(false);
  const [memperbaiki, setMemperbaiki] = useState(false);

  async function jalankanPerbaiki() {
    const sasaran = (semua ?? []).filter(
      (row) => row.status !== "SELESAI" && row.status !== "DITOLAK",
    );
    if (!sasaran.length) {
      toast.info("Semua arsip sudah berstatus siap cetak.");
      setPerbaikiOpen(false);
      return;
    }
    setMemperbaiki(true);
    try {
      await Promise.all(
        sasaran.map((row) =>
          apiSend(`/master/surat-dinas/${row.id}`, "PATCH", { status: "SELESAI" }),
        ),
      );
      toast.success(`${sasaran.length} arsip diperbaiki menjadi siap cetak`);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal memperbaiki arsip");
    } finally {
      setMemperbaiki(false);
      setPerbaikiOpen(false);
    }
  }

  const daftar = semua ?? [];
  const tahunList = [
    ...new Set(daftar.map((row) => hari(row.tanggal).slice(0, 4)).filter(Boolean)),
  ].sort((a, b) => b.localeCompare(a));
  const adaFilter = Boolean(jenisId || tahun || bulan);

  function labelJenis(row: CrudRow) {
    const item = jenis.find((masuk) => String(masuk.id) === String(row.jenisId));
    return item?.nama ?? "-";
  }

  function kodeJenis(row: CrudRow) {
    const item = jenis.find((masuk) => String(masuk.id) === String(row.jenisId));
    return item?.kode ?? "-";
  }

  const columns: CrudColumn[] = arsip
    ? [
        { name: "kodeSurat", label: "Kode Surat", render: kodeJenis },
        { name: "nomor", label: "No Urut" },
        { name: "jenisSurat", label: "Jenis Surat", render: labelJenis },
        { name: "perihal", label: "Keterangan" },
        { name: "ditandatanganiOleh", label: "Ditandatangani Oleh" },
        { name: "tanggal", label: "Tanggal" },
        { name: "dibuatOleh", label: "User", hideOnMobile: true },
        {
          name: "status",
          label: "Status",
          render: (row: CrudRow) => (
            <Badge variant={row.status === "DITOLAK" ? "danger" : "success"}>
              {String(row.status ?? "-")}
            </Badge>
          ),
        },
        { name: "alasanDitolak", label: "Alasan Ditolak", hideOnMobile: true },
      ]
    : [
        { name: "nomor", label: "Nomor Surat" },
        { name: "kodeSurat", label: "Kode Surat", render: kodeJenis },
        { name: "jenisSurat", label: "Jenis Surat", render: labelJenis },
        { name: "perihal", label: "Keterangan" },
        { name: "pengirim", label: "Pengirim", hideOnMobile: true },
        { name: "tanggal", label: "Tanggal" },
      ];

  function bersihkan() {
    setJenisId("");
    setTahun("");
    setBulan("");
  }

  function cocok(row: CrudRow) {
    if (jenisId && String(row.jenisId) !== jenisId) return false;
    const tanggal = hari(row.tanggal);
    if (tahun && !tanggal.startsWith(tahun)) return false;
    if (bulan && tanggal.slice(5, 7) !== bulan.padStart(2, "0")) return false;
    return true;
  }

  const terfilter = daftar.filter(cocok);

  return (
    <div className="space-y-5">
      <SimpleCrud
      title={title}
      description={description}
      entity="surat-dinas"
      fields={jenisFields(jenis)}
      columns={columns}
      searchFields={["nomor", "perihal", "pengirim", "alamat"]}
      searchPlaceholder="Cari nomor, perihal, atau pengirim…"
      canWrite={create}
      createLabel="Tambah Surat"
      showNo
      selectable
      actionOnLeft
      filter={cocok}
      toolbar={
        <>
          <Select
            value={jenisId}
            onChange={(event) => setJenisId(event.target.value)}
            aria-label="Pilih Jenis Surat"
            className="w-full sm:w-48"
          >
            <option value="">Pilih Jenis Surat</option>
            {jenis.map((item) => (
              <option key={item.id} value={String(item.id)}>
                {item.nama}
              </option>
            ))}
          </Select>
          {arsip && (
            <>
              <Select
                value={tahun}
                onChange={(event) => setTahun(event.target.value)}
                aria-label="Pilih Tahun"
                className="w-full sm:w-32"
              >
                <option value="">Pilih Tahun</option>
                {tahunList.map((item) => (
                  <option key={item} value={item}>
                    {item}
                  </option>
                ))}
              </Select>
              <Select
                value={bulan}
                onChange={(event) => setBulan(event.target.value)}
                aria-label="Pilih Bulan"
                className="w-full sm:w-36"
              >
                <option value="">Pilih Bulan</option>
                {NAMA_BULAN.map((nama, index) => (
                  <option key={nama} value={String(index + 1)}>
                    {nama}
                  </option>
                ))}
              </Select>
            </>
          )}
          {adaFilter && (
            <Button variant="ghost" size="sm" onClick={bersihkan}>
              Bersihkan
            </Button>
          )}
          {arsip && (
            <Button variant="outline" size="sm" onClick={() => setPerbaikiOpen(true)}>
              <Wrench className="h-4 w-4" />
              Perbaiki
            </Button>
          )}
        </>
      }
      ekspor={
        arsip
          ? {
              fileName: "arsip-surat-dinas",
              header: [
                "Kode Surat",
                "No Urut",
                "Jenis Surat",
                "Keterangan",
                "Ditandatangani Oleh",
                "Tanggal",
                "User",
                "Status",
                "Alasan Ditolak",
              ],
              values: (row) => [
                kodeJenis(row),
                String(row.nomor ?? ""),
                labelJenis(row),
                String(row.perihal ?? ""),
                String(row.ditandatanganiOleh ?? ""),
                hari(row.tanggal),
                String(row.dibuatOleh ?? ""),
                String(row.status ?? ""),
                String(row.alasanDitolak ?? ""),
              ],
            }
          : {
              fileName: "daftar-surat-dinas",
              header: ["No Urut", "Kode Surat", "Jenis Surat", "Keterangan", "Pengirim", "Tanggal"],
              values: (row) => [
                String(row.nomor ?? ""),
                kodeJenis(row),
                labelJenis(row),
                String(row.perihal ?? ""),
                String(row.pengirim ?? ""),
                hari(row.tanggal),
              ],
            }
      }
      cetak={(rows) => ({
        judul: arsip ? "Arsip Surat Dinas" : "Daftar Surat Dinas",
        isi: `
          ${kopDesa(desa, arsip ? "Arsip Surat Dinas" : "Daftar Surat Dinas")}
          <table class="info">
            <tr><td>Tahun</td><td>:</td><td>${escapeHtml(tahun || "Semua tahun")}</td></tr>
            <tr><td>Jumlah surat</td><td>:</td><td>${rows.length}</td></tr>
          </table>
          <table>
            <thead><tr><th>No</th>${arsip ? "<th>Kode Surat</th><th>No Urut</th><th>Jenis Surat</th><th>Keterangan</th><th>Ditandatangani Oleh</th><th>Tanggal</th><th>User</th><th>Status</th><th>Alasan Ditolak</th>" : "<th>No Urut</th><th>Kode Surat</th><th>Jenis Surat</th><th>Keterangan</th><th>Pengirim</th><th>Tanggal</th>"}</tr></thead>
            <tbody>
              ${rows
                .map((row, index) =>
                  arsip
                    ? `<tr><td class="num">${index + 1}</td><td>${escapeHtml(kodeJenis(row))}</td><td>${escapeHtml(row.nomor ?? "-")}</td><td>${escapeHtml(labelJenis(row))}</td><td>${escapeHtml(row.perihal ?? "-")}</td><td>${escapeHtml(row.ditandatanganiOleh ?? "-")}</td><td>${escapeHtml(hari(row.tanggal))}</td><td>${escapeHtml(row.dibuatOleh ?? "-")}</td><td>${escapeHtml(row.status ?? "-")}</td><td>${escapeHtml(row.alasanDitolak ?? "-")}</td></tr>`
                    : `<tr><td class="num">${index + 1}</td><td>${escapeHtml(row.nomor ?? "-")}</td><td>${escapeHtml(kodeJenis(row))}</td><td>${escapeHtml(labelJenis(row))}</td><td>${escapeHtml(row.perihal ?? "-")}</td><td>${escapeHtml(row.pengirim ?? "-")}</td><td>${escapeHtml(hari(row.tanggal))}</td></tr>`,
                )
                .join("")}
            </tbody>
          </table>
          <div class="ttd">
            <div>
              <div>${escapeHtml((desa?.kecamatan ?? "Cipari").toUpperCase())}, ${new Date().toLocaleDateString("id-ID", { day: "2-digit", month: "long", year: "numeric" })}</div>
              <div>Kepala Desa ${escapeHtml((desa?.nama ?? "Mulyadadi").replace(/^Desa\s+/i, ""))}</div>
              <div class="ruang"></div>
              <div><strong>${escapeHtml(desa?.kepalaDesa ?? "-")}</strong></div>
            </div>
          </div>
        `,
      })}
      headerExtra={
        create ? (
          <>
            <Button variant="outline" size="sm" asChild>
              <Link href="/admin/surat-dinas/baru">
                <FilePlus2 className="h-4 w-4" />
                Buat Surat Dinas
              </Link>
            </Button>
            <Button variant="outline" size="sm" asChild>
              <Link href="/admin/surat-dinas/jenis">
                <Settings2 className="h-4 w-4" />
                Kelola Jenis
              </Link>
            </Button>
          </>
        ) : undefined
      }
      rowActions={(row: CrudRow) => (
        <Link
          href={`/admin/surat-dinas/cetak/${row.id}`}
          className="rounded-md p-1.5 text-muted-foreground hover:bg-muted hover:text-foreground"
          title="Cetak"
        >
          <Printer className="h-4 w-4" />
        </Link>
      )}
      />
      {arsip && <PieSuratKeluar daftar={terfilter} labelJenis={labelJenis} />}

      <Dialog open={perbaikiOpen} onOpenChange={(open) => !open && setPerbaikiOpen(false)}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Perbaiki Arsip Surat</DialogTitle>
            <DialogDescription>
              Surat yang ada sekarang akan diverifikasi semua. Surat berstatus proses atau
              tanpa status akan diubah menjadi siap cetak. Ingin melanjutkan?
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setPerbaikiOpen(false)}>
              Tidak
            </Button>
            <Button onClick={jalankanPerbaiki} disabled={memperbaiki}>
              <Wrench className="h-4 w-4" /> {memperbaiki ? "Memproses…" : "Ya"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

const PALET_WARNA = [
  "#0f766e",
  "#2563eb",
  "#c026d3",
  "#ea580c",
  "#65a30d",
  "#0891b2",
  "#9333ea",
  "#dc2626",
];

function PieSuratKeluar({
  daftar,
  labelJenis,
}: {
  daftar: CrudRow[];
  labelJenis: (row: CrudRow) => string;
}) {
  const hitung = new Map<string, number>();
  for (const row of daftar) {
    const nama = labelJenis(row);
    hitung.set(nama, (hitung.get(nama) ?? 0) + 1);
  }
  const data = [...hitung.entries()].map(([nama, jumlah]) => ({ nama, jumlah }));

  return (
    <Card>
      <CardHeader>
        <CardTitle className="text-base">Pie Surat Keluar</CardTitle>
      </CardHeader>
      <CardContent>
        {data.length ? (
          <ResponsiveContainer width="100%" height={280}>
            <PieChart>
              <Pie
                data={data}
                dataKey="jumlah"
                nameKey="nama"
                cx="50%"
                cy="50%"
                outerRadius={96}
                label={(props) => `${String(props.name ?? "")}: ${Number(props.value ?? 0)}`}
              >
                {data.map((item, index) => (
                  <Cell key={item.nama} fill={PALET_WARNA[index % PALET_WARNA.length]} />
                ))}
              </Pie>
              <Tooltip />
              <Legend />
            </PieChart>
          </ResponsiveContainer>
        ) : (
          <p className="py-8 text-center text-sm text-muted-foreground">
            Belum ada surat keluar pada filter ini.
          </p>
        )}
      </CardContent>
    </Card>
  );
}

export function SuratDinasJenisPicker() {
  const jenis = useJenis();
  return (
    <Card>
      <CardContent className="p-0">
        <div className="border-b px-4 py-3 text-sm font-semibold">
          Jenis Surat Dinas
        </div>
        <div className="overflow-x-auto">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-14">No</TableHead>
                <TableHead className="w-40">Aksi</TableHead>
                <TableHead>Nama Surat</TableHead>
                <TableHead className="w-44">Kode / Klasifikasi</TableHead>
                <TableHead className="w-40">Lampiran</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {jenis.map((item, index) => (
                <TableRow key={item.id}>
                  <TableCell className="text-muted-foreground">
                    {index + 1}
                  </TableCell>
                  <TableCell>
                    <Button variant="outline" size="sm" asChild>
                      <Link href={`/admin/surat-dinas/baru?jenisId=${item.id}`}>
                        <Printer className="h-4 w-4" />
                        Isi &amp; Cetak
                      </Link>
                    </Button>
                  </TableCell>
                  <TableCell>{item.nama}</TableCell>
                  <TableCell>
                    <span className="rounded-full bg-muted px-2 py-0.5 font-mono text-[11px] text-muted-foreground">
                      {item.kode ?? "-"}
                    </span>
                  </TableCell>
                  <TableCell className="text-sm">{item.lampiran ?? "-"}</TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table>
        </div>
      </CardContent>
    </Card>
  );
}
