"use client";

import { useCallback, useEffect, useState } from "react";
import { useTranslations } from "next-intl";

import { Button } from "@hexahost/ui";

import {
  createBackup,
  deleteBackup,
  getBackupDownloadUrl,
  getBackupSchedule,
  listBackups,
  restoreBackup,
  updateBackupSchedule,
  type BackupItem,
  type BackupSchedule,
} from "@/lib/api/backups";

interface ServerBackupsProps {
  serverId: string;
}

function formatBytes(value: string | null): string {
  if (!value) {
    return "—";
  }
  const bytes = Number(value);
  if (Number.isNaN(bytes)) {
    return value;
  }
  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 ServerBackups({ serverId }: ServerBackupsProps) {
  const t = useTranslations("servers.backups");
  const [backups, setBackups] = useState<BackupItem[]>([]);
  const [schedule, setSchedule] = useState<BackupSchedule | null>(null);
  const [loading, setLoading] = useState(true);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const refresh = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const [backupList, scheduleData] = await Promise.all([
        listBackups(serverId),
        getBackupSchedule(serverId),
      ]);
      setBackups(backupList.backups);
      setSchedule(scheduleData);
    } catch (err) {
      setError(err instanceof Error ? err.message : t("loadError"));
    } finally {
      setLoading(false);
    }
  }, [serverId, t]);

  useEffect(() => {
    void refresh();
  }, [refresh]);

  async function handleCreateBackup() {
    setBusy(true);
    setError(null);
    try {
      await createBackup(serverId, t("manualLabel"));
      await refresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : t("createError"));
    } finally {
      setBusy(false);
    }
  }

  async function handleDownload(backupId: string) {
    try {
      const { downloadUrl } = await getBackupDownloadUrl(serverId, backupId);
      window.open(downloadUrl, "_blank", "noopener,noreferrer");
    } catch (err) {
      setError(err instanceof Error ? err.message : t("downloadError"));
    }
  }

  async function handleRestore(backupId: string) {
    if (!window.confirm(t("restoreConfirm"))) {
      return;
    }
    setBusy(true);
    try {
      await restoreBackup(serverId, backupId);
      await refresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : t("restoreError"));
    } finally {
      setBusy(false);
    }
  }

  async function handleDelete(backupId: string) {
    if (!window.confirm(t("deleteConfirm"))) {
      return;
    }
    setBusy(true);
    try {
      await deleteBackup(serverId, backupId);
      await refresh();
    } catch (err) {
      setError(err instanceof Error ? err.message : t("deleteError"));
    } finally {
      setBusy(false);
    }
  }

  async function toggleSchedule(enabled: boolean) {
    if (!schedule) {
      return;
    }
    setBusy(true);
    try {
      const updated = await updateBackupSchedule(serverId, { enabled });
      setSchedule(updated);
    } catch (err) {
      setError(err instanceof Error ? err.message : t("scheduleError"));
    } finally {
      setBusy(false);
    }
  }

  if (loading) {
    return <p className="text-sm text-zinc-500">{t("loading")}</p>;
  }

  return (
    <div className="space-y-6">
      {error ? (
        <p className="rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700 dark:border-red-900 dark:bg-red-950 dark:text-red-300">
          {error}
        </p>
      ) : null}

      <div className="flex flex-wrap items-center gap-3">
        <Button onClick={() => void handleCreateBackup()} disabled={busy}>
          {t("create")}
        </Button>
        {schedule ? (
          <Button
            variant="secondary"
            onClick={() => void toggleSchedule(!schedule.enabled)}
            disabled={busy}
          >
            {schedule.enabled ? t("disableSchedule") : t("enableSchedule")}
          </Button>
        ) : null}
      </div>

      {schedule ? (
        <p className="text-sm text-zinc-600 dark:text-zinc-400">
          {t("scheduleInfo", {
            hours: schedule.intervalHours,
            retention: schedule.retentionCount,
          })}
        </p>
      ) : null}

      <div className="overflow-x-auto rounded-lg border border-zinc-200 dark:border-zinc-800">
        <table className="min-w-full divide-y divide-zinc-200 text-sm dark:divide-zinc-800">
          <thead className="bg-zinc-50 dark:bg-zinc-900">
            <tr>
              <th className="px-4 py-2 text-left font-medium">{t("label")}</th>
              <th className="px-4 py-2 text-left font-medium">{t("status")}</th>
              <th className="px-4 py-2 text-left font-medium">{t("size")}</th>
              <th className="px-4 py-2 text-left font-medium">{t("created")}</th>
              <th className="px-4 py-2 text-right font-medium">{t("actions")}</th>
            </tr>
          </thead>
          <tbody className="divide-y divide-zinc-200 dark:divide-zinc-800">
            {backups.length === 0 ? (
              <tr>
                <td colSpan={5} className="px-4 py-6 text-center text-zinc-500">
                  {t("empty")}
                </td>
              </tr>
            ) : (
              backups.map((backup) => (
                <tr key={backup.id}>
                  <td className="px-4 py-2">{backup.label ?? backup.type}</td>
                  <td className="px-4 py-2">{backup.status}</td>
                  <td className="px-4 py-2">{formatBytes(backup.sizeBytes)}</td>
                  <td className="px-4 py-2">
                    {new Date(backup.createdAt).toLocaleString()}
                  </td>
                  <td className="px-4 py-2 text-right space-x-2">
                    {backup.status === "AVAILABLE" ? (
                      <>
                        <Button
                          size="sm"
                          variant="secondary"
                          onClick={() => void handleDownload(backup.id)}
                        >
                          {t("download")}
                        </Button>
                        <Button
                          size="sm"
                          variant="secondary"
                          onClick={() => void handleRestore(backup.id)}
                          disabled={busy}
                        >
                          {t("restore")}
                        </Button>
                      </>
                    ) : null}
                    <Button
                      size="sm"
                      variant="ghost"
                      onClick={() => void handleDelete(backup.id)}
                      disabled={busy}
                    >
                      {t("delete")}
                    </Button>
                  </td>
                </tr>
              ))
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
