"use client";

import { useMemo, useState } from "react";
import useSWR from "swr";
import {
  CalendarClock,
  Clock,
  FilePenLine,
  Plus,
  Printer,
  Timer,
  Trash2,
} from "lucide-react";
import { toast } from "sonner";
import type { JamKerja } from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
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, CardHeader, CardTitle } 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 { formatNumber } from "@/lib/utils";

const HARI = ["Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"];

type FormState = {
  namaHari: string;
  jamMasuk: string;
  jamKeluar: string;
  aktif: boolean;
  keterangan: string;
};

const emptyForm: FormState = {
  namaHari: "Senin",
  jamMasuk: "08:00",
  jamKeluar: "15:00",
  aktif: true,
  keterangan: "",
};

function durasiMenit(masuk: string, keluar: string) {
  const [mh, mm] = masuk.split(":").map(Number);
  const [kh, km] = keluar.split(":").map(Number);
  return kh * 60 + km - (mh * 60 + mm);
}

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

  const { data, isLoading, mutate } = useSWR<JamKerja[]>("/jam-kerja", fetcher);
  const daftar = data ?? [];

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

  const ringkasan = useMemo(() => {
    const aktif = daftar.filter((item) => item.aktif);
    const totalMenit = aktif.reduce(
      (sum, item) => sum + durasiMenit(item.jamMasuk, item.jamKeluar),
      0,
    );
    return {
      aktif: aktif.length,
      nonaktif: daftar.length - aktif.length,
      totalJam: Math.round((totalMenit / 60) * 10) / 10,
    };
  }, [daftar]);

  function openCreate() {
    setEditing(null);
    setForm(emptyForm);
    setFormOpen(true);
  }

  function openEdit(item: JamKerja) {
    setEditing(item);
    setForm({
      namaHari: item.namaHari,
      jamMasuk: item.jamMasuk,
      jamKeluar: item.jamKeluar,
      aktif: item.aktif,
      keterangan: item.keterangan ?? "",
    });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const payload = {
        namaHari: form.namaHari,
        jamMasuk: form.jamMasuk,
        jamKeluar: form.jamKeluar,
        aktif: form.aktif,
        ...(form.keterangan ? { keterangan: form.keterangan } : { keterangan: "" }),
      };
      if (editing) {
        await apiSend(`/jam-kerja/${editing.id}`, "PATCH", payload);
        toast.success("Jam kerja diperbarui");
      } else {
        await apiSend("/jam-kerja", "POST", payload);
        toast.success("Jam kerja ditambahkan");
      }
      setFormOpen(false);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menyimpan data");
    } finally {
      setSaving(false);
    }
  }

  async function remove() {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await apiSend(`/jam-kerja/${deleteTarget.id}`, "DELETE");
      toast.success("Jam kerja 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="Jam Kerja"
          description="Jadwal jam layanan kantor desa untuk setiap hari dalam sepekan."
          action={
            <div className="flex flex-wrap gap-2">
              <Button variant="outline" onClick={() => window.print()}>
                <Printer className="h-4 w-4" />
                Cetak
              </Button>
              <PengaturanKehadiran />
              {canMutate && (
                <Button onClick={openCreate}>
                  <Plus className="h-4 w-4" />
                  Tambah Hari
                </Button>
              )}
            </div>
          }
        />
      </div>

      <KopLaporan title="Jadwal Jam Kerja Perangkat Desa" />

      {isLoading || !data ? (
        <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-3">
          {Array.from({ length: 3 }).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-3">
            <StatCard
              title="Hari kerja aktif"
              value={formatNumber(ringkasan.aktif)}
              hint="Hari dengan layanan kantor"
              icon={CalendarClock}
            />
            <StatCard
              title="Total jam layanan"
              value={`${formatNumber(ringkasan.totalJam)} jam`}
              hint="Akumulasi per pekan"
              icon={Timer}
              tone="sky"
            />
            <StatCard
              title="Hari nonaktif"
              value={formatNumber(ringkasan.nonaktif)}
              hint="Tutup atau layanan terbatas"
              icon={Clock}
              tone="amber"
            />
          </div>

          <Card>
            <CardHeader>
              <CardTitle>Jadwal Layanan Mingguan</CardTitle>
            </CardHeader>
            <CardContent>
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead className="w-14">No</TableHead>
                    {canMutate && <TableHead className="w-24">Aksi</TableHead>}
                    <TableHead>Hari</TableHead>
                    <TableHead>Jam masuk</TableHead>
                    <TableHead>Jam keluar</TableHead>
                    <TableHead>Keterangan</TableHead>
                    <TableHead>Status</TableHead>
                    <TableHead className="hidden md:table-cell">Durasi</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {daftar.map((item, index) => (
                    <TableRow key={item.id}>
                      <TableCell className="text-muted-foreground">{index + 1}</TableCell>
                      {canMutate && (
                        <TableCell>
                          <div className="flex gap-1">
                            <Button
                              variant="ghost"
                              size="icon"
                              onClick={() => openEdit(item)}
                              aria-label="Ubah jam kerja"
                            >
                              <FilePenLine className="h-4 w-4" />
                            </Button>
                            <Button
                              variant="ghost"
                              size="icon"
                              onClick={() => setDeleteTarget(item)}
                              aria-label="Hapus jam kerja"
                            >
                              <Trash2 className="h-4 w-4 text-destructive" />
                            </Button>
                          </div>
                        </TableCell>
                      )}
                      <TableCell className="font-medium">{item.namaHari}</TableCell>
                      <TableCell className="font-mono text-sm">{item.jamMasuk}</TableCell>
                      <TableCell className="font-mono text-sm">{item.jamKeluar}</TableCell>
                      <TableCell className="max-w-[240px] truncate text-muted-foreground">
                        {item.keterangan || "-"}
                      </TableCell>
                      <TableCell>
                        <Badge variant={item.aktif ? "success" : "secondary"}>
                          {item.aktif ? "Aktif" : "Nonaktif"}
                        </Badge>
                      </TableCell>
                      <TableCell className="hidden text-muted-foreground md:table-cell">
                        {durasiMenit(item.jamMasuk, item.jamKeluar)} menit
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </CardContent>
          </Card>
        </>
      )}

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>{editing ? "Ubah Jam Kerja" : "Tambah Jam Kerja"}</DialogTitle>
            <DialogDescription>
              Atur jam masuk dan keluar layanan kantor desa.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="namaHari">Hari</Label>
              <Select
                id="namaHari"
                value={form.namaHari}
                onChange={(event) => setForm({ ...form, namaHari: event.target.value })}
              >
                {HARI.map((hari) => (
                  <option key={hari} value={hari}>
                    {hari}
                  </option>
                ))}
              </Select>
            </div>
            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-1.5">
                <Label htmlFor="jamMasuk">Jam masuk</Label>
                <Input
                  id="jamMasuk"
                  type="time"
                  value={form.jamMasuk}
                  onChange={(event) => setForm({ ...form, jamMasuk: event.target.value })}
                  required
                />
              </div>
              <div className="space-y-1.5">
                <Label htmlFor="jamKeluar">Jam keluar</Label>
                <Input
                  id="jamKeluar"
                  type="time"
                  value={form.jamKeluar}
                  onChange={(event) => setForm({ ...form, jamKeluar: event.target.value })}
                  required
                />
              </div>
            </div>
            <label className="flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={form.aktif}
                onChange={(event) => setForm({ ...form, aktif: event.target.checked })}
                className="h-4 w-4 accent-primary"
              />
              Hari kerja aktif
            </label>
            <div className="space-y-1.5">
              <Label htmlFor="keterangan">Keterangan</Label>
              <Input
                id="keterangan"
                value={form.keterangan}
                onChange={(event) => setForm({ ...form, keterangan: event.target.value })}
                placeholder="Opsional"
              />
            </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 jam kerja?</DialogTitle>
            <DialogDescription>
              Jadwal hari {deleteTarget?.namaHari} 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>
  );
}
