"use client";

import { useEffect, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { useAlertConfirm } from "@/components/ui/alert-dialog";
import { snapshotAllStores, restoreFromBackup, storageSummary, type SagBackup } from "@/lib/sag/data-export";

export function DataBackup() {
  const [summary, setSummary] = useState<ReturnType<typeof storageSummary> | null>(null);
  const [lastAction, setLastAction] = useState<string | null>(null);
  const [error, setError] = useState<string>("");
  const { confirm: confirmAlert, AlertConfirmPortal } = useAlertConfirm();

  useEffect(() => {
    // Defer to next tick to avoid sync-setState-in-effect lint
    const t = setTimeout(() => setSummary(storageSummary()), 0);
    return () => clearTimeout(t);
  }, [lastAction]);

  function download() {
    const snap = snapshotAllStores();
    const blob = new Blob([JSON.stringify(snap, null, 2)], { type: "application/json" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = `sag-backup-${new Date().toISOString().slice(0, 19).replace(/:/g, "-")}.json`;
    a.click();
    URL.revokeObjectURL(url);
    setLastAction(`Downloaded ${Object.keys(snap.stores).length} stores at ${new Date().toLocaleTimeString()}`);
    setError("");
  }

  async function onRestore(file: File, mode: "replace" | "merge") {
    setError("");
    try {
      const text = await file.text();
      const json = JSON.parse(text) as SagBackup;
      const ok = await confirmAlert(
        mode === "replace"
          ? {
              title: "Replace ALL current SAG data with the backup?",
              description: "This wipes current localStorage entries first.",
              actionLabel: "Replace",
              destructive: true,
            }
          : {
              title: "Merge backup into current data?",
              description: "Existing keys will be overwritten by the backup's values.",
              actionLabel: "Merge",
              destructive: false,
            },
      );
      if (!ok) return;
      const result = restoreFromBackup(json, mode);
      setLastAction(`Restored ${result.applied} stores (skipped ${result.skipped}) at ${new Date().toLocaleTimeString()} — refresh the page to see them.`);
    } catch (e) {
      setError(e instanceof Error ? e.message : "Restore failed");
    }
  }

  async function clearAll() {
    const ok = await confirmAlert({
      title: "Delete all sag.* localStorage entries on this device?",
      description: "This cannot be undone. Download a backup first if you want to keep the data.",
      actionLabel: "Wipe all data",
      destructive: true,
    });
    if (!ok) return;
    if (typeof window === "undefined") return;
    const remove: string[] = [];
    for (let i = 0; i < window.localStorage.length; i++) {
      const key = window.localStorage.key(i);
      if (key && key.startsWith("sag.")) remove.push(key);
    }
    remove.forEach((k) => window.localStorage.removeItem(k));
    setLastAction(`Cleared ${remove.length} stores at ${new Date().toLocaleTimeString()} — refresh the page.`);
  }

  return (
    <>
    <div className="space-y-6">
      <Card>
        <CardContent className="p-6">
          <h2 className="text-base font-semibold">Backup all data</h2>
          <p className="mt-1 text-sm text-muted-foreground max-w-2xl">
            All app data lives in this browser’s localStorage until Supabase is provisioned. Clearing your browser, switching devices, or hitting localStorage quota would wipe it. Download a backup now and any time you want a snapshot.
          </p>
          <Button variant="brand" className="mt-4" onClick={download}>
            ⬇ Download SAG backup (.json)
          </Button>
        </CardContent>
      </Card>

      <Card>
        <CardContent className="p-6">
          <h2 className="text-base font-semibold">Restore from backup</h2>
          <p className="mt-1 text-sm text-muted-foreground max-w-2xl">
            Pick a previously-downloaded <code className="text-xs bg-muted px-1 py-0.5 rounded">sag-backup-*.json</code> file. <strong>Replace</strong> wipes current data first and reloads from the backup; <strong>Merge</strong> overlays the backup on top of existing data (existing keys overwritten where present in the backup, others kept).
          </p>
          <div className="mt-4 flex flex-wrap gap-2">
            <label className="inline-flex items-center gap-2 cursor-pointer rounded-md border bg-background px-4 py-2 text-sm font-medium hover:bg-accent">
              ↺ Restore (replace)
              <input
                type="file"
                accept="application/json,.json"
                className="sr-only"
                onChange={(e) => {
                  const f = e.target.files?.[0];
                  if (f) onRestore(f, "replace");
                  e.target.value = "";
                }}
              />
            </label>
            <label className="inline-flex items-center gap-2 cursor-pointer rounded-md border bg-background px-4 py-2 text-sm font-medium hover:bg-accent">
              ⊕ Restore (merge)
              <input
                type="file"
                accept="application/json,.json"
                className="sr-only"
                onChange={(e) => {
                  const f = e.target.files?.[0];
                  if (f) onRestore(f, "merge");
                  e.target.value = "";
                }}
              />
            </label>
          </div>
          {error && (
            <div className="mt-3 rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive">
              {error}
            </div>
          )}
          {lastAction && !error && (
            <div className="mt-3 rounded-md border border-green-500/30 bg-green-50/40 dark:bg-green-900/10 p-3 text-sm">
              {lastAction}
            </div>
          )}
        </CardContent>
      </Card>

      <Card>
        <CardContent className="p-6">
          <h2 className="text-base font-semibold">Storage usage</h2>
          {!summary ? (
            <p className="mt-2 text-sm text-muted-foreground">Calculating...</p>
          ) : (
            <>
              <div className="mt-3 flex flex-wrap gap-3">
                <Stat label="Stores" value={String(summary.keys)} />
                <Stat label="Bytes" value={`${(summary.bytes / 1024).toFixed(1)} KB`} />
                <Stat label="Browser cap (typical)" value="~5–10 MB" />
              </div>
              {summary.topKeys.length > 0 && (
                <>
                  <h3 className="mt-5 text-sm font-medium">Largest stores</h3>
                  <ul className="mt-2 space-y-1 text-sm">
                    {summary.topKeys.map((s) => (
                      <li key={s.key} className="flex items-center justify-between rounded-md border bg-background px-3 py-2">
                        <code className="text-xs">{s.key}</code>
                        <span className="font-mono text-xs tabular-nums">{(s.bytes / 1024).toFixed(1)} KB</span>
                      </li>
                    ))}
                  </ul>
                </>
              )}
            </>
          )}
        </CardContent>
      </Card>

      <Card className="border-destructive/30 bg-destructive/5">
        <CardContent className="p-6">
          <Badge variant="destructive">Danger zone</Badge>
          <h2 className="mt-2 text-base font-semibold">Wipe all SAG data on this device</h2>
          <p className="mt-1 text-sm text-muted-foreground max-w-2xl">
            Deletes every <code className="text-xs">sag.*</code> entry from this browser’s localStorage. The seed data (entities, domains, pitches) is in code and unaffected. Download a backup first.
          </p>
          <Button variant="destructive" className="mt-4" onClick={clearAll}>
            Wipe all data
          </Button>
        </CardContent>
      </Card>
    </div>
    <AlertConfirmPortal />
    </>
  );
}

function Stat({ label, value }: { label: string; value: string }) {
  return (
    <div className="rounded-md border bg-background px-4 py-3">
      <div className="section-label">{label}</div>
      <div className="mt-0.5 text-lg font-semibold tabular-nums">{value}</div>
    </div>
  );
}
