import { useMemo, useState } from "react";
import { FormDialog, val } from "@/components/sip/FormDialog";
import { Section, DataTable } from "@/components/sip/Section";
import { SearchToggleBar, SummaryCards, type ViewMode } from "@/components/sip/FilterBar";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Plus, RotateCcw } from "lucide-react";
import { toast } from "sonner";
import { newId, nowTime, todayISO, useSip, waliKelasOf, type Pelanggaran } from "@/lib/sip-data";

const selectClass =
  "border-input bg-background focus-visible:ring-ring h-10 w-full rounded-md border px-3 text-sm focus-visible:ring-2 focus-visible:outline-none";

/** Semester berjalan: Januari–Juni (Genap) atau Juli–Desember (Ganjil). */
function semesterRange(ref = new Date()) {
  const y = ref.getFullYear();
  const ganjil = ref.getMonth() >= 6;
  return {
    label: ganjil ? `Ganjil ${y}/${y + 1}` : `Genap ${y - 1}/${y}`,
    start: ganjil ? `${y}-07-01` : `${y}-01-01`,
    end: ganjil ? `${y}-12-31` : `${y}-06-30`,
  };
}

function riskLevel(count: number) {
  if (count >= 10) return { cls: "bg-risk-high text-risk-high-foreground", label: "Kritis (≥10)" };
  if (count >= 6) return { cls: "bg-risk-mid text-risk-mid-foreground", label: "Berat (≥6)" };
  if (count >= 3) return { cls: "bg-risk-low text-risk-low-foreground", label: "Perhatian (≥3)" };
  return { cls: "", label: "Aman" };
}

const tingkatDari = (kelas: string) => kelas.split("-")[0] ?? kelas;

