import { 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 { ExternalLink, Plus } from "lucide-react";
import { toast } from "sonner";
import { newId, nowTime, todayISO, useSip } from "@/lib/sip-data";
import { parseDriveFolderId } from "@/lib/drive";
import { uploadToDrive } from "@/lib/drive.functions";
import { useServerFn } from "@tanstack/react-start";

export function BukuTamu() {
  const { tamu, setTamu, currentUser, driveTamuUrl } = useSip();
  const upload = useServerFn(uploadToDrive);
  const isPiket = currentUser?.role === "Petugas Piket";
  const [query, setQuery] = useState("");
  const [view, setView] = useState<ViewMode>("rinci");

  const q = query.trim().toLowerCase();
  const data = tamu.filter(
    (t) =>
      !q ||
      t.nama.toLowerCase().includes(q) ||
      t.instansi.toLowerCase().includes(q) ||
      t.tujuan.toLowerCase().includes(q) ||
      t.dituju.toLowerCase().includes(q) ||
      t.tanggal.includes(q),
  );
  const perTanggal = Array.from(
    data.reduce((m, t) => m.set(t.tanggal, (m.get(t.tanggal) ?? 0) + 1), new Map<string, number>()),
  )
    .sort((a, b) => (a[0] < b[0] ? 1 : -1))
    .map(([label, value]) => ({ label: `Tanggal ${label}`, value }));


  return (
    <Section
      title="Buku Tamu Digital"
      action={
        <div className="flex flex-wrap items-center gap-2">
          {driveTamuUrl ? (
            <Button size="sm" variant="outline" asChild>
              <a href={driveTamuUrl} target="_blank" rel="noreferrer">
                <ExternalLink className="mr-1 h-4 w-4" /> Folder Drive Foto
              </a>
            </Button>
          ) : null}
          {isPiket ? (
            <FormDialog
              title="Catat Tamu Baru"
              description={
                driveTamuUrl
                  ? "Foto tamu tersimpan pada arsip buku tamu dan folder Drive yang diatur admin."
                  : "Admin belum mengatur link folder Drive untuk arsip foto tamu."
              }
              fields={[
                { name: "nama", label: "Nama Tamu" },
                { name: "instansi", label: "Instansi / Asal" },
                { name: "tujuan", label: "Keperluan" },
                { name: "dituju", label: "Pihak yang Dituju" },
                { name: "foto", label: "Foto Tamu", type: "photo", optional: true },
                { name: "keterangan", label: "Keterangan", optional: true },
              ]}
              submitLabel="Simpan Tamu"
              onSubmit={async (v) => {
                const foto = v["foto"] ?? "";
                const id = newId("T");
                setTamu((prev) => [
                  ...prev,
                  {
                    id,
                    tanggal: todayISO(),
                    waktu: nowTime(),
                    nama: val(v, "nama"),
                    instansi: val(v, "instansi"),
                    tujuan: val(v, "tujuan"),
                    dituju: val(v, "dituju"),
                    keterangan: val(v, "keterangan") || "-",
                    foto,
                  },
                ]);
                toast.success("Data tamu tersimpan");
                if (foto && driveTamuUrl) {
                  const folderId = parseDriveFolderId(driveTamuUrl);
                  if (!folderId) {
                    window.open(driveTamuUrl, "_blank", "noopener");
                    return;
                  }
                  try {
                    const fileName = `Tamu_${val(v, "nama").replace(/\s+/g, "_")}_${Date.now()}.jpg`;
                    const res = await upload({ data: { folderId, name: fileName, dataUrl: foto } });
                    setTamu((prev) =>
                      prev.map((t) => (t.id === id ? { ...t, driveUrl: res.webViewLink } : t))
                    );
                    toast.success("Foto tamu berhasil diunggah ke Google Drive");
                  } catch (err) {
                    toast.error("Foto tamu tersimpan lokal, tetapi gagal diunggah ke Drive", {
                      description: String(err),
                    });
                    window.open(driveTamuUrl, "_blank", "noopener");
                  }
                }
              }}
              trigger={
                <Button size="sm">
                  <Plus className="mr-1 h-4 w-4" /> Tamu Baru
                </Button>
              }
            />
          ) : null}
        </div>
      }
    >
      <SearchToggleBar
        query={query}
        onQueryChange={setQuery}
        view={view}
        onViewChange={setView}
        placeholder="Cari nama tamu / instansi / keperluan / tanggal..."
      />
      {view === "ringkas" ? (
        <SummaryCards total={data.length} totalLabel="Total Tamu" items={perTanggal} />
      ) : (
        <DataTable
          head={["Waktu", "Foto", "Nama Tamu", "Instansi", "Keperluan", "Dituju"]}
          empty="Tidak ada data tamu."
          rows={data.map((t) => [
            <span className="text-muted-foreground whitespace-nowrap">
              {t.tanggal} {t.waktu}
            </span>,
            t.foto ? (
              <img
                src={t.foto}
                alt={`Foto ${t.nama}`}
                className="border-border h-12 w-12 rounded-md border object-cover"
              />
            ) : (
              <span className="text-muted-foreground">-</span>
            ),
            <span className="font-semibold">{t.nama}</span>,
            t.instansi,
            t.tujuan,
            <span className="text-primary font-medium">{t.dituju}</span>,
          ])}
        />
      )}
    </Section>
  );
}
