/**
 * 系统设置 · 备份与恢复
 */
(function () {
  const page = document.getElementById("page-settings");
  if (!page) return;

  const elAuto = document.getElementById("backup-auto-enabled");
  const elHour = document.getElementById("backup-auto-hour");
  const elRetention = document.getElementById("backup-retention-days");
  const elIncludeEnv = document.getElementById("backup-include-env");
  const elIncludeImages = document.getElementById("backup-include-images");
  const elRoot = document.getElementById("backup-root");
  const elStatus = document.getElementById("backup-status-line");
  const elList = document.getElementById("backup-list");
  const elRun = document.getElementById("backup-run-now");
  const elRestoreFile = document.getElementById("backup-restore-file");
  const elRestoreBtn = document.getElementById("backup-restore-upload-btn");

  let settingsCache = null;
  let statusCache = null;

  function fmtBytes(n) {
    const v = Number(n);
    if (!Number.isFinite(v) || v < 0) return "—";
    if (v < 1024) return v + " B";
    if (v < 1024 * 1024) return (v / 1024).toFixed(1) + " KB";
    return (v / (1024 * 1024)).toFixed(2) + " MB";
  }

  function setStatus(msg, isErr) {
    if (!elStatus) return;
    elStatus.textContent = msg || "";
    elStatus.className = "backup-status-line" + (isErr ? " err" : "");
  }

  function collectBackupFromUI() {
    return {
      auto_enabled: !!(elAuto && elAuto.checked),
      auto_hour: Math.max(0, Math.min(23, parseInt(elHour && elHour.value, 10) || 0)),
      retention_days: Math.max(1, Math.min(365, parseInt(elRetention && elRetention.value, 10) || 30)),
      include_env: !!(elIncludeEnv && elIncludeEnv.checked),
      include_exchange_images: !!(elIncludeImages && elIncludeImages.checked),
      backup_root: (elRoot && elRoot.value || "").trim(),
    };
  }

  function syncBackupUI(data) {
    const b = (data && data.backup) || {};
    if (elAuto) elAuto.checked = b.auto_enabled !== false;
    if (elHour) elHour.value = b.auto_hour != null ? b.auto_hour : 0;
    if (elRetention) elRetention.value = b.retention_days != null ? b.retention_days : 30;
    if (elIncludeEnv) elIncludeEnv.checked = b.include_env !== false;
    if (elIncludeImages) elIncludeImages.checked = !!b.include_exchange_images;
    if (elRoot) elRoot.value = b.backup_root || "";
  }

  function renderBackupList(status) {
    if (!elList) return;
    const rows = (status && status.backups) || [];
    const state = (status && status.state) || {};
    const root = (status && status.backup_root) || "";
    let html = '<div class="backup-meta">';
    html += '<div>目录:<code>' + esc(root) + '</code></div>';
    if (state.last_backup_at) {
      html += '<div>上次备份:' + esc(state.last_backup_at) + '(' + esc(state.last_trigger || "") + ")</div>";
    }
    if (state.last_auto_at) {
      html += '<div>上次自动:' + esc(state.last_auto_at) + "</div>";
    }
    if (state.last_restore_at) {
      html += '<div>上次恢复:' + esc(state.last_restore_at) + " ← " + esc(state.last_restore_from || "") + "</div>";
    }
    html += "</div>";
    if (!rows.length) {
      html += '<p class="backup-empty">暂无备份文件</p>';
      elList.innerHTML = html;
      return;
    }
    html += '<table class="backup-table"><thead><tr><th>文件</th><th>大小</th><th>时间</th><th></th></tr></thead><tbody>';
    rows.forEach(function (row) {
      html +=
        "<tr><td>" +
        esc(row.name) +
        "</td><td>" +
        fmtBytes(row.size) +
        "</td><td>" +
        esc(row.modified_at || "") +
        '</td><td class="backup-row-actions">' +
        '<a class="ghost" href="/api/backup/download/' +
        encodeURIComponent(row.name) +
        '" download>下载</a> ' +
        '<button type="button" class="danger backup-restore-local" data-name="' +
        escAttr(row.name) +
        '">恢复</button></td></tr>';
    });
    html += "</tbody></table>";
    elList.innerHTML = html;
    elList.querySelectorAll(".backup-restore-local").forEach(function (btn) {
      btn.addEventListener("click", function () {
        restoreLocal(btn.getAttribute("data-name"));
      });
    });
  }

  function esc(s) {
    return String(s || "")
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/"/g, "&quot;");
  }

  function escAttr(s) {
    return esc(s).replace(/'/g, "&#39;");
  }

  async function loadSettingsData() {
    const r = await fetch("/api/settings", { credentials: "same-origin" });
    if (!r.ok) throw new Error("加载设置失败");
    settingsCache = await r.json();
    syncBackupUI(settingsCache);
  }

  async function loadBackupStatus() {
    const r = await fetch("/api/backup/status", { credentials: "same-origin" });
    if (!r.ok) throw new Error("加载备份状态失败");
    statusCache = await r.json();
    renderBackupList(statusCache);
  }

  async function saveBackupSettings() {
    if (!settingsCache) await loadSettingsData();
    const body = {
      exchanges: settingsCache.exchanges || [],
      display: settingsCache.display,
      supervisor: settingsCache.supervisor,
      backup: collectBackupFromUI(),
    };
    const r = await fetch("/api/settings", {
      method: "POST",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(body),
    });
    if (!r.ok) throw new Error("保存失败");
    settingsCache = (await r.json()).settings || settingsCache;
    syncBackupUI(settingsCache);
    await loadBackupStatus();
    if (typeof showToast === "function") showToast("备份设置已保存");
  }

  async function runBackupNow() {
    setStatus("备份中…");
    const r = await fetch("/api/backup/run", { method: "POST", credentials: "same-origin" });
    const data = await r.json().catch(function () {
      return {};
    });
    if (!r.ok) {
      setStatus(data.detail || "备份失败", true);
      return;
    }
    setStatus("完成:" + (data.file || "") + "(" + fmtBytes(data.size) + ")");
    await loadBackupStatus();
    if (typeof showToast === "function") showToast("备份完成");
  }

  async function restoreLocal(name) {
    if (!name) return;
    if (!window.confirm("确认从服务器备份 " + name + " 恢复?\n恢复前会自动做 pre-restore 快照并重启 PM2.")) return;
    if (window.prompt('请输入 RESTORE 确认恢复') !== "RESTORE") return;
    setStatus("恢复中…");
    const r = await fetch("/api/backup/restore-local", {
      method: "POST",
      credentials: "same-origin",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: name, confirm: "RESTORE" }),
    });
    const data = await r.json().catch(function () {
      return {};
    });
    if (!r.ok) {
      setStatus(data.detail || "恢复失败", true);
      return;
    }
    setStatus("恢复完成,已恢复 " + ((data.restored && data.restored.length) || 0) + " 个文件");
    await loadBackupStatus();
    if (typeof showToast === "function") showToast("恢复完成,请刷新页面");
  }

  async function restoreUpload() {
    const file = elRestoreFile && elRestoreFile.files && elRestoreFile.files[0];
    if (!file) {
      setStatus("请选择 .zip 备份文件", true);
      return;
    }
    if (!window.confirm("确认上传并恢复 " + file.name + "?\n恢复前会自动做 pre-restore 快照并重启 PM2.")) return;
    if (window.prompt('请输入 RESTORE 确认恢复') !== "RESTORE") return;
    setStatus("上传并恢复中…");
    const fd = new FormData();
    fd.append("file", file);
    fd.append("confirm", "RESTORE");
    const r = await fetch("/api/backup/restore", {
      method: "POST",
      credentials: "same-origin",
      body: fd,
    });
    const data = await r.json().catch(function () {
      return {};
    });
    if (!r.ok) {
      setStatus(data.detail || "恢复失败", true);
      return;
    }
    setStatus("恢复完成,已恢复 " + ((data.restored && data.restored.length) || 0) + " 个文件");
    if (elRestoreFile) elRestoreFile.value = "";
    await loadBackupStatus();
    if (typeof showToast === "function") showToast("恢复完成,请刷新页面");
  }

  window.initBackupSettingsUI = async function () {
    try {
      await loadSettingsData();
      await loadBackupStatus();
      setStatus("");
    } catch (e) {
      setStatus(e.message || String(e), true);
    }
  };

  if (elRun) elRun.addEventListener("click", function () {
    runBackupNow().catch(function (e) {
      setStatus(e.message || String(e), true);
    });
  });

  if (elRestoreBtn) elRestoreBtn.addEventListener("click", function () {
    restoreUpload().catch(function (e) {
      setStatus(e.message || String(e), true);
    });
  });

  page.addEventListener("click", function (ev) {
    const btn = ev.target.closest(".settings-section-save[data-settings-section='backup']");
    if (!btn) return;
    ev.preventDefault();
    saveBackupSettings().catch(function (e) {
      setStatus(e.message || String(e), true);
    });
  });
})();
