/**
 * 策略说明:策略正文(目录 h2 + 章节标识) + 执行清单 Tab.
 */
(function () {
  const page = document.getElementById("page-strategy");
  if (!page) return;

  const tabsEl = document.getElementById("strategy-tabs");
  const viewTabsEl = document.getElementById("strategy-view-tabs");
  const statusEl = document.getElementById("strategy-load-status");
  const docBody = document.getElementById("strategy-doc-body");
  const docSource = document.getElementById("strategy-doc-source");
  const docToc = document.getElementById("strategy-doc-toc");
  const panelDoc = document.getElementById("strategy-panel-doc");
  const panelChecklist = document.getElementById("strategy-panel-checklist");
  const checklistTitle = document.getElementById("strategy-checklist-title");
  const checklistBody = document.getElementById("strategy-checklist-body");
  const footnotesEl = document.getElementById("strategy-checklist-footnotes");
  const btnPrintDoc = document.getElementById("strategy-btn-print-doc");
  const btnPrintChecklist = document.getElementById("strategy-btn-print-checklist");
  const btnPrintChecklistInline = document.getElementById("strategy-btn-print-checklist-inline");
  const btnDownload = document.getElementById("strategy-btn-download");

  let activeKey = "playbook_v2";
  let activeView = "doc";
  let tabsMeta = [];
  let cache = {};
  let bound = false;
  let scrollSpyObs = null;

  async function apiFetch(url, opts) {
    const r = await fetch(url, { credentials: "same-origin", ...(opts || {}) });
    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) || 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 slugify(text) {
    return String(text || "")
      .trim()
      .toLowerCase()
      .replace(/\s+/g, "-")
      .replace(/[^\w\u4e00-\u9fff\-]+/g, "")
      .replace(/\-+/g, "-")
      .replace(/^\-|\-$/g, "")
      .slice(0, 48);
  }

  function setView(view) {
    activeView = view === "checklist" ? "checklist" : "doc";
    if (panelDoc) panelDoc.classList.toggle("hidden", activeView !== "doc");
    if (panelChecklist) panelChecklist.classList.toggle("hidden", activeView !== "checklist");
    if (viewTabsEl) {
      viewTabsEl.querySelectorAll(".strategy-view-tab").forEach((btn) => {
        const on = btn.getAttribute("data-view") === activeView;
        btn.classList.toggle("is-active", on);
        btn.setAttribute("aria-selected", on ? "true" : "false");
      });
    }
  }

  function renderExchangeTabs() {
    if (!tabsEl) return;
    if (!tabsMeta.length) {
      tabsEl.innerHTML = "";
      if (statusEl) statusEl.textContent = "当前无可显示的策略页签(可在系统设置·显示与导航中开启)";
      if (docBody) docBody.innerHTML = "";
      if (docToc) docToc.innerHTML = "";
      if (checklistBody) checklistBody.innerHTML = "";
      return;
    }
    tabsEl.innerHTML = tabsMeta
      .map(
        (t) =>
          `<button type="button" class="strategy-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(".strategy-tab").forEach((btn) => {
      btn.addEventListener("click", () => {
        const key = btn.getAttribute("data-key");
        if (!key || key === activeKey) return;
        activeKey = key;
        renderExchangeTabs();
        void loadExchange(key);
      });
    });
  }

  function setActiveToc(id) {
    if (!docToc) return;
    docToc.querySelectorAll(".strategy-toc-item").forEach((a) => {
      a.classList.toggle("is-active", a.getAttribute("data-id") === id);
    });
  }

  function bindScrollSpy(heads) {
    if (scrollSpyObs) {
      scrollSpyObs.disconnect();
      scrollSpyObs = null;
    }
    if (!docBody || !heads.length || typeof IntersectionObserver === "undefined") return;
    const visible = new Map();
    scrollSpyObs = new IntersectionObserver(
      (entries) => {
        entries.forEach((en) => {
          if (en.isIntersecting) visible.set(en.target.id, en.intersectionRatio);
          else visible.delete(en.target.id);
        });
        let bestId = "";
        let bestRatio = -1;
        visible.forEach((ratio, id) => {
          if (ratio > bestRatio) {
            bestRatio = ratio;
            bestId = id;
          }
        });
        if (bestId) setActiveToc(bestId);
      },
      { root: docBody, rootMargin: "-8% 0px -70% 0px", threshold: [0, 0.25, 0.5, 1] }
    );
    heads.forEach((h) => scrollSpyObs.observe(h));
  }

  function sectionTag(title) {
    const t = String(title || "");
    if (/总原则|原则/.test(t)) return "原则";
    if (/账户|定位|分工/.test(t)) return "账户";
    if (/开仓类型|开仓|入场|反转|顺势|波段|假破|结构|对冲|方向单/.test(t)) return "入场";
    if (/周期/.test(t)) return "周期";
    if (/方向/.test(t)) return "方向";
    if (/纪律|出场|笔数|节奏|止损|次数/.test(t)) return "纪律";
    if (/持仓|离场|强平|到期/.test(t)) return "离场";
    if (/资金|杠杆|计仓|仓位|预算/.test(t)) return "仓位";
    if (/系统|字段|对接/.test(t)) return "系统";
    if (/修订|记录/.test(t)) return "版本";
    if (/边界|关系|行情状态/.test(t)) return "边界";
    if (/选择|如何/.test(t)) return "选择";
    return "章节";
  }

  function buildDocToc() {
    if (!docBody || !docToc) return;
    const heads = Array.from(docBody.querySelectorAll("h2"));
    if (!heads.length) {
      docToc.innerHTML = '<p class="strategy-empty">暂无目录</p>';
      return;
    }
    const used = {};
    const items = [];
    heads.forEach((el, idx) => {
      const num = String(idx + 1).padStart(2, "0");
      const text = (el.textContent || "").trim();
      const tag = sectionTag(text);
      let base = "st-" + num + "-" + slugify(text);
      if (!base || base === "st-" + num + "-") base = "st-" + num;
      let id = base;
      let n = 2;
      while (used[id] || document.getElementById(id)) {
        id = base + "-" + n;
        n += 1;
      }
      used[id] = true;
      el.id = id;
      if (!el.querySelector(".strategy-sec-mark")) {
        const mark = document.createElement("span");
        mark.className = "strategy-sec-mark";
        mark.setAttribute("aria-hidden", "true");
        mark.innerHTML =
          `<span class="strategy-sec-num">${esc(num)}</span>` +
          `<span class="strategy-sec-tag">${esc(tag)}</span>`;
        el.insertBefore(mark, el.firstChild);
      }
      items.push({ num, id, text, tag });
    });
    Array.from(docBody.querySelectorAll("h3")).forEach((el, idx) => {
      if (el.id) return;
      let base = "st-h3-" + (idx + 1) + "-" + slugify(el.textContent);
      if (!base || base.endsWith("-")) base = "st-h3-" + (idx + 1);
      let id = base;
      let n = 2;
      while (document.getElementById(id)) {
        id = base + "-" + n;
        n += 1;
      }
      el.id = id;
    });
    docToc.innerHTML = items
      .map(
        (it) =>
          `<a href="#${esc(it.id)}" class="strategy-toc-item" data-id="${esc(it.id)}">` +
          `<span class="strategy-toc-num">${esc(it.num)}</span>` +
          `<span class="strategy-toc-tag">${esc(it.tag)}</span>` +
          `<span class="strategy-toc-text">${esc(it.text)}</span></a>`
      )
      .join("");
    docToc.querySelectorAll(".strategy-toc-item").forEach((a) => {
      a.addEventListener("click", (ev) => {
        ev.preventDefault();
        const id = a.getAttribute("data-id");
        const target = id ? document.getElementById(id) : null;
        if (!target || !docBody.contains(target)) return;
        setActiveToc(id);
        target.scrollIntoView({ behavior: "smooth", block: "start" });
      });
    });
    if (items[0]) setActiveToc(items[0].id);
    bindScrollSpy(heads);
  }

  function renderChecklist(checklist) {
    const cl = checklist || {};
    const title = cl.title || "开仓检查清单";
    if (checklistTitle) checklistTitle.textContent = title;
    if (!checklistBody) return;
    const groups = cl.groups || [];
    if (!groups.length) {
      checklistBody.innerHTML = '<p class="strategy-empty">暂无检查清单</p>';
    } else {
      checklistBody.innerHTML = groups
        .map((grp) => {
          const items = (grp.items || [])
            .map((item) => `<li><span class="strategy-check-box" aria-hidden="true">☐</span>${esc(item)}</li>`)
            .join("");
          return `<div class="strategy-check-group"><h4>${esc(grp.title || "")}</h4><ul>${items}</ul></div>`;
        })
        .join("");
    }
    if (footnotesEl) {
      const notes = cl.footnotes || [];
      footnotesEl.innerHTML = notes.map((n) => `<li>${esc(n)}</li>`).join("");
      footnotesEl.classList.toggle("hidden", !notes.length);
    }
  }

  function renderPayload(data) {
    if (docBody) docBody.innerHTML = data.strategy_html || "";
    if (docSource) {
      const ver = data.version ? ` · ${data.version}` : "";
      docSource.textContent = `文档:${data.md_source || ""}${ver}`;
    }
    buildDocToc();
    renderChecklist(data.checklist);
  }

  async function loadExchange(key) {
    if (statusEl) statusEl.textContent = "加载中…";
    try {
      let data = cache[key];
      if (!data) {
        data = await apiFetch(`/api/strategy/${encodeURIComponent(key)}`);
        cache[key] = data;
      }
      renderPayload(data);
      if (statusEl) statusEl.textContent = "";
    } catch (e) {
      if (statusEl) statusEl.textContent = String(e);
      if (docBody) docBody.innerHTML = "";
      if (docToc) docToc.innerHTML = "";
      if (checklistBody) checklistBody.innerHTML = "";
    }
  }

  async function loadMeta() {
    const meta = await apiFetch("/api/strategy/meta");
    tabsMeta = meta.exchanges || [];
    if (tabsMeta.length && !tabsMeta.some((t) => t.key === activeKey)) {
      activeKey = tabsMeta[0].key;
    }
    renderExchangeTabs();
  }

  async function reloadMeta() {
    try {
      await loadMeta();
      if (tabsMeta.length) await loadExchange(activeKey);
    } catch (e) {
      if (statusEl) statusEl.textContent = String(e);
    }
  }

  async function printSection(mode) {
    const part = mode === "checklist" ? "checklist" : "doc";
    const url = `/api/strategy/${encodeURIComponent(activeKey)}/print?part=${encodeURIComponent(part)}`;
    const w = window.open("about:blank", "_blank");
    if (!w) {
      if (statusEl) statusEl.textContent = "请允许弹出窗口以打开打印预览";
      return;
    }
    try {
      w.document.write(
        "<!DOCTYPE html><title>打印准备中…</title><body style=\"font-family:sans-serif;padding:24px;color:#222\">正在加载打印内容…</body>"
      );
      w.document.close();
    } catch (_) {}
    try {
      const r = await fetch(url, { credentials: "same-origin" });
      const html = await r.text();
      if (!r.ok) {
        throw new Error((html && html.slice(0, 120)) || r.statusText || "加载打印页失败");
      }
      w.document.open();
      w.document.write(html);
      w.document.close();
      if (statusEl) statusEl.textContent = "";
    } catch (e) {
      const msg = String(e && e.message ? e.message : e);
      try {
        w.document.open();
        w.document.write(
          `<!DOCTYPE html><body style="font-family:sans-serif;padding:24px;color:#222">打印页加载失败: ${esc(msg)}</body>`
        );
        w.document.close();
      } catch (_) {}
      if (statusEl) statusEl.textContent = msg;
    }
  }

  function bindActions() {
    if (bound) return;
    bound = true;
    if (viewTabsEl) {
      viewTabsEl.querySelectorAll(".strategy-view-tab").forEach((btn) => {
        btn.addEventListener("click", () => setView(btn.getAttribute("data-view")));
      });
    }
    if (btnPrintDoc) btnPrintDoc.addEventListener("click", () => printSection("doc"));
    if (btnPrintChecklist) btnPrintChecklist.addEventListener("click", () => printSection("checklist"));
    if (btnPrintChecklistInline) btnPrintChecklistInline.addEventListener("click", () => printSection("checklist"));
    if (btnDownload) {
      btnDownload.addEventListener("click", () => {
        window.location.href = `/api/strategy/${encodeURIComponent(activeKey)}/export`;
      });
    }
  }

  async function init() {
    bindActions();
    setView(activeView);
    try {
      await loadMeta();
      if (tabsMeta.length) await loadExchange(activeKey);
      else if (statusEl) statusEl.textContent = "当前无可显示的策略页签(可在系统设置·显示与导航中开启)";
    } catch (e) {
      if (statusEl) statusEl.textContent = String(e);
    }
  }

  function destroy() {
    if (scrollSpyObs) {
      scrollSpyObs.disconnect();
      scrollSpyObs = null;
    }
  }

  window.hubStrategyPage = { init, destroy, reloadMeta };
})();
