"use client";

import { useMemo, useState } from "react";
import useSWR from "swr";
import {
  CalendarCheck,
  CalendarX2,
  FilePenLine,
  FileSpreadsheet,
  Plus,
  Printer,
  Timer,
  Trash2,
  UserCheck,
} from "lucide-react";
import { toast } from "sonner";
import type {
  Kehadiran,
  KehadiranResponse,
  StatusKehadiran,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { unduhCsv } from "@/lib/sekretariat";
import { useSession } from "@/lib/use-session";
import { PageHeader, StatCard } from "@/components/page-header";
import { KopLaporan } from "@/components/admin/kop-laporan";
import { PengaturanKehadiran } from "@/components/admin/pengaturan-kehadiran";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
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 { Textarea } from "@/components/ui/textarea";
import { formatDateShort, formatNumber } from "@/lib/utils";
import {
  STATUS_KEHADIRAN_OPTIONS,
  badgeStatusKehadiran,
  labelStatusKehadiran,
  selisihJam,
} from "@/lib/kehadiran";

function toInput(date: Date) {
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${date.getFullYear()}-${month}-${day}`;
}

const today = new Date();
const awalDefault = new Date(today);
awalDefault.setDate(today.getDate() - 29);

type FormState = {
  perangkatId: string;
  tanggal: string;
  status: StatusKehadiran;
  jamMasuk: string;
  jamKeluar: string;
  keterangan: string;
};

function emptyForm(): FormState {
  return {
    perangkatId: "",
    tanggal: toInput(new Date()),
    status: "HADIR",
    jamMasuk: "08:00",
    jamKeluar: "15:00",
    keterangan: "",
  };
}

export default function RekapitulasiKehadiranPage() {
  const { user } = useSession();
  const canMutate = user?.role === "ADMIN" || user?.role === "OPERATOR";

  const [awal, setAwal] = useState(toInput(awalDefault));
  const [akhir, setAkhir] = useState(toInput(today));
  const [perangkatFilter, setPerangkatFilter] = useState("");
  const [statusFilter, setStatusFilter] = useState("");

  const key = useMemo(() => {
    const params = new URLSearchParams({ awal, akhir });
    if (perangkatFilter) params.set("perangkatId", perangkatFilter);
    if (statusFilter) params.set("status", statusFilter);
    return `/kehadiran?${params.toString()}`;
  }, [awal, akhir, perangkatFilter, statusFilter]);

  const { data, isLoading, mutate } = useSWR<KehadiranResponse>(key, fetcher);
  const daftar = data?.data ?? [];

  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<Kehadiran | null>(null);
  const [form, setForm] = useState<FormState>(emptyForm);
  const [saving, setSaving] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<Kehadiran | null>(null);
  const [deleting, setDeleting] = useState(false);

  const tidakHadir = data
    ? data.ringkasan.izin +
      data.ringkasan.sakit +
      data.ringkasan.cuti +
      data.ringkasan.dinasLuar +
      data.ringkasan.alpa
    : 0;

  function openCreate() {
    setEditing(null);
    const next = emptyForm();
    next.perangkatId = data?.perangkat[0]?.id ? String(data.perangkat[0].id) : "";
    setForm(next);
    setFormOpen(true);
  }

  function openEdit(item: Kehadiran) {
    setEditing(item);
    setForm({
      perangkatId: String(item.perangkatId),
      tanggal: item.tanggal.slice(0, 10),
      status: item.status,
      jamMasuk: item.jamMasuk ?? "",
      jamKeluar: item.jamKeluar ?? "",
      keterangan: item.keterangan ?? "",
    });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!form.perangkatId) {
      toast.error("Pilih perangkat desa terlebih dahulu");
      return;
    }
    setSaving(true);
    try {
      const payload = {
        perangkatId: Number(form.perangkatId),
        tanggal: form.tanggal,
        status: form.status,
        jamMasuk: form.jamMasuk || null,
        jamKeluar: form.jamKeluar || null,
        ...(form.keterangan ? { keterangan: form.keterangan } : { keterangan: "" }),
      };
      if (editing) {
        await apiSend(`/kehadiran/${editing.id}`, "PATCH", payload);
        toast.success("Catatan kehadiran diperbarui");
      } else {
        await apiSend("/kehadiran", "POST", payload);
        toast.success("Catatan kehadiran ditambahkan");
      }
      setFormOpen(false);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menyimpan data");
    } finally {
      setSaving(false);
    }
  }

  function eksporExcel() {
    if (!daftar.length) {
      toast.error("Tidak ada data untuk diekspor");
      return;
    }
    unduhCsv(
      `rekapitulasi-kehadiran-${awal}-${akhir}.csv`,
      ["No", "Nama", "Jabatan", "Tanggal", "Jam masuk", "Jam keluar", "Total waktu", "Status", "Keterangan"],
      daftar.map((item, index) => [
        index + 1,
        item.perangkat.nama,
        item.perangkat.jabatan,
        item.tanggal.slice(0, 10),
        item.jamMasuk ?? "",
        item.jamKeluar ?? "",
        selisihJam(item.jamMasuk, item.jamKeluar),
        labelStatusKehadiran(item.status),
        item.keterangan ?? "",
      ]),
    );
    toast.success(`${daftar.length} data diekspor`);
  }

  async function remove() {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await apiSend(`/kehadiran/${deleteTarget.id}`, "DELETE");
      toast.success("Catatan kehadiran dihapus");
      setDeleteTarget(null);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menghapus data");
    } finally {
      setDeleting(false);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <div className="no-print">
        <PageHeader
          title="Rekapitulasi Kehadiran"
          description="Log kehadiran perangkat desa beserta rekap status dalam rentang tanggal."
          action={
            <div className="flex flex-wrap gap-2">
              <Button variant="outline" onClick={eksporExcel}>
                <FileSpreadsheet className="h-4 w-4" />
                Ekspor ke excel
              </Button>
              <Button variant="outline" onClick={() => window.print()}>
                <Printer className="h-4 w-4" />
                Cetak
              </Button>
              <PengaturanKehadiran />
              {canMutate && (
                <Button onClick={openCreate} disabled={!data?.perangkat.length}>
                  <Plus className="h-4 w-4" />
                  Catat Kehadiran
                </Button>
              )}
            </div>
          }
        />
      </div>

      <KopLaporan
        title="Rekapitulasi Kehadiran Perangkat Desa"
        subtitle={`${formatDateShort(awal)} – ${formatDateShort(akhir)}`}
      />

      {isLoading || !data ? (
        <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>
      ) : (
        <>
          <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            <StatCard
              title="Total catatan"
              value={formatNumber(data.ringkasan.total)}
              hint="Baris kehadiran terfilter"
              icon={CalendarCheck}
            />
            <StatCard
              title="Hadir"
              value={formatNumber(data.ringkasan.hadir)}
              hint={`${formatNumber(data.ringkasan.terlambat)} terlambat`}
              icon={UserCheck}
              tone="sky"
            />
            <StatCard
              title="Terlambat"
              value={formatNumber(data.ringkasan.terlambat)}
              hint="Melewati jam masuk"
              icon={Timer}
              tone="amber"
            />
            <StatCard
              title="Tidak hadir"
              value={formatNumber(tidakHadir)}
              hint="Izin, sakit, cuti, dinas, alpa"
              icon={CalendarX2}
              tone="violet"
            />
          </div>

          <Card>
            <CardContent className="space-y-4 p-4">
              <div className="no-print grid gap-3 sm:grid-cols-2 xl:grid-cols-4">
                <div className="space-y-1.5">
                  <Label htmlFor="awal">Dari tanggal</Label>
                  <Input
                    id="awal"
                    type="date"
                    value={awal}
                    onChange={(event) => setAwal(event.target.value)}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="akhir">Sampai tanggal</Label>
                  <Input
                    id="akhir"
                    type="date"
                    value={akhir}
                    onChange={(event) => setAkhir(event.target.value)}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="perangkat">Perangkat</Label>
                  <Select
                    id="perangkat"
                    value={perangkatFilter}
                    onChange={(event) => setPerangkatFilter(event.target.value)}
                  >
                    <option value="">Semua perangkat</option>
                    {data.perangkat.map((item) => (
                      <option key={item.id} value={item.id}>
                        {item.nama}
                      </option>
                    ))}
                  </Select>
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="status">Status</Label>
                  <Select
                    id="status"
                    value={statusFilter}
                    onChange={(event) => setStatusFilter(event.target.value)}
                  >
                    <option value="">Semua status</option>
                    {STATUS_KEHADIRAN_OPTIONS.map((option) => (
                      <option key={option.value} value={option.value}>
                        {option.label}
                      </option>
                    ))}
                  </Select>
                </div>
              </div>

              {daftar.length ? (
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-14">No</TableHead>
                      <TableHead>Nama</TableHead>
                      <TableHead>Jabatan</TableHead>
                      <TableHead>Tanggal</TableHead>
                      <TableHead>Jam masuk</TableHead>
                      <TableHead>Jam keluar</TableHead>
                      <TableHead>Total waktu</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead className="hidden lg:table-cell">Keterangan</TableHead>
                      {canMutate && <TableHead className="text-right">Aksi</TableHead>}
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {daftar.map((item, index) => (
                      <TableRow key={item.id}>
                        <TableCell className="text-muted-foreground">{index + 1}</TableCell>
                        <TableCell className="font-medium">{item.perangkat.nama}</TableCell>
                        <TableCell className="text-muted-foreground">
                          {item.perangkat.jabatan}
                        </TableCell>
                        <TableCell className="whitespace-nowrap text-muted-foreground">
                          {formatDateShort(item.tanggal)}
                        </TableCell>
                        <TableCell className="font-mono text-sm">
                          {item.jamMasuk ?? "-"}
                        </TableCell>
                        <TableCell className="font-mono text-sm">
                          {item.jamKeluar ?? "-"}
                        </TableCell>
                        <TableCell className="text-muted-foreground">
                          {selisihJam(item.jamMasuk, item.jamKeluar)}
                        </TableCell>
                        <TableCell>
                          <Badge variant={badgeStatusKehadiran(item.status)}>
                            {labelStatusKehadiran(item.status)}
                          </Badge>
                        </TableCell>
                        <TableCell className="hidden max-w-[220px] truncate text-muted-foreground lg:table-cell">
                          {item.keterangan ?? "-"}
                        </TableCell>
                        {canMutate && (
                          <TableCell>
                            <div className="flex justify-end gap-1">
                              <Button
                                variant="ghost"
                                size="icon"
                                onClick={() => openEdit(item)}
                                aria-label="Ubah kehadiran"
                              >
                                <FilePenLine className="h-4 w-4" />
                              </Button>
                              <Button
                                variant="ghost"
                                size="icon"
                                onClick={() => setDeleteTarget(item)}
                                aria-label="Hapus kehadiran"
                              >
                                <Trash2 className="h-4 w-4 text-destructive" />
                              </Button>
                            </div>
                          </TableCell>
                        )}
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              ) : (
                <p className="py-10 text-center text-sm text-muted-foreground">
                  Tidak ada catatan kehadiran pada filter ini.
                </p>
              )}
            </CardContent>
          </Card>
        </>
      )}

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-h-[90vh] max-w-xl overflow-y-auto">
          <DialogHeader>
            <DialogTitle>
              {editing ? "Ubah Kehadiran" : "Catat Kehadiran"}
            </DialogTitle>
            <DialogDescription>
              Simpan kehadiran harian perangkat desa beserta jam masuk dan keluar.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-1.5 sm:col-span-2">
                <Label htmlFor="perangkatForm">Perangkat desa</Label>
                <Select
                  id="perangkatForm"
                  value={form.perangkatId}
                  onChange={(event) =>
                    setForm({ ...form, perangkatId: event.target.value })
                  }
                  required
                >
                  <option value="">Pilih perangkat</option>
                  {(data?.perangkat ?? []).map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.nama} — {item.jabatan}
                    </option>
                  ))}
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="tanggalForm">Tanggal</Label>
                <Input
                  id="tanggalForm"
                  type="date"
                  value={form.tanggal}
                  onChange={(event) => setForm({ ...form, tanggal: event.target.value })}
                  required
                />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="statusForm">Status</Label>
                <Select
                  id="statusForm"
                  value={form.status}
                  onChange={(event) =>
                    setForm({ ...form, status: event.target.value as StatusKehadiran })
                  }
                >
                  {STATUS_KEHADIRAN_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="jamMasukForm">Jam masuk</Label>
                <Input
                  id="jamMasukForm"
                  type="time"
                  value={form.jamMasuk}
                  onChange={(event) => setForm({ ...form, jamMasuk: event.target.value })}
                />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="jamKeluarForm">Jam keluar</Label>
                <Input
                  id="jamKeluarForm"
                  type="time"
                  value={form.jamKeluar}
                  onChange={(event) => setForm({ ...form, jamKeluar: event.target.value })}
                />
              </div>
              <div className="space-y-1.5 sm:col-span-2">
                <Label htmlFor="keteranganForm">Keterangan</Label>
                <Textarea
                  id="keteranganForm"
                  value={form.keterangan}
                  onChange={(event) =>
                    setForm({ ...form, keterangan: event.target.value })
                  }
                  rows={2}
                  placeholder="Opsional, misalnya alasan izin atau dinas luar"
                />
              </div>
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setFormOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan..." : "Simpan"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus catatan kehadiran?</DialogTitle>
            <DialogDescription>
              Catatan {deleteTarget?.perangkat.nama} tanggal{" "}
              {deleteTarget ? formatDateShort(deleteTarget.tanggal) : ""} akan dihapus
              permanen.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Batal
            </Button>
            <Button variant="destructive" onClick={remove} disabled={deleting}>
              {deleting ? "Menghapus..." : "Hapus"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
