/**
 * 系统日志:三所 + 中控 PM2 stdout/stderr.
 */
(function () {
  const page = document.getElementById("page-logs");
  if (!page) return;

  const tabsEl = document.getElementById("hub-logs-tabs");
  const statusEl = document.getElementById("hub-logs-status");
  const outEl = document.getElementById("hub-logs-out");
  const errEl = document.getElementById("hub-logs-err");
  const btnRefresh = document.getElementById("hub-logs-btn-refresh");
  const btnPause = document.getElementById("hub-logs-btn-pause");

  const POLL_MS = 4000;
  let activeKey = "binance";
  let tabsMeta = [];
  let pollTimer = null;
  let paused = false;
  let loading = false;
  let bound = false;

  async function apiFetch(url) {
    const r = await fetch(url, { credentials: "same-origin" });
    const ct = (r.headers.get("content-type") || "").toLowerCase();
    if (ct.includes("application/json")) {
      const data = await r.json();
      if (!r.ok) throw new Error((data && (data.msg || data.detail)) || r.statusText || "请求失败");
      return data;
    }
    if (!r.ok) throw new Error(r.statusText || "请求失败");
    return r;
  }

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

  function wasScrolledToBottom(el) {
    if (!el) return true;
    return el.scrollHeight - el.scrollTop - el.clientHeight < 24;
  }

  function setPreText(el, text, stickBottom) {
    if (!el) return;
    const atBottom = stickBottom || wasScrolledToBottom(el);
    el.textContent = text || "(暂无日志)";
    if (atBottom) el.scrollTop = el.scrollHeight;
  }

  function setStatus(text, isErr) {
    if (!statusEl) return;
    statusEl.textContent = text || "";
    statusEl.classList.toggle("is-err", !!isErr);
  }

  function renderTabs() {
    if (!tabsEl) return;
    tabsEl.innerHTML = tabsMeta
      .map(
        (t) =>
          `<button type="button" class="hub-logs-tab${t.key === activeKey ? " is-active" : ""}" role="tab" aria-selected="${t.key === activeKey}" data-key="${esc(t.key)}">${esc(t.label)}</button>`
      )
      .join("");
    tabsEl.querySelectorAll(".hub-logs-tab").forEach((btn) => {
      btn.addEventListener("click", () => {
        const key = btn.getAttribute("data-key");
        if (!key || key === activeKey) return;
        activeKey = key;
        renderTabs();
        void loadLogs(true);
      });
    });
  }

  async function loadMeta() {
    const meta = await apiFetch("/api/system-logs/meta");
    tabsMeta = Array.isArray(meta.targets) ? meta.targets : [];
    if (tabsMeta.length && !tabsMeta.some((t) => t.key === activeKey)) {
      activeKey = tabsMeta[0].key;
    }
    renderTabs();
  }

  async function loadLogs(force) {
    if (loading && !force) return;
    loading = true;
    try {
      const data = await apiFetch(`/api/system-logs/${encodeURIComponent(activeKey)}?lines=200`);
      setPreText(outEl, data.out || "", true);
      setPreText(errEl, data.err || "", true);
      const ts = data.updated_at ? new Date(data.updated_at * 1000) : new Date();
      const hh = String(ts.getHours()).padStart(2, "0");
      const mm = String(ts.getMinutes()).padStart(2, "0");
      const ss = String(ts.getSeconds()).padStart(2, "0");
      const missing = [];
      if (!data.out_exists) missing.push("实时");
      if (!data.err_exists) missing.push("报错");
      const hint = missing.length ? ` · ${missing.join("/")}日志文件暂无` : "";
      setStatus(`已更新 ${hh}:${mm}:${ss}${hint}`, false);
    } catch (e) {
      setStatus(e.message || "加载失败", true);
    } finally {
      loading = false;
    }
  }

  function startPoll() {
    stopPoll();
    if (paused) return;
    pollTimer = window.setInterval(() => {
      void loadLogs(false);
    }, POLL_MS);
  }

  function stopPoll() {
    if (pollTimer) {
      clearInterval(pollTimer);
      pollTimer = null;
    }
  }

  function bindControls() {
    if (bound) return;
    bound = true;
    if (btnRefresh) {
      btnRefresh.addEventListener("click", () => {
        void loadLogs(true);
      });
    }
    if (btnPause) {
      btnPause.addEventListener("click", () => {
        paused = !paused;
        btnPause.textContent = paused ? "继续刷新" : "暂停刷新";
        btnPause.classList.toggle("is-paused", paused);
        if (paused) stopPoll();
        else startPoll();
      });
    }
  }

  async function init() {
    bindControls();
    paused = false;
    if (btnPause) {
      btnPause.textContent = "暂停刷新";
      btnPause.classList.remove("is-paused");
    }
    setStatus("加载中…", false);
    try {
      await loadMeta();
      await loadLogs(true);
      startPoll();
    } catch (e) {
      setStatus(e.message || "初始化失败", true);
    }
  }

  function destroy() {
    stopPoll();
    setStatus("", false);
  }

  window.hubLogsPage = { init, destroy };
})();
