import { useRef, useState } from "react";
import { FormDialog, val } from "@/components/sip/FormDialog";
import { Section, DataTable } from "@/components/sip/Section";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Plus, Pencil, Trash2, Download, Upload, Eraser } from "lucide-react";
import { toast } from "sonner";
import { newId, useSip, type Siswa } from "@/lib/sip-data";
import { FilterBar, RekapKelasTable, type ViewMode } from "@/components/sip/FilterBar";

export function DataSiswa() {
  const { siswa, setSiswa, kelasList } = useSip();
  const [filter, setFilter] = useState("");
  const [query, setQuery] = useState("");
  const [view, setView] = useState<ViewMode>("rinci");
  const fileRef = useRef<HTMLInputElement>(null);

  const downloadTemplate = async () => {
    const XLSX = await import("xlsx");
    const ws = XLSX.utils.json_to_sheet([
      { NIS: "10101", Nama: "Andi Saputra", Kelas: kelasList[0] ?? "VII-A", JK: "L" },
    ]);
    ws["!cols"] = [{ wch: 12 }, { wch: 28 }, { wch: 12 }, { wch: 6 }];
    const wb = XLSX.utils.book_new();
    XLSX.utils.book_append_sheet(wb, ws, "Data Siswa");
    XLSX.writeFile(wb, "template-data-siswa.xlsx");
    toast.success("Template Excel diunduh");
  };

  const handleUpload = async (file: File) => {
    try {
      const XLSX = await import("xlsx");
      const wb = XLSX.read(await file.arrayBuffer(), { type: "array" });
      const sheetName = wb.SheetNames[0];
      if (!sheetName) throw new Error("kosong");
      const rows = XLSX.utils.sheet_to_json<Record<string, unknown>>(wb.Sheets[sheetName]!);
      const parsed: Siswa[] = [];
      for (const r of rows) {
        const get = (k: string) =>
          String(
            (r[k] ?? r[k.toUpperCase()] ?? r[k.toLowerCase()] ?? "") as string | number,
          ).trim();
        const nis = get("NIS");
        const nama = get("Nama");
        if (!nis || !nama) continue;
        parsed.push({
          id: newId("S"),
          nis,
          nama,
          kelas: get("Kelas") || (kelasList[0] ?? ""),
          jk: get("JK").toUpperCase() === "P" ? "P" : "L",
        });
      }
      if (parsed.length === 0) {
        toast.error("Tidak ada data valid", { description: "Gunakan template yang disediakan." });
        return;
      }
      setSiswa((prev) => [...prev, ...parsed]);
      toast.success(`${parsed.length} data siswa diimpor`);
    } catch {
      toast.error("Gagal membaca file", { description: "Pastikan file berformat .xlsx atau .xls" });
    }
  };

  const fields = (s?: Siswa) => [
    { name: "nis", label: "NIS", defaultValue: s?.nis },
    { name: "nama", label: "Nama Siswa", defaultValue: s?.nama },
    { name: "kelas", label: "Kelas", type: "select" as const, options: kelasList, defaultValue: s?.kelas },
    { name: "jk", label: "Jenis Kelamin", type: "select" as const, options: ["L", "P"], defaultValue: s?.jk },
  ];

  const q = query.trim().toLowerCase();
  const data = siswa.filter(
    (s) =>
      (!filter || s.kelas === filter) &&
      (!q ||
        s.nama.toLowerCase().includes(q) ||
        s.kelas.toLowerCase().includes(q) ||
        s.nis.includes(q)),
  );
  const hapusSemuaFilter = () => {
    if (data.length === 0) {
      toast.error("Tidak ada data untuk dihapus");
      return;
    }
    const ids = new Set(data.map((s) => s.id));
    setSiswa((prev) => prev.filter((s) => !ids.has(s.id)));
    toast.success(`${ids.size} data siswa dihapus`);
  };

  const kelasRekap = (filter ? [filter] : kelasList).filter(Boolean);

  return (
    <Section
      title="Data Siswa Per Kelas"
      action={
        <div className="flex w-full flex-wrap items-center gap-2 md:w-auto">
          <input
            ref={fileRef}
            type="file"
            accept=".xlsx,.xls"
            className="hidden"
            onChange={(e) => {
              const f = e.target.files?.[0];
              if (f) void handleUpload(f);
              e.target.value = "";
            }}
          />
          <Button size="sm" variant="outline" onClick={() => void downloadTemplate()}>
            <Download className="mr-1 h-4 w-4" /> Template
          </Button>
          <Button size="sm" variant="outline" onClick={() => fileRef.current?.click()}>
            <Upload className="mr-1 h-4 w-4" /> Unggah Excel
          </Button>
          <Button
            size="sm"
            variant="destructive"
            disabled={data.length === 0}
            onClick={() => {
              if (window.confirm(`Hapus ${data.length} data siswa sesuai filter/pencarian saat ini?`))
                hapusSemuaFilter();
            }}
          >
            <Eraser className="mr-1 h-4 w-4" /> Hapus Semua ({data.length})
          </Button>
          <FormDialog
            title="Tambah Data Siswa"
            fields={fields()}
            onSubmit={(v) => {
              setSiswa((prev) => [
                ...prev,
                {
                  id: newId("S"),
                  nis: val(v, "nis"),
                  nama: val(v, "nama"),
                  kelas: val(v, "kelas"),
                  jk: val(v, "jk") === "P" ? "P" : "L",
                },
              ]);
              toast.success("Data siswa ditambahkan");
            }}
            trigger={
              <Button size="sm">
                <Plus className="mr-1 h-4 w-4" /> Tambah Siswa
              </Button>
            }
          />
        </div>
      }
    >
      <FilterBar
        query={query}
        onQueryChange={setQuery}
        kelas={filter}
        onKelasChange={setFilter}
        kelasList={kelasList}
        view={view}
        onViewChange={setView}
        placeholder="Cari nama siswa / NIS / kelas..."
      />
      {view === "ringkas" ? (
        <RekapKelasTable
          kelasList={kelasRekap}
          count={(k) => siswa.filter((s) => s.kelas === k).length}
          label="Siswa"
          extra={(k) =>
            `${siswa.filter((s) => s.kelas === k && s.jk === "L").length} L · ${siswa.filter((s) => s.kelas === k && s.jk === "P").length} P`
          }
        />
      ) : (
      <DataTable
        head={["NIS", "Nama Siswa", "Kelas", "L/P", "Aksi"]}
        alignLast
        empty="Belum ada data siswa pada kelas ini."
        rows={data.map((s) => [
          s.nis,
          <span className="font-medium">{s.nama}</span>,
          <Badge variant="secondary">{s.kelas}</Badge>,
          s.jk,
          <div className="flex justify-center gap-1">
            <FormDialog
              title="Edit Data Siswa"
              fields={fields(s)}
              submitLabel="Update"
              onSubmit={(v) => {
                setSiswa((prev) =>
                  prev.map((x) =>
                    x.id === s.id
                      ? {
                          ...x,
                          nis: val(v, "nis"),
                          nama: val(v, "nama"),
                          kelas: val(v, "kelas"),
                          jk: val(v, "jk") === "P" ? "P" : "L",
                        }
                      : x,
                  ),
                );
                toast.success("Data siswa diperbarui");
              }}
              trigger={
                <Button size="icon" variant="ghost">
                  <Pencil className="h-4 w-4" />
                </Button>
              }
            />
            <Button
              size="icon"
              variant="ghost"
              onClick={() => {
                setSiswa((prev) => prev.filter((x) => x.id !== s.id));
                toast.success("Data siswa dihapus");
              }}
            >
              <Trash2 className="text-destructive h-4 w-4" />
            </Button>
          </div>,
        ])}
      />
      )}
    </Section>
  );
}