"use client";

import React, { useCallback, useEffect, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { apiFetch, API_BASE } from "@/lib/api";
import { useDismissingState } from "@/hooks/useDismissingState";
import { DatabaseBackup, Download } from "lucide-react";

interface BackupEntry {
  filename: string;
  size: number;
  createdAt: string;
}

function formatSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

export function BackupsTab({ active }: { active: boolean }) {
  const { token } = useAuth();
  const [backups, setBackups] = useState<BackupEntry[]>([]);
  const [loading, setLoading] = useState(true);
  const [running, setRunning] = useState(false);
  const [message, setMessage] = useDismissingState<{ type: "ok" | "err"; text: string } | null>(null);

  const [retainCount, setRetainCount] = useState("14");
  const [savingRetain, setSavingRetain] = useState(false);

  const load = useCallback(async () => {
    if (!token) return;
    setLoading(true);
    try {
      const [list, allSettings] = await Promise.all([
        apiFetch<BackupEntry[]>("/api/backups", { authToken: token }),
        apiFetch<Record<string, string>>("/api/settings/all", { authToken: token }),
      ]);
      setBackups(list || []);
      setRetainCount(allSettings?.backup_retain_count || "14");
    } catch (e: any) {
      setMessage({ type: "err", text: e?.message || "Failed to load backups" });
    } finally {
      setLoading(false);
    }
  }, [token]);

  const saveRetainCount = async () => {
    if (!token) return;
    setSavingRetain(true);
    try {
      await apiFetch("/api/settings", { method: "PUT", authToken: token, body: { backup_retain_count: retainCount } });
      setMessage({ type: "ok", text: "Retention setting saved." });
    } catch (e: any) {
      setMessage({ type: "err", text: e?.message || "Failed to save retention setting" });
    } finally {
      setSavingRetain(false);
    }
  };

  useEffect(() => { if (active) load(); }, [active, load]);

  const runBackup = async () => {
    if (!token) return;
    setRunning(true);
    setMessage(null);
    try {
      const res = await apiFetch<{ filename: string }>("/api/backups/run", { method: "POST", authToken: token });
      setMessage({ type: "ok", text: `Backup created: ${res.filename}` });
      await load();
    } catch (e: any) {
      setMessage({ type: "err", text: e?.message || "Backup failed" });
    } finally {
      setRunning(false);
    }
  };

  return (
    <div className="space-y-4">
      <div className="flex items-center gap-3">
        <div className="w-9 h-9 rounded-lg bg-brand-50 flex items-center justify-center shrink-0">
          <DatabaseBackup className="w-4 h-4 text-brand-600" />
        </div>
        <div>
          <h2 className="text-lg font-semibold text-gray-900">Database backups</h2>
          <p className="text-xs text-gray-500">Nightly automatic backups, stored locally on this server. Not uploaded anywhere else.</p>
        </div>
      </div>

      {message && (
        <div className={`text-sm p-2.5 rounded-lg ${message.type === "ok" ? "bg-green-50 text-green-700" : "bg-red-50 text-red-700"}`}>
          {message.text}
        </div>
      )}

      <button
        type="button"
        onClick={runBackup}
        disabled={running}
        className="px-4 py-2 bg-brand-600 hover:bg-brand-700 disabled:opacity-50 text-white rounded-lg text-sm font-medium"
      >
        {running ? "Running…" : "Run backup now"}
      </button>

      <div className="flex items-end gap-2 pt-2 border-t">
        <div>
          <label className="block text-xs text-gray-600 mb-1">Keep the most recent</label>
          <input
            type="number"
            min={1}
            className="w-24 border rounded-lg px-3 py-1.5 text-sm"
            value={retainCount}
            onChange={(e) => setRetainCount(e.target.value)}
          />
        </div>
        <span className="text-sm text-gray-500 pb-1.5">backups, delete the rest</span>
        <button
          type="button"
          onClick={saveRetainCount}
          disabled={savingRetain}
          className="ml-auto px-3 py-1.5 text-sm rounded-lg bg-gray-100 hover:bg-gray-200 disabled:opacity-50"
        >
          {savingRetain ? "Saving…" : "Save"}
        </button>
      </div>

      <div className="border rounded-lg overflow-hidden mt-2">
        <table className="min-w-full text-sm">
          <thead>
            <tr className="text-left text-gray-600 border-b bg-gray-50">
              <th className="p-2.5">Created</th>
              <th className="p-2.5">Size</th>
              <th className="p-2.5">Download</th>
            </tr>
          </thead>
          <tbody>
            {backups.map((b) => (
              <tr key={b.filename} className="border-t">
                <td className="p-2.5">{new Date(b.createdAt).toLocaleString()}</td>
                <td className="p-2.5 text-gray-500">{formatSize(b.size)}</td>
                <td className="p-2.5">
                  <a
                    href={`${API_BASE}/api/backups/${encodeURIComponent(b.filename)}/download`}
                    className="inline-flex items-center gap-1.5 text-brand-600 hover:underline"
                    onClick={(e) => {
                      // authenticated download: fetch as blob rather than a bare link,
                      // since this route requires an admin bearer token
                      e.preventDefault();
                      if (!token) return;
                      fetch(`${API_BASE}/api/backups/${encodeURIComponent(b.filename)}/download`, {
                        headers: { Authorization: `Bearer ${token}` },
                      })
                        .then((res) => res.blob())
                        .then((blob) => {
                          const url = URL.createObjectURL(blob);
                          const link = document.createElement("a");
                          link.href = url;
                          link.download = b.filename;
                          document.body.appendChild(link);
                          link.click();
                          document.body.removeChild(link);
                          URL.revokeObjectURL(url);
                        })
                        .catch(() => setMessage({ type: "err", text: "Download failed" }));
                    }}
                  >
                    <Download className="w-3.5 h-3.5" />
                    Download
                  </a>
                </td>
              </tr>
            ))}
            {backups.length === 0 && !loading && (
              <tr>
                <td className="p-3 text-gray-500" colSpan={3}>No backups yet.</td>
              </tr>
            )}
            {loading && (
              <tr>
                <td className="p-3 text-gray-400" colSpan={3}>Loading…</td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
