/**
 * app.js — Main logic for sunvpy static documentation site.
 * Handles routing, markdown rendering, navigation, TOC, and theme.
 */
(function () {
  "use strict";

  // --- State ---
  let navData = null;
  let flatPages = []; // ordered array of all slugs
  let currentPage = null;
  let isDark = false;
  let mermaidInitialized = false;

  // --- DOM refs ---
  const sidebarNav = document.getElementById("sidebarNav");
  const article = document.getElementById("article");
  const pageNav = document.getElementById("pageNav");
  const tocNav = document.getElementById("tocNav");
  const contentEl = document.getElementById("content");

  // --- Init ---
  async function init() {
    // Theme
    const saved = localStorage.getItem("sunvpy-theme");
    if (saved === "dark" || (!saved && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
      setTheme(true, false);
    }

    // Load nav
    try {
      const resp = await fetch("data/nav.json");
      navData = await resp.json();
    } catch (e) {
      article.innerHTML = '<div class="loading">无法加载导航数据。请通过 HTTP 服务器访问（如 python -m http.server）。</div>';
      return;
    }

    // Build flat page list
    flatPages = [];
    navData.sections.forEach(function (section) {
      if (section.pages) {
        section.pages.forEach(function (p) { flatPages.push(p.slug); });
      }
      if (section.groups) {
        section.groups.forEach(function (group) {
          group.pages.forEach(function (p) { flatPages.push(p.slug); });
        });
      }
    });

    // Build sidebar
    renderSidebar();

    // Route
    handleRoute();
    window.addEventListener("hashchange", handleRoute);

    // Theme toggle buttons
    document.getElementById("themeToggle").addEventListener("click", function () { setTheme(!isDark, true); });
    document.getElementById("themeToggleMobile").addEventListener("click", function () { setTheme(!isDark, true); });

    // Mobile sidebar
    document.getElementById("hamburger").addEventListener("click", toggleMobileSidebar);
    document.getElementById("sidebarBackdrop").addEventListener("click", closeMobileSidebar);
  }

  // --- Theme ---
  function setTheme(dark, save) {
    isDark = dark;
    document.documentElement.setAttribute("data-theme", dark ? "dark" : "light");

    const lightSheet = document.getElementById("hljs-light-theme");
    const darkSheet = document.getElementById("hljs-dark-theme");
    lightSheet.disabled = dark;
    darkSheet.disabled = !dark;

    if (save) localStorage.setItem("sunvpy-theme", dark ? "dark" : "light");

    // Re-render mermaid if already initialized
    if (mermaidInitialized && currentPage) {
      rerenderMermaid();
    }
  }

  // --- Sidebar ---
  function renderSidebar() {
    var html = "";
    navData.sections.forEach(function (section) {
      var isActive = currentPage && isSectionActive(section);
      html += '<div class="nav-section' + (isActive ? "" : " collapsed") + '" data-section="' + section.id + '">';
      html += '<div class="nav-section-header" onclick="toggleSection(this)">';
      html += '<svg class="chevron" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg>';
      html += escHtml(section.title);
      html += "</div>";
      html += '<div class="nav-section-body">';

      if (section.pages) {
        section.pages.forEach(function (page) {
          html += renderPageLink(page);
        });
      }
      if (section.groups) {
        section.groups.forEach(function (group) {
          html += '<div class="nav-group">';
          html += '<div class="nav-group-label">' + escHtml(group.title) + "</div>";
          group.pages.forEach(function (page) {
            html += renderPageLink(page);
          });
          html += "</div>";
        });
      }

      html += "</div></div>";
    });
    sidebarNav.innerHTML = html;
  }

  function renderPageLink(page) {
    var active = currentPage === page.slug ? " active" : "";
    var levelClass = page.level ? page.level.toLowerCase() : "";
    var badge = page.level ? ' <span class="level-badge ' + levelClass + '">' + escHtml(page.level.charAt(0)) + "</span>" : "";
    return '<a class="nav-page' + active + '" href="#' + page.slug + '">' + escHtml(page.title) + badge + "</a>";
  }

  function isSectionActive(section) {
    if (!currentPage) return false;
    if (section.pages) {
      for (var i = 0; i < section.pages.length; i++) {
        if (section.pages[i].slug === currentPage) return true;
      }
    }
    if (section.groups) {
      for (var g = 0; g < section.groups.length; g++) {
        for (var j = 0; j < section.groups[g].pages.length; j++) {
          if (section.groups[g].pages[j].slug === currentPage) return true;
        }
      }
    }
    return false;
  }

  // Expose toggleSection globally for onclick
  window.toggleSection = function (header) {
    header.parentElement.classList.toggle("collapsed");
  };

  // --- Routing ---
  function handleRoute() {
    var hash = window.location.hash.slice(1) || flatPages[0];
    if (!hash || hash === currentPage) return;
    loadPage(hash);
  }

  // --- Load & Render Page ---
  async function loadPage(slug) {
    currentPage = slug;

    // Update sidebar active state
    renderSidebar();

    // Scroll content to top
    contentEl.scrollTop = 0;

    // Show loading
    article.innerHTML = '<div class="loading">加载中...</div>';
    tocNav.innerHTML = "";
    pageNav.innerHTML = "";

    // Fetch markdown
    var md;
    try {
      var resp = await fetch("content/" + slug + ".md");
      if (!resp.ok) throw new Error(resp.status);
      md = await resp.text();
    } catch (e) {
      article.innerHTML = '<div class="loading">无法加载页面: ' + escHtml(slug) + "</div>";
      return;
    }

    // Pre-process: transform cross-doc links
    md = md.replace(/\]\((\d+-[\w-]+)\)/g, function (match, linkSlug) {
      // Only transform if it matches a known page slug
      if (flatPages.indexOf(linkSlug) !== -1) {
        return "](#" + linkSlug + ")";
      }
      return match;
    });

    // Configure marked
    var renderer = new marked.Renderer();

    // Custom paragraph handler for "Sources:" lines
    renderer.paragraph = function (obj) {
      var text = typeof obj === "object" ? obj.text : obj;
      if (text && (text.indexOf("Sources:") === 0 || text.indexOf("Sources: [") === 0)) {
        return '<div class="source-ref">' + text + "</div>";
      }
      return "<p>" + text + "</p>";
    };

    // Add IDs to headings
    var headingIndex = {};
    renderer.heading = function (text, depth) {
      // marked v15 passes heading data as object or text+depth
      var headingText = typeof text === "object" ? text.text : text;
      var headingDepth = typeof text === "object" ? text.depth : depth;
      var raw = headingText.replace(/<[^>]+>/g, "");
      var baseId = raw.toLowerCase()
        .replace(/[^\w\u4e00-\u9fff]+/g, "-")
        .replace(/^-|-$/g, "");
      if (!baseId) baseId = "heading";
      if (headingIndex[baseId] !== undefined) {
        headingIndex[baseId]++;
        baseId = baseId + "-" + headingIndex[baseId];
      } else {
        headingIndex[baseId] = 0;
      }
      return '<h' + headingDepth + ' id="' + escAttr(baseId) + '">' + headingText + "</h" + headingDepth + ">";
    };

    // Code block handler
    renderer.code = function (obj) {
      var code, lang;
      if (typeof obj === "object") {
        code = obj.text;
        lang = obj.lang || "";
      } else {
        code = obj;
        lang = "";
      }
      if (lang === "mermaid") {
        return '<div class="mermaid-wrapper"><div class="mermaid" data-mermaid-source="' + escAttr(code) + '">' + escHtml(code) + "</div></div>";
      }
      var highlighted = "";
      try {
        if (lang && hljs.getLanguage(lang)) {
          highlighted = hljs.highlight(code, { language: lang }).value;
        } else {
          highlighted = hljs.highlightAuto(code).value;
        }
      } catch (e) {
        highlighted = escHtml(code);
      }
      var langLabel = lang ? '<span class="code-lang">' + escHtml(lang) + "</span>" : "";
      return "<pre>" + langLabel + '<code class="hljs language-' + escAttr(lang) + '">' + highlighted + "</code><button class=\"copy-btn\" onclick=\"copyCode(this)\">复制</button></pre>";
    };

    marked.use({
      renderer: renderer,
      gfm: true,
      breaks: false,
    });

    // Render
    var html;
    try {
      html = marked.parse(md);
    } catch (e) {
      console.error("Markdown render error:", e);
      article.innerHTML = '<div class="loading">渲染出错: ' + escHtml(String(e)) + '</div>';
      return;
    }
    article.innerHTML = html;

    // Add page title from nav data
    var pageInfo = findPageInfo(slug);
    if (pageInfo) {
      var titleDiv = document.createElement("div");
      titleDiv.className = "page-title";
      titleDiv.innerHTML = "<h1>" + escHtml(pageInfo.title) + "</h1>";
      if (pageInfo.section) {
        titleDiv.innerHTML += '<div class="page-meta">' + escHtml(pageInfo.section);
        if (pageInfo.level) titleDiv.innerHTML += ' · <span class="level-badge ' + pageInfo.level.toLowerCase() + '">' + escHtml(pageInfo.level) + "</span>";
        titleDiv.innerHTML += "</div>";
      }
      article.insertBefore(titleDiv, article.firstChild);
    }

    // Render mermaid diagrams
    await renderMermaid();

    // Build TOC
    buildTOC();

    // Prev/Next navigation
    renderPageNav();

    // Update document title
    document.title = (pageInfo ? pageInfo.title + " — " : "") + "sunvpy 文档";
  }

  // --- Mermaid ---
  async function renderMermaid() {
    var mermaidDivs = article.querySelectorAll(".mermaid");
    if (mermaidDivs.length === 0) return;

    if (!mermaidInitialized) {
      mermaid.initialize({
        startOnLoad: false,
        theme: isDark ? "dark" : "default",
        securityLevel: "loose",
        maxTextSize: 90000,
      });
      mermaidInitialized = true;
    }

    try {
      await mermaid.run({ nodes: mermaidDivs, suppressErrors: true });
    } catch (e) {
      console.warn("Mermaid render error:", e);
    }
  }

  async function rerenderMermaid() {
    var wrappers = article.querySelectorAll(".mermaid-wrapper");
    wrappers.forEach(function (wrapper) {
      var div = wrapper.querySelector(".mermaid");
      if (!div) return;
      var source = div.getAttribute("data-mermaid-source");
      if (source) {
        div.removeAttribute("data-processed");
        div.innerHTML = escHtml(source);
      }
    });

    mermaid.initialize({
      startOnLoad: false,
      theme: isDark ? "dark" : "default",
      securityLevel: "loose",
      maxTextSize: 90000,
    });

    try {
      await mermaid.run({ nodes: article.querySelectorAll(".mermaid"), suppressErrors: true });
    } catch (e) {
      console.warn("Mermaid re-render error:", e);
    }
  }

  // --- TOC ---
  function buildTOC() {
    var headings = article.querySelectorAll("h2, h3");
    if (headings.length === 0) {
      tocNav.innerHTML = '<div style="color:var(--text-muted);font-size:0.82rem">无目录</div>';
      return;
    }

    var html = "<ul>";
    headings.forEach(function (h) {
      var cls = h.tagName === "H3" ? "toc-h3" : "";
      html += '<li><a class="' + cls + '" href="#' + escAttr(h.id) + '">' + escHtml(h.textContent) + "</a></li>";
    });
    html += "</ul>";
    tocNav.innerHTML = html;

    // Scroll spy
    setupScrollSpy(headings);
  }

  function setupScrollSpy(headings) {
    var links = tocNav.querySelectorAll("a");

    contentEl.removeEventListener("scroll", scrollSpyHandler);
    contentEl.addEventListener("scroll", scrollSpyHandler);

    function scrollSpyHandler() {
      var scrollTop = contentEl.scrollTop;
      var activeIdx = 0;
      for (var i = headings.length - 1; i >= 0; i--) {
        if (headings[i].offsetTop - 100 <= scrollTop) {
          activeIdx = i;
          break;
        }
      }
      links.forEach(function (link, idx) {
        link.classList.toggle("active", idx === activeIdx);
      });
    }
  }

  // --- Prev/Next ---
  function renderPageNav() {
    var idx = flatPages.indexOf(currentPage);
    if (idx === -1) { pageNav.innerHTML = ""; return; }

    var html = "";
    if (idx > 0) {
      var prevInfo = findPageInfo(flatPages[idx - 1]);
      html += '<a class="page-nav-btn prev" href="#' + flatPages[idx - 1] + '">';
      html += '<span class="label">上一节</span>';
      html += '<span class="title">' + escHtml(prevInfo ? prevInfo.title : flatPages[idx - 1]) + "</span>";
      html += "</a>";
    } else {
      html += "<div></div>";
    }
    if (idx < flatPages.length - 1) {
      var nextInfo = findPageInfo(flatPages[idx + 1]);
      html += '<a class="page-nav-btn next" href="#' + flatPages[idx + 1] + '">';
      html += '<span class="label">下一节</span>';
      html += '<span class="title">' + escHtml(nextInfo ? nextInfo.title : flatPages[idx + 1]) + "</span>";
      html += "</a>";
    }
    pageNav.innerHTML = html;
  }

  // --- Helpers ---
  function findPageInfo(slug) {
    for (var s = 0; s < navData.sections.length; s++) {
      var section = navData.sections[s];
      if (section.pages) {
        for (var i = 0; i < section.pages.length; i++) {
          if (section.pages[i].slug === slug) {
            return Object.assign({}, section.pages[i], { section: section.title });
          }
        }
      }
      if (section.groups) {
        for (var g = 0; g < section.groups.length; g++) {
          for (var j = 0; j < section.groups[g].pages.length; j++) {
            if (section.groups[g].pages[j].slug === slug) {
              return Object.assign({}, section.groups[g].pages[j], { section: section.title });
            }
          }
        }
      }
    }
    return null;
  }

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

  function escAttr(s) {
    return escHtml(s);
  }

  // Copy code to clipboard
  window.copyCode = function (btn) {
    var code = btn.parentElement.querySelector("code");
    var text = code.textContent;
    navigator.clipboard.writeText(text).then(function () {
      btn.textContent = "已复制";
      setTimeout(function () { btn.textContent = "复制"; }, 1500);
    });
  };

  // --- Mobile sidebar ---
  function toggleMobileSidebar() {
    document.getElementById("sidebar").classList.toggle("open");
    document.getElementById("sidebarBackdrop").classList.toggle("open");
  }
  function closeMobileSidebar() {
    document.getElementById("sidebar").classList.remove("open");
    document.getElementById("sidebarBackdrop").classList.remove("open");
  }

  // Close mobile sidebar on nav
  document.addEventListener("click", function (e) {
    if (e.target.classList.contains("nav-page")) {
      closeMobileSidebar();
    }
  });

  // --- Start ---
  init();
})();
