import { useRef, useState } from "react";
import { Section } from "@/components/sip/Section";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Database, Download, Link2, RefreshCw, Upload } from "lucide-react";
import { toast } from "sonner";
import { useSip } from "@/lib/sip-data";
import { connectSpreadsheet } from "@/lib/sheets.functions";
import { SHEET_NAMES, type SheetRow } from "@/lib/sheets-schema";

export function PengaturanDatabase() {
  const { spreadsheetId, setSpreadsheetId, reloadDatabase, backupDatabase, restoreDatabase, dbStatus } =
    useSip();
  const [input, setInput] = useState(spreadsheetId);
  const [proses, setProses] = useState(false);
  const fileRef = useRef<HTMLInputElement>(null);

  const hubungkan = async () => {
    setProses(true);
    try {
      const hasil = await connectSpreadsheet({ data: { spreadsheetId: input } });
      setSpreadsheetId(hasil.id);
      setInput(hasil.id);
      reloadDatabase();
      toast.success(
        `Terhubung ke "${hasil.judul}"` +
          (hasil.dibuat.length ? ` — ${hasil.dibuat.length} tabel baru dibuat.` : "."),
      );
    } catch (err) {
      console.error(err);
      toast.error("Gagal terhubung. Pastikan ID/URL benar dan spreadsheet dapat diakses akun Google yang tertaut.");
    } finally {
      setProses(false);
    }
  };

  const unduhBackup = () => {
    const data = backupDatabase();
    const blob = new Blob([JSON.stringify({ dibuat: new Date().toISOString(), data }, null, 2)], {
      type: "application/json",
    });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `backup-sip-smpn8-${new Date().toISOString().slice(0, 10)}.json`;
    a.click();
    URL.revokeObjectURL(url);
    toast.success("Backup database berhasil diunduh.");
  };

  const pulihkan = async (file: File) => {
    if (!confirm("Pulihkan database dari file ini? Seluruh data di spreadsheet aktif akan ditimpa.")) return;
    setProses(true);
    try {
      const isi = JSON.parse(await file.text()) as {
        data?: Record<string, SheetRow[]>;
      } & Record<string, unknown>;
      const tabel = (isi.data ?? (isi as unknown as Record<string, SheetRow[]>)) as Record<string, SheetRow[]>;
      const valid = Object.fromEntries(
        SHEET_NAMES.filter((n) => Array.isArray(tabel[n])).map((n) => [n, tabel[n] as SheetRow[]]),
      );
      if (!Object.keys(valid).length) throw new Error("File backup tidak dikenali");
      await restoreDatabase(valid);
      toast.success("Database berhasil dipulihkan.");
    } catch (err) {
      console.error(err);
      toast.error("Gagal memulihkan database. Periksa file backup.");
    } finally {
      setProses(false);
      if (fileRef.current) fileRef.current.value = "";
    }
  };

  const statusText =
    dbStatus === "memuat"
      ? "Memuat data…"
      : dbStatus === "menyimpan"
        ? "Menyimpan…"
        : dbStatus === "gagal"
          ? "Gagal sinkron"
          : "Tersimpan";

  return (
    <div className="space-y-6">
      <Section title="Tautan Spreadsheet Database">
        <div className="space-y-4">
          <p className="text-muted-foreground text-sm">
            Tempelkan URL atau ID Google Spreadsheet yang akan dipakai sebagai database aplikasi. Tab/tabel
            yang belum ada akan dibuat otomatis. Pengaturan ini berlaku untuk perangkat ini.
          </p>
          <div className="flex flex-col gap-2 md:flex-row">
            <Input
              value={input}
              onChange={(e) => setInput(e.target.value)}
              placeholder="https://docs.google.com/spreadsheets/d/…  atau ID spreadsheet"
            />
            <Button onClick={hubungkan} disabled={proses}>
              <Link2 className="mr-2 h-4 w-4" /> Hubungkan
            </Button>
            <Button variant="outline" onClick={reloadDatabase} disabled={proses}>
              <RefreshCw className="mr-2 h-4 w-4" /> Muat Ulang
            </Button>
          </div>
          <div className="text-muted-foreground flex flex-wrap items-center gap-2 text-sm">
            <Database className="h-4 w-4" />
            <span>
              Aktif: <b className="text-foreground">{spreadsheetId || "Spreadsheet bawaan aplikasi"}</b>
            </span>
            <span>• Status: {statusText}</span>
          </div>
          {spreadsheetId ? (
            <div className="flex flex-wrap gap-2">
              <a
                className="text-primary text-sm underline"
                href={`https://docs.google.com/spreadsheets/d/${spreadsheetId}`}
                target="_blank"
                rel="noreferrer"
              >
                Buka spreadsheet
              </a>
              <button
                className="text-destructive text-sm underline"
                onClick={() => {
                  setSpreadsheetId("");
                  setInput("");
                  reloadDatabase();
                  toast.success("Kembali memakai spreadsheet bawaan.");
                }}
              >
                Gunakan spreadsheet bawaan
              </button>
            </div>
          ) : null}
        </div>
      </Section>

      <Section title="Backup & Restore Database">
        <div className="space-y-4">
          <p className="text-muted-foreground text-sm">
            Backup menyimpan seluruh data aplikasi ke satu file JSON. Restore akan menimpa data pada
            spreadsheet yang sedang aktif.
          </p>
          <div className="flex flex-wrap gap-2">
            <Button onClick={unduhBackup} disabled={proses}>
              <Download className="mr-2 h-4 w-4" /> Unduh Backup
            </Button>
            <Button variant="outline" onClick={() => fileRef.current?.click()} disabled={proses}>
              <Upload className="mr-2 h-4 w-4" /> Pulihkan dari Backup
            </Button>
            <input
              ref={fileRef}
              type="file"
              accept="application/json,.json"
              className="hidden"
              onChange={(e) => {
                const f = e.target.files?.[0];
                if (f) void pulihkan(f);
              }}
            />
          </div>
        </div>
      </Section>
    </div>
  );
}
