/**
 * 三所实例主题:默认暗色;单独登录用 instance-theme;中控 iframe/SSO 随 hub-theme 联动.
 */
(function (global) {
  const STANDALONE_KEY = "instance-theme";
  const HUB_LINKED_THEME_KEY = "hub-linked-theme";
  const META = { dark: "#0b0d14", light: "#c8d4de" };

  function normalize(theme) {
    return theme === "light" ? "light" : "dark";
  }

  function isHubLinked() {
    try {
      if (window.self !== window.top) return true;
    } catch (_) {
      return true;
    }
    return false;
  }

  function themeFromUrl() {
    try {
      const t = new URLSearchParams(location.search).get("hub_theme");
      if (t === "light" || t === "dark") return t;
    } catch (_) {}
    return null;
  }

  function readLinkedThemeStorage() {
    try {
      const t = sessionStorage.getItem(HUB_LINKED_THEME_KEY);
      if (t === "light" || t === "dark") return t;
    } catch (_) {}
    return null;
  }

  function writeLinkedThemeStorage(theme) {
    if (!isHubLinked()) return;
    try {
      sessionStorage.setItem(HUB_LINKED_THEME_KEY, normalize(theme));
    } catch (_) {}
  }

  function getStandalone() {
    try {
      return normalize(localStorage.getItem(STANDALONE_KEY));
    } catch (_) {
      return "dark";
    }
  }

  function setStandalone(theme) {
    try {
      localStorage.setItem(STANDALONE_KEY, normalize(theme));
    } catch (_) {}
  }

  let _linkedTheme = null;
  let _appliedTheme = null;

  function get() {
    if (isHubLinked()) {
      return themeFromUrl() || _linkedTheme || readLinkedThemeStorage() || "dark";
    }
    return getStandalone();
  }

  /** 模板内联暗色 → 亮色(切换时重写 style 属性) */
  const INLINE_HEX_LIGHT = {
    "#cfd3ef": "#1a2838",
    "#8892b0": "#4a6078",
    "#9aa3c4": "#4a6078",
    "#8b95a8": "#4a6078",
    "#8b95b8": "#4a6078",
    "#6a7598": "#4a6078",
    "#7d8799": "#4a6078",
    "#6d7689": "#4a6078",
    "#dbe4ff": "#142232",
    "#f0f2ff": "#142232",
    "#e8ecf4": "#142232",
    "#c5cce0": "#4a6078",
    "#b8c4ff": "#142232",
    "#8fc8ff": "#006e9a",
    "#6ab8ff": "#006e9a",
    "#6eb5ff": "#006e9a",
    "#101522": "#ffffff",
    "#121726": "#ffffff",
    "#141423": "#ffffff",
    "#24243b": "#b8c8d8",
    "#252a45": "#b8c8d8",
    "#252538": "#eef3f8",
    "#1a1a29": "#f6f9fc",
    "#2e2e45": "#b8c8d8",
    "#2b2b43": "#d0dae4",
    "#151a2a": "#eef3f8",
    "#141a2a": "#ffffff",
    "#141923": "#ffffff",
    "#141a2e": "#ffffff",
    "#0f1424": "#f6f9fc",
    "#0f1420": "#f6f9fc",
    "#0f1117": "#d8e2ec",
    "#1a2034": "#eef3f8",
    "#1a2030": "#ffffff",
    "#1f3a5a": "#e8eef5",
    "#2f2f44": "#dde5ec",
    "#2a3f6c": "rgba(0,110,154,0.14)",
    "#304164": "rgba(0,95,140,0.22)",
    "#2a3150": "#b8c8d8",
    "#2a3152": "#b8c8d8",
    "#3a5a8a": "rgba(0,95,140,0.35)",
    "#2a3348": "#b8c8d8",
    "#243050": "rgba(0,75,115,0.16)",
    "#2a3558": "#d0dae4",
    "#3a4468": "#c8d4e0",
    "#3a4a66": "#b8c8d8",
    "#3a3f52": "#dde5ec",
    "#3d4659": "#b8c8d8",
    "#1f2740": "#eef3f8",
    "#1f2a44": "rgba(0,110,154,0.1)",
    "#1f4a3a": "#e8f5ef",
    "#2a4a7a": "#e8eef5",
    "#3a3048": "#eef3f8",
    "#d4b8ff": "#5b4fc7",
    "#e6e8ef": "#1a2838",
  };

  function remapInlineStyle(style, theme) {
    if (!style) return style;
    if (theme !== "light") return style;
    const hadSecondaryBtnBg = /#1f3a5a/i.test(style);
    let out = style;
    for (const [from, to] of Object.entries(INLINE_HEX_LIGHT)) {
      out = out.replace(new RegExp(from.replace("#", "\\#"), "gi"), to);
    }
    if (hadSecondaryBtnBg && !/color\s*:/i.test(style)) {
      out = `${out.replace(/;+\s*$/, "")};color:#006e9a`;
    }
    return out;
  }

  function syncInlineStyles(theme, root) {
    const scope = root || document;
    scope.querySelectorAll("[style]").forEach((el) => {
      const raw = el.getAttribute("style");
      if (!raw) return;
      if (!el.dataset.instStyleBase) {
        el.dataset.instStyleBase = raw;
      }
      const base = el.dataset.instStyleBase;
      el.setAttribute("style", theme === "light" ? remapInlineStyle(base, "light") : base);
    });
  }

  function mergeHubQueryIntoHref(href, theme) {
    if (!href || href.startsWith("#") || href.startsWith("javascript:")) return href;
    try {
      const u = new URL(href, location.origin);
      if (u.origin !== location.origin) return href;
      if (isHubLinked()) {
        u.searchParams.set("embed", "1");
        if (theme === "light" || theme === "dark") {
          u.searchParams.set("hub_theme", theme);
        }
      }
      return u.pathname + u.search + u.hash;
    } catch (_) {
      return href;
    }
  }

  function patchHubNavLinks(theme) {
    if (!isHubLinked()) return;
    const t = normalize(theme || get());
    document
      .querySelectorAll(".top-nav a[href], .strategy-subnav a[href]")
      .forEach((a) => {
        const href = a.getAttribute("href");
        if (!href) return;
        const next = mergeHubQueryIntoHref(href, t);
        if (next !== href) a.setAttribute("href", next);
      });
  }

  function apply(theme, opts) {
    const options = opts || {};
    const linked = isHubLinked();
    const t = normalize(theme);
    const root = document.documentElement;
    const unchanged =
      !options.force &&
      _appliedTheme === t &&
      root.getAttribute("data-theme") === t;
    if (unchanged) {
      return t;
    }
    _appliedTheme = t;
    if (linked) {
      _linkedTheme = t;
      writeLinkedThemeStorage(t);
      root.setAttribute("data-hub-linked", "1");
    } else {
      root.removeAttribute("data-hub-linked");
    }
    if (!linked && !options.skipStore) {
      setStandalone(t);
    }
    root.setAttribute("data-theme", t);
    const meta = document.querySelector('meta[name="theme-color"]');
    if (meta) meta.setAttribute("content", META[t]);
    root.style.colorScheme = t;
    if (document.body) {
      syncInlineStyles(t);
      patchHubNavLinks(t);
    } else {
      document.addEventListener(
        "DOMContentLoaded",
        function onDom() {
          syncInlineStyles(t);
          patchHubNavLinks(t);
        },
        { once: true }
      );
    }
    syncToggleUI();
    document.dispatchEvent(
      new CustomEvent("instance-theme-change", { detail: { theme: t, hubLinked: linked } })
    );
    return t;
  }

  function syncToggleUI(root) {
    const scope = root || document;
    const linked = isHubLinked();
    const toggle = scope.querySelector(".instance-theme-toggle");
    if (toggle) {
      toggle.classList.toggle("is-hub-linked", linked);
      toggle.setAttribute("aria-hidden", linked ? "true" : "false");
    }
    if (linked) return;
    scope.querySelectorAll(".theme-toggle-btn[data-theme-value]").forEach((btn) => {
      const on = btn.getAttribute("data-theme-value") === getStandalone();
      btn.classList.toggle("is-active", on);
      btn.setAttribute("aria-pressed", on ? "true" : "false");
    });
  }

  function initToggleUI(root) {
    const scope = root || document;
    syncToggleUI(scope);
    scope.querySelectorAll(".theme-toggle-btn[data-theme-value]").forEach((btn) => {
      if (btn.dataset.themeBound === "1") return;
      btn.dataset.themeBound = "1";
      btn.addEventListener("click", () => {
        if (isHubLinked()) return;
        apply(btn.getAttribute("data-theme-value"));
      });
    });
  }

  function initMobileTopNav() {
    const mq = window.matchMedia("(max-width: 720px)");

    function scrollActiveTab(nav) {
      const active = nav.querySelector("a.active");
      if (!active) return;
      requestAnimationFrame(() => {
        try {
          active.scrollIntoView({ inline: "center", block: "nearest", behavior: "instant" });
        } catch (_) {
          active.scrollIntoView(false);
        }
      });
    }

    function apply() {
      if (!mq.matches) return;
      document.querySelectorAll(".top-nav").forEach(scrollActiveTab);
    }

    apply();
    mq.addEventListener("change", apply);
    window.addEventListener("resize", apply);
    window.addEventListener("orientationchange", apply);
  }

  function initFromHubMessage(data) {
    if (!data || data.type !== "hub-theme-sync") return;
    if (!isHubLinked()) return;
    apply(data.theme, { skipStore: true });
  }

  /** 交易记录页:核对开关与按钮 disabled 保持同步(含 iframe 软导航后动态挂载的 toggle) */
  function syncReviewEditButtons() {
    const toggle = document.getElementById("review-mode-toggle");
    if (!toggle) return;
    const on = !!toggle.checked;
    document.querySelectorAll(".review-edit-btn").forEach((btn) => {
      btn.disabled = !on;
    });
  }

  function initReviewEditModeSync() {
    if (!global.__instReviewModeBound) {
      global.__instReviewModeBound = true;
      const onToggle = () => {
        if (typeof global.toggleReviewMode === "function") global.toggleReviewMode();
        else syncReviewEditButtons();
      };
      document.addEventListener("change", (ev) => {
        if (ev.target && ev.target.id === "review-mode-toggle") onToggle();
      });
      document.addEventListener("input", (ev) => {
        if (ev.target && ev.target.id === "review-mode-toggle") onToggle();
      });
    }
    const run = () => {
      if (typeof global.toggleReviewMode === "function") global.toggleReviewMode();
      else syncReviewEditButtons();
    };
    run();
    requestAnimationFrame(run);
    setTimeout(run, 0);
    if (!global.__instReviewModePageshowBound) {
      global.__instReviewModePageshowBound = true;
      window.addEventListener("pageshow", run);
    }
  }

  function notifyParentFrameNavStart() {
    if (!isHubLinked()) return;
    try {
      window.parent.postMessage({ type: "instance-frame-navigating", theme: get() }, "*");
    } catch (_) {}
  }

  function notifyParentFrameReady() {
    if (!isHubLinked()) return;
    dismissNavOverlay();
    try {
      window.parent.postMessage({ type: "instance-frame-ready", theme: get() }, "*");
    } catch (_) {}
  }

  function ensureNavOverlay() {
    const t = normalize(get());
    const bg = META[t];
    let el = document.getElementById("inst-nav-overlay");
    if (!el) {
      el = document.createElement("div");
      el.id = "inst-nav-overlay";
      el.setAttribute("aria-hidden", "true");
      (document.body || document.documentElement).appendChild(el);
    }
    el.style.cssText =
      "position:fixed;inset:0;z-index:2147483646;background:" +
      bg +
      ";opacity:1;pointer-events:auto;transition:opacity 80ms ease;";
    return el;
  }

  function dismissNavOverlay() {
    const el = document.getElementById("inst-nav-overlay");
    if (!el) return;
    el.style.opacity = "0";
    window.setTimeout(() => {
      try {
        el.remove();
      } catch (_) {}
    }, 90);
  }

  function injectNavOverlayIntoHtml(html, theme) {
    const t = normalize(theme || get());
    const bg = META[t];
    let out = html || "";
    const guard =
      '<style id="inst-nav-guard">html,body{background:' +
      bg +
      "!important;color-scheme:" +
      t +
      ';}</style>';
    if (out.includes("</head>")) {
      out = out.replace("</head>", guard + "</head>");
    } else {
      out = guard + out;
    }
    out = out.replace(/<html([^>]*)>/i, (m, attrs) => {
      if (/data-theme=/i.test(attrs)) {
        return m.replace(/data-theme="[^"]*"/i, 'data-theme="' + t + '"');
      }
      return "<html" + attrs + ' data-theme="' + t + '">';
    });
    const overlay =
      '<div id="inst-nav-overlay" aria-hidden="true" style="position:fixed;inset:0;z-index:2147483646;background:' +
      bg +
      ';opacity:1;pointer-events:auto"></div>';
    if (/<body[^>]*>/i.test(out)) {
      out = out.replace(/<body([^>]*)>/i, "<body$1>" + overlay);
    }
    return out;
  }

  /** 中控 iframe:fetch 换页 + 页内遮罩,避免整页卸载与中控侧长时间空白. */
  function initHubEmbedInFrameNav() {
    if (!isHubLinked()) return;
    if (document.body && document.body.getAttribute("data-embed-shell") === "1") return;

    let navToken = 0;

    function isSoftNavLink(a) {
      if (!a || !a.getAttribute) return false;
      if (a.hasAttribute("download") || a.target === "_blank") return false;
      return !!a.closest(".top-nav, .strategy-subnav");
    }

    function softNavFetch(href) {
      return fetch(href, {
        credentials: "same-origin",
        headers: { "X-Instance-Soft-Nav": "1" },
      });
    }

    async function navigateInFrame(href, opts) {
      const token = ++navToken;
      notifyParentFrameNavStart();
      ensureNavOverlay();
      try {
        const r = await softNavFetch(href);
        if (token !== navToken) return;
        if (!r.ok) {
          location.assign(href);
          return;
        }
        let html = await r.text();
        if (token !== navToken) return;
        html = injectNavOverlayIntoHtml(html, get());
        let path = href;
        try {
          const u = new URL(href, location.href);
          path = u.pathname + u.search + u.hash;
        } catch (_) {}
        if (opts && opts.replace) history.replaceState(null, "", path);
        else history.pushState(null, "", path);
        document.open();
        document.write(html);
        document.close();
      } catch (_) {
        if (token === navToken) location.assign(href);
      }
    }

    document.addEventListener(
      "click",
      (ev) => {
        const a = ev.target.closest("a[href]");
        if (!a || !isSoftNavLink(a) || ev.defaultPrevented) return;
        if (ev.button !== 0 || ev.ctrlKey || ev.metaKey || ev.shiftKey || ev.altKey) return;
        const rawHref = a.getAttribute("href");
        if (!rawHref || rawHref.startsWith("#") || rawHref.startsWith("javascript:")) return;
        let target;
        try {
          target = new URL(rawHref, location.href);
        } catch (_) {
          return;
        }
        if (target.origin !== location.origin) return;
        const nextHref = target.pathname + target.search + target.hash;
        if (target.pathname === location.pathname && target.search === location.search) return;
        ev.preventDefault();
        void navigateInFrame(nextHref);
      },
      true
    );

    window.addEventListener("popstate", () => {
      void navigateInFrame(location.pathname + location.search + location.hash, { replace: true });
    });
  }

  function purgeLegacySoftNavCache() {
    try {
      for (let i = localStorage.length - 1; i >= 0; i -= 1) {
        const key = localStorage.key(i);
        if (!key) continue;
        if (
          key.startsWith("inst-pc:") ||
          key === "inst-page-cache-index" ||
          key === "inst-page-cache-days"
        ) {
          localStorage.removeItem(key);
        }
      }
      sessionStorage.removeItem("inst-soft-nav");
      sessionStorage.removeItem("inst-cache-revalidate");
    } catch (_) {}
  }

  function boot() {
    purgeLegacySoftNavCache();
    if (isHubLinked()) {
      apply(get(), { skipStore: true });
      window.addEventListener("message", (ev) => initFromHubMessage(ev.data));
      initHubEmbedInFrameNav();
      try {
        window.parent.postMessage({ type: "instance-theme-ready" }, "*");
      } catch (_) {}
    } else {
      apply(getStandalone());
    }

    function observeDynamicLists() {
      ["journal-list", "review-list"].forEach((id) => {
        const el = document.getElementById(id);
        if (!el || el.dataset.instThemeObserved === "1") return;
        el.dataset.instThemeObserved = "1";
        new MutationObserver(() => {
          syncInlineStyles(get());
          patchHubNavLinks(get());
        }).observe(el, {
          childList: true,
          subtree: true,
        });
      });
    }

    const onReady = () => {
      initToggleUI();
      initMobileTopNav();
      initReviewEditModeSync();
      syncInlineStyles(get());
      patchHubNavLinks(get());
      observeDynamicLists();
      if (isHubLinked()) {
        requestAnimationFrame(() => {
          requestAnimationFrame(() => notifyParentFrameReady());
        });
      }
    };
    if (document.readyState === "loading") {
      document.addEventListener("DOMContentLoaded", onReady);
    } else {
      onReady();
    }
    document.addEventListener("instance-theme-change", (ev) => {
      const t = ev.detail && ev.detail.theme;
      if (t) {
        syncInlineStyles(t);
        patchHubNavLinks(t);
      }
    });
  }

  boot();

  global.InstanceTheme = {
    STANDALONE_KEY,
    HUB_LINKED_THEME_KEY,
    isHubLinked,
    get,
    apply,
    initToggleUI,
    syncToggleUI,
    syncInlineStyles,
    patchHubNavLinks,
    mergeHubQueryIntoHref,
    syncReviewEditButtons,
    initReviewEditModeSync,
  };
})(typeof window !== "undefined" ? window : globalThis);