export function DataPelanggaran({ context }: { context: string }) {
  const { pelanggaran, setPelanggaran, kelasList, siswa, currentUser } = useSip();
  const isPiket =
    currentUser?.role === "Petugas Piket" ||
    currentUser?.role === "Guru Mapel" ||
    currentUser?.role === "Guru BK" ||
    currentUser?.role === "Waka Kesiswaan";
  const isBk = currentUser?.role === "Guru BK";
  const isWali = context === "rekap_kelas_pelanggaran";
  const myClass = waliKelasOf(currentUser) || "-";

  const semester = useMemo(() => semesterRange(), []);

  const [query, setQuery] = useState("");
  const [view, setView] = useState<ViewMode>("rinci");
  const [fKelas, setFKelas] = useState("");
  const [fNama, setFNama] = useState("");
  const [fDari, setFDari] = useState("");
  const [fSampai, setFSampai] = useState("");
  const [fJam, setFJam] = useState("");
  const [fTingkat, setFTingkat] = useState("");
  const [fRekapKelas, setFRekapKelas] = useState("");

  const base = isWali ? pelanggaran.filter((p) => p.kelas === myClass) : pelanggaran;

  // Akumulasi pelanggaran per siswa dalam satu semester berjalan
  const countPerSiswa = useMemo(() => {
    const map = new Map<string, number>();
    for (const p of pelanggaran) {
      if (p.tanggal < semester.start || p.tanggal > semester.end) continue;
      const key = `${p.nama}||${p.kelas}`;
      map.set(key, (map.get(key) ?? 0) + 1);
    }
    return map;
  }, [pelanggaran, semester]);

  const countOf = (p: Pick<Pelanggaran, "nama" | "kelas">) =>
    countPerSiswa.get(`${p.nama}||${p.kelas}`) ?? 0;

  const filtered = useMemo(() => {
    const qq = query.trim().toLowerCase();
    return base.filter((p) => {
      if (
        qq &&
        !(
          p.nama.toLowerCase().includes(qq) ||
          p.kelas.toLowerCase().includes(qq) ||
          p.jenis.toLowerCase().includes(qq) ||
          p.tindakan.toLowerCase().includes(qq) ||
          p.tanggal.includes(qq) ||
          (p.pelapor ?? "").toLowerCase().includes(qq)
        )
      )
        return false;
      if (!isBk) return true;
      if (fKelas && p.kelas !== fKelas) return false;
      if (fNama && !p.nama.toLowerCase().includes(fNama.trim().toLowerCase())) return false;
      if (fDari && p.tanggal < fDari) return false;
      if (fSampai && p.tanggal > fSampai) return false;
      if (fJam && !p.waktu.startsWith(fJam)) return false;
      return true;
    });
  }, [base, isBk, query, fKelas, fNama, fDari, fSampai, fJam]);

  const rekap = useMemo(() => {
    const rows = Array.from(countPerSiswa.entries()).map(([key, jumlah]) => {
      const [nama = "", kelas = ""] = key.split("||");
      return { nama, kelas, jumlah };
    });
    return rows
      .filter((r) => (fTingkat ? tingkatDari(r.kelas) === fTingkat : true))
      .filter((r) => (fRekapKelas ? r.kelas === fRekapKelas : true))
      .sort((a, b) => b.jumlah - a.jumlah || a.nama.localeCompare(b.nama));
  }, [countPerSiswa, fTingkat, fRekapKelas]);

  const tingkatList = useMemo(
    () => Array.from(new Set(kelasList.map(tingkatDari))).sort(),
    [kelasList],
  );

  const namaCell = (p: Pick<Pelanggaran, "nama" | "kelas">) => {
    const n = countOf(p);
    const risk = riskLevel(n);
    return risk.cls ? (
      <span className={`inline-flex items-center gap-2 rounded-md px-2 py-1 font-semibold ${risk.cls}`}>
        {p.nama}
        <span className="text-[11px] opacity-90">{n}x</span>
      </span>
    ) : (
      <span className="font-semibold">{p.nama}</span>
    );
  };

  const ringkasItems = Array.from(
    filtered.reduce((m, p) => m.set(p.kelas, (m.get(p.kelas) ?? 0) + 1), new Map<string, number>()),
  )
    .sort((a, b) => b[1] - a[1])
    .map(([k, v]) => ({ label: `Kelas ${k}`, value: v }));

  const tabel = (
    <>
      <SearchToggleBar
        query={query}
        onQueryChange={setQuery}
        view={view}
        onViewChange={setView}
        placeholder={
          isBk
            ? "Cari nama / kelas / jenis / tanggal / pelapor..."
            : "Cari nama / kelas / jenis pelanggaran / tanggal..."
        }
      />
      {view === "ringkas" ? (
        <SummaryCards
          total={filtered.length}
          totalLabel="Total Pelanggaran"
          items={ringkasItems}
        />
      ) : (
        <DataTable
          head={
            isBk
              ? ["Waktu", "Nama Siswa", "Kelas", "Jenis Pelanggaran", "Tindakan", "Pelapor"]
              : ["Waktu", "Nama Siswa", "Kelas", "Jenis Pelanggaran", "Tindakan"]
          }
          empty="Tidak ada data pelanggaran."
          rows={filtered.map((p) => [
            <span className="text-muted-foreground whitespace-nowrap">
              {p.tanggal} {p.waktu}
            </span>,
            namaCell(p),
            <Badge variant="secondary">{p.kelas}</Badge>,
            p.jenis,
            p.tindakan,
            ...(isBk
              ? [
                  p.pelapor ? (
                    <Badge variant="outline" className="whitespace-nowrap">
                      {p.pelapor}
                    </Badge>
                  ) : (
                    <span className="text-muted-foreground text-xs">-</span>
                  ),
                ]
              : []),
          ])}
        />
      )}
    </>
  );

  const tambahAction = isPiket ? (
    <FormDialog
      title="Catat Pelanggaran Siswa"
      fields={[
        { name: "kelas", label: "Kelas", type: "select", options: kelasList },
        {
          name: "nama",
          label: "Nama Siswa",
          type: "select",
          options: (values) => siswa.filter((s) => s.kelas === values["kelas"]).map((s) => s.nama),
        },
        { name: "jenis", label: "Jenis Pelanggaran", placeholder: "Contoh: Terlambat" },
        { name: "tindakan", label: "Tindakan", type: "textarea" },
      ]}
      submitLabel="Simpan Pelanggaran"
      onSubmit={(v) => {
        setPelanggaran((prev) => [
          ...prev,
          {
            id: newId("P"),
            tanggal: todayISO(),
            waktu: nowTime(),
            nama: val(v, "nama"),
            kelas: val(v, "kelas"),
            jenis: val(v, "jenis"),
            tindakan: val(v, "tindakan"),
            pelapor: `${currentUser?.nama ?? "-"} · ${currentUser?.role ?? "-"}`,
          },
        ]);
        toast.success("Pelanggaran berhasil dicatat");
      }}
      trigger={
        <Button size="sm" variant="destructive">
          <Plus className="mr-1 h-4 w-4" /> Catat Pelanggaran
        </Button>
      }
    />
  ) : null;

  if (!isBk) {
    return (
      <Section
        title={isWali ? `Pelanggaran Siswa Kelas ${myClass}` : "Data Pelanggaran Siswa"}
        action={tambahAction}
      >
        {tabel}
      </Section>
    );
  }

  return (
    <div className="space-y-6">
      <div className="surface-card flex flex-wrap items-center justify-between gap-3 p-5">
        <div>
          <h3 className="text-lg font-bold">Pembinaan Pelanggaran Siswa</h3>
          <p className="text-muted-foreground text-sm">
            Akumulasi pelanggaran semester {semester.label} ({semester.start} s/d {semester.end}).
          </p>
        </div>
        <div className="flex flex-wrap items-center gap-3">
          {tambahAction}
          <div className="flex flex-wrap gap-2 text-xs">
            <span className="bg-risk-low text-risk-low-foreground rounded-md px-2 py-1 font-semibold">
              3+ Perhatian
            </span>
            <span className="bg-risk-mid text-risk-mid-foreground rounded-md px-2 py-1 font-semibold">
              6+ Berat
            </span>
            <span className="bg-risk-high text-risk-high-foreground rounded-md px-2 py-1 font-semibold">
              10+ Kritis
            </span>
          </div>
        </div>
      </div>

      <Tabs defaultValue="data">
        <TabsList>
          <TabsTrigger value="data">Data Pelanggaran ({filtered.length})</TabsTrigger>
          <TabsTrigger value="rekap">Rekap Siswa ({rekap.length})</TabsTrigger>
        </TabsList>

        <TabsContent value="data" className="mt-4 space-y-4">
          <div className="surface-card grid gap-3 p-5 md:grid-cols-3 lg:grid-cols-5">
            <div className="grid gap-2">
              <Label htmlFor="f-kelas">Kelas</Label>
              <select
                id="f-kelas"
                className={selectClass}
                value={fKelas}
                onChange={(e) => setFKelas(e.target.value)}
              >
                <option value="">Semua Kelas</option>
                {kelasList.map((k) => (
                  <option key={k} value={k}>
                    {k}
                  </option>
                ))}
              </select>
            </div>
            <div className="grid gap-2">
              <Label htmlFor="f-nama">Nama Siswa</Label>
              <Input
                id="f-nama"
                placeholder="Cari nama..."
                value={fNama}
                onChange={(e) => setFNama(e.target.value)}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="f-dari">Tanggal Dari</Label>
              <Input id="f-dari" type="date" value={fDari} onChange={(e) => setFDari(e.target.value)} />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="f-sampai">Tanggal Sampai</Label>
              <Input
                id="f-sampai"
                type="date"
                value={fSampai}
                onChange={(e) => setFSampai(e.target.value)}
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="f-jam">Waktu (jam)</Label>
              <Input
                id="f-jam"
                placeholder="Contoh: 09"
                value={fJam}
                onChange={(e) => setFJam(e.target.value)}
              />
            </div>
            <div className="flex items-end">
              <Button
                variant="secondary"
                onClick={() => {
                  setFKelas("");
                  setFNama("");
                  setFDari("");
                  setFSampai("");
                  setFJam("");
                }}
              >
                <RotateCcw className="mr-2 h-4 w-4" /> Reset Filter
              </Button>
            </div>
          </div>

          <Section title="Data Pelanggaran Siswa">{tabel}</Section>
        </TabsContent>

        <TabsContent value="rekap" className="mt-4 space-y-4">
          <div className="surface-card grid gap-3 p-5 md:grid-cols-3">
            <div className="grid gap-2">
              <Label htmlFor="f-tingkat">Tingkatan Kelas</Label>
              <select
                id="f-tingkat"
                className={selectClass}
                value={fTingkat}
                onChange={(e) => setFTingkat(e.target.value)}
              >
                <option value="">Semua Tingkatan</option>
                {tingkatList.map((t) => (
                  <option key={t} value={t}>
                    Kelas {t}
                  </option>
                ))}
              </select>
            </div>
            <div className="grid gap-2">
              <Label htmlFor="f-rekap-kelas">Per Kelas</Label>
              <select
                id="f-rekap-kelas"
                className={selectClass}
                value={fRekapKelas}
                onChange={(e) => setFRekapKelas(e.target.value)}
              >
                <option value="">Semua Kelas</option>
                {kelasList
                  .filter((k) => (fTingkat ? tingkatDari(k) === fTingkat : true))
                  .map((k) => (
                    <option key={k} value={k}>
                      {k}
                    </option>
                  ))}
              </select>
            </div>
            <div className="flex items-end gap-2">
              <Button
                variant="secondary"
                onClick={() => {
                  setFTingkat("");
                  setFRekapKelas("");
                }}
              >
                <RotateCcw className="mr-2 h-4 w-4" /> Reset
              </Button>
              <Button onClick={() => window.print()}>Cetak Rekap</Button>
            </div>
          </div>

          <Section title={`Rekap Pelanggaran Semester ${semester.label}`}>
            <DataTable
              head={["Nama Siswa", "Kelas", "Jumlah Pelanggaran", "Status Pembinaan"]}
              empty="Belum ada pelanggaran pada filter ini."
              rows={rekap.map((r) => {
                const risk = riskLevel(r.jumlah);
                return [
                  namaCell(r),
                  <Badge variant="secondary">{r.kelas}</Badge>,
                  <span className="font-bold">{r.jumlah}x</span>,
                  risk.cls ? (
                    <span className={`rounded-md px-2 py-1 text-xs font-semibold ${risk.cls}`}>
                      {risk.label}
                    </span>
                  ) : (
                    <span className="text-muted-foreground text-xs">{risk.label}</span>
                  ),
                ];
              })}
            />
          </Section>
        </TabsContent>
      </Tabs>
    </div>
  );
}
