"use client";

import { useEffect, useState } from "react";
import useSWR from "swr";
import {
  CalendarDays,
  FilePenLine,
  Plus,
  Search,
  Trash2,
  UserRound,
  UsersRound,
  ClipboardList,
} from "lucide-react";
import { toast } from "sonner";
import type { BukuTamu, Paginated, RingkasanBukuTamu } from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { useSession } from "@/lib/use-session";
import { PageHeader, StatCard } from "@/components/page-header";
import { Pagination } from "@/components/pagination";
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 {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Textarea } from "@/components/ui/textarea";
import { formatDate } from "@/lib/utils";

function toLocalInput(value: string | Date) {
  const date = new Date(value);
  const pad = (number: number) => String(number).padStart(2, "0");
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
    date.getDate(),
  )}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

type FormState = {
  nama: string;
  nik: string;
  instansi: string;
  telepon: string;
  alamat: string;
  keperluan: string;
  jumlahTamu: string;
  waktu: string;
  catatan: string;
};

function emptyForm(): FormState {
  return {
    nama: "",
    nik: "",
    instansi: "",
    telepon: "",
    alamat: "",
    keperluan: "",
    jumlahTamu: "1",
    waktu: toLocalInput(new Date()),
    catatan: "",
  };
}

export default function BukuTamuPage() {
  const { user } = useSession();
  const isAdmin = user?.role === "ADMIN";

  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [q, setQ] = useState("");
  const [dari, setDari] = useState("");
  const [sampai, setSampai] = useState("");

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

  const query = new URLSearchParams({ page: String(page), limit: "10" });
  if (q) query.set("q", q);
  if (dari) query.set("dari", new Date(`${dari}T00:00:00`).toISOString());
  if (sampai) query.set("sampai", new Date(`${sampai}T23:59:59`).toISOString());

  const { data, isLoading, mutate } = useSWR<Paginated<BukuTamu>>(
    `/buku-tamu?${query.toString()}`,
    fetcher,
  );
  const { data: ringkasan, mutate: mutateRingkasan } = useSWR<RingkasanBukuTamu>(
    "/buku-tamu/ringkasan",
    fetcher,
  );

  const daftar = data?.data ?? [];

  useEffect(() => {
    setPage(1);
  }, [q, dari, sampai]);

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

  function openEdit(item: BukuTamu) {
    setEditing(item);
    setForm({
      nama: item.nama,
      nik: item.nik ?? "",
      instansi: item.instansi ?? "",
      telepon: item.telepon ?? "",
      alamat: item.alamat ?? "",
      keperluan: item.keperluan,
      jumlahTamu: String(item.jumlahTamu),
      waktu: toLocalInput(item.waktu),
      catatan: item.catatan ?? "",
    });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const payload = {
        nama: form.nama,
        keperluan: form.keperluan,
        jumlahTamu: Number(form.jumlahTamu) || 1,
        waktu: new Date(form.waktu).toISOString(),
        ...(form.nik ? { nik: form.nik } : {}),
        ...(form.instansi ? { instansi: form.instansi } : {}),
        ...(form.telepon ? { telepon: form.telepon } : {}),
        ...(form.alamat ? { alamat: form.alamat } : {}),
        ...(form.catatan ? { catatan: form.catatan } : {}),
      };
      if (editing) {
        await apiSend(`/buku-tamu/${editing.id}`, "PATCH", payload);
        toast.success("Data tamu diperbarui");
      } else {
        await apiSend("/buku-tamu", "POST", payload);
        toast.success("Kunjungan tamu dicatat");
      }
      setFormOpen(false);
      await mutate();
      await mutateRingkasan();
    } 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(`/buku-tamu/${deleteTarget.id}`, "DELETE");
      toast.success("Data tamu dihapus");
      setDeleteTarget(null);
      await mutate();
      await mutateRingkasan();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menghapus data");
    } finally {
      setDeleting(false);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Buku Tamu"
        description="Catatan kunjungan tamu ke kantor Desa Mulyadadi beserta keperluan dan jumlah tamu."
        action={
          <Button onClick={openCreate}>
            <Plus className="h-4 w-4" />
            Catat Tamu
          </Button>
        }
      />

      <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
        <StatCard
          title="Total kunjungan"
          value={ringkasan?.total ?? 0}
          hint="Seluruh waktu"
          icon={ClipboardList}
        />
        <StatCard
          title="Hari ini"
          value={ringkasan?.hariIni ?? 0}
          hint="Kunjungan hari ini"
          icon={CalendarDays}
          tone="sky"
        />
        <StatCard
          title="Bulan ini"
          value={ringkasan?.bulanIni ?? 0}
          hint="Kunjungan bulan berjalan"
          icon={UsersRound}
          tone="amber"
        />
        <StatCard
          title="Total orang"
          value={ringkasan?.totalOrang ?? 0}
          hint="Termasuk tamu kelompok"
          icon={UserRound}
          tone="violet"
        />
      </div>

      <Card>
        <CardContent className="p-0">
          <div className="flex flex-col gap-3 border-b p-4 xl:flex-row xl:items-center xl:justify-between">
            <form
              onSubmit={(event) => {
                event.preventDefault();
                setQ(search.trim());
              }}
              className="relative w-full xl:max-w-sm"
            >
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={search}
                onChange={(event) => setSearch(event.target.value)}
                placeholder="Cari nama, instansi, atau keperluan…"
                className="pl-9"
              />
            </form>
            <div className="flex flex-wrap items-end gap-2">
              <div className="space-y-1">
                <Label className="text-xs text-muted-foreground">Dari tanggal</Label>
                <Input
                  type="date"
                  value={dari}
                  onChange={(event) => setDari(event.target.value)}
                  className="w-full sm:w-40"
                />
              </div>
              <div className="space-y-1">
                <Label className="text-xs text-muted-foreground">Sampai tanggal</Label>
                <Input
                  type="date"
                  value={sampai}
                  onChange={(event) => setSampai(event.target.value)}
                  className="w-full sm:w-40"
                />
              </div>
              {(q || dari || sampai) && (
                <Button
                  type="button"
                  variant="ghost"
                  onClick={() => {
                    setSearch("");
                    setQ("");
                    setDari("");
                    setSampai("");
                  }}
                >
                  Reset
                </Button>
              )}
            </div>
          </div>

          {isLoading ? (
            <div className="space-y-2 p-4">
              {Array.from({ length: 6 }).map((_, index) => (
                <div key={index} className="h-12 animate-pulse rounded-lg bg-muted" />
              ))}
            </div>
          ) : daftar.length ? (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Waktu</TableHead>
                  <TableHead>Tamu</TableHead>
                  <TableHead>Instansi / Kontak</TableHead>
                  <TableHead>Keperluan</TableHead>
                  <TableHead>Jumlah</TableHead>
                  <TableHead className="text-right">Aksi</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {daftar.map((tamu) => (
                  <TableRow key={tamu.id}>
                    <TableCell>
                      <div className="text-sm font-medium">{formatDate(tamu.waktu)}</div>
                    </TableCell>
                    <TableCell>
                      <div className="font-medium">{tamu.nama}</div>
                      <div className="font-mono text-xs text-muted-foreground">
                        {tamu.nik ?? "-"}
                      </div>
                    </TableCell>
                    <TableCell>
                      <div className="text-sm">{tamu.instansi ?? "-"}</div>
                      <div className="text-xs text-muted-foreground">
                        {tamu.telepon ?? tamu.alamat ?? ""}
                      </div>
                    </TableCell>
                    <TableCell>
                      <div className="max-w-[240px] text-sm text-muted-foreground">
                        {tamu.keperluan}
                      </div>
                      {tamu.catatan && (
                        <div className="mt-0.5 max-w-[240px] truncate text-xs text-muted-foreground">
                          {tamu.catatan}
                        </div>
                      )}
                    </TableCell>
                    <TableCell>
                      <Badge variant="secondary">{tamu.jumlahTamu} orang</Badge>
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex justify-end gap-1">
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={() => openEdit(tamu)}
                          aria-label="Ubah data tamu"
                        >
                          <FilePenLine className="h-4 w-4" />
                        </Button>
                        {isAdmin && (
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-8 w-8 text-destructive hover:text-destructive"
                            onClick={() => setDeleteTarget(tamu)}
                            aria-label="Hapus data tamu"
                          >
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        )}
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          ) : (
            <div className="py-16 text-center">
              <p className="font-semibold">Belum ada kunjungan tercatat</p>
              <p className="mt-1 text-sm text-muted-foreground">
                Catat tamu baru atau ubah filter tanggal.
              </p>
            </div>
          )}

          {data && data.data.length > 0 && (
            <Pagination
              page={data.meta.page}
              totalPages={data.meta.totalPages}
              total={data.meta.total}
              onChange={setPage}
            />
          )}
        </CardContent>
      </Card>

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-w-xl">
          <DialogHeader>
            <DialogTitle>{editing ? "Ubah Data Tamu" : "Catat Tamu Baru"}</DialogTitle>
            <DialogDescription>
              Isi identitas tamu, keperluan kunjungan, dan waktu kedatangan.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="grid gap-4 sm:grid-cols-2">
              <Field label="Nama tamu" required>
                <Input
                  required
                  value={form.nama}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, nama: event.target.value }))
                  }
                />
              </Field>
              <Field label="NIK">
                <Input
                  maxLength={16}
                  value={form.nik}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, nik: event.target.value }))
                  }
                />
              </Field>
              <Field label="Instansi / lembaga">
                <Input
                  value={form.instansi}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, instansi: event.target.value }))
                  }
                  placeholder="Warga / Dinas / Kecamatan"
                />
              </Field>
              <Field label="Telepon">
                <Input
                  value={form.telepon}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, telepon: event.target.value }))
                  }
                />
              </Field>
              <Field label="Waktu kunjungan" required>
                <Input
                  required
                  type="datetime-local"
                  value={form.waktu}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, waktu: event.target.value }))
                  }
                />
              </Field>
              <Field label="Jumlah tamu">
                <Input
                  type="number"
                  min={1}
                  value={form.jumlahTamu}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, jumlahTamu: event.target.value }))
                  }
                />
              </Field>
              <div className="sm:col-span-2">
                <Field label="Alamat">
                  <Input
                    value={form.alamat}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, alamat: event.target.value }))
                    }
                  />
                </Field>
              </div>
              <div className="sm:col-span-2">
                <Field label="Keperluan" required>
                  <Textarea
                    required
                    rows={2}
                    value={form.keperluan}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, keperluan: event.target.value }))
                    }
                    placeholder="Contoh: pengurusan surat keterangan domisili"
                  />
                </Field>
              </div>
              <div className="sm:col-span-2">
                <Field label="Catatan">
                  <Textarea
                    rows={2}
                    value={form.catatan}
                    onChange={(event) =>
                      setForm((current) => ({ ...current, catatan: event.target.value }))
                    }
                  />
                </Field>
              </div>
            </div>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setFormOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : editing ? "Simpan Perubahan" : "Catat Tamu"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus data tamu?</DialogTitle>
            <DialogDescription>
              Catatan kunjungan <span className="font-semibold">{deleteTarget?.nama}</span>{" "}
              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>
  );
}

function Field({
  label,
  required,
  children,
}: {
  label: string;
  required?: boolean;
  children: React.ReactNode;
}) {
  return (
    <div className="space-y-1.5">
      <Label>
        {label}
        {required && <span className="ml-0.5 text-destructive">*</span>}
      </Label>
      {children}
    </div>
  );
}
