/**
 * search.js — Full-text search for sunvpy docs using Fuse.js
 */
(function () {
  "use strict";

  var fuse = null;
  var searchIndex = null;
  var searchOverlay = document.getElementById("searchOverlay");
  var searchInput = document.getElementById("searchInput");
  var searchResults = document.getElementById("searchResults");
  var debounceTimer = null;

  // Open search
  function openSearch() {
    searchOverlay.classList.add("active");
    searchInput.value = "";
    searchResults.innerHTML = '<div class="search-hint">输入关键词开始搜索</div>';
    searchInput.focus();
    loadIndex();
  }

  // Close search
  function closeSearch() {
    searchOverlay.classList.remove("active");
    searchInput.blur();
  }

  // Lazy-load search index
  async function loadIndex() {
    if (searchIndex) return;
    try {
      var resp = await fetch("data/search-index.json");
      searchIndex = await resp.json();
      fuse = new Fuse(searchIndex, {
        keys: [
          { name: "title", weight: 0.4 },
          { name: "headings", weight: 0.3 },
          { name: "content", weight: 0.3 },
        ],
        threshold: 0.3,
        ignoreLocation: true,
        includeMatches: true,
        minMatchCharLength: 2,
      });
    } catch (e) {
      searchResults.innerHTML = '<div class="search-hint">无法加载搜索索引</div>';
    }
  }

  // Perform search
  function doSearch(query) {
    if (!fuse || !query.trim()) {
      searchResults.innerHTML = '<div class="search-hint">输入关键词开始搜索</div>';
      return;
    }

    var results = fuse.search(query, { limit: 20 });

    if (results.length === 0) {
      searchResults.innerHTML = '<div class="search-hint">未找到匹配结果</div>';
      return;
    }

    var html = "";
    results.forEach(function (result) {
      var item = result.item;
      var context = getContext(result.matches, item);
      html += '<a class="search-result-item" href="#' + escAttr(item.slug) + '" onclick="closeSearch()">'
        + '<div class="result-title">' + escHtml(item.title) + "</div>"
        + '<div class="result-section">' + escHtml(item.section) + "</div>"
        + '<div class="result-context">' + context + "</div>"
        + "</a>";
    });
    searchResults.innerHTML = html;
  }

  // Get matching context snippet
  function getContext(matches, item) {
    if (!matches || matches.length === 0) return "";

    // Prefer title/content match context
    for (var i = 0; i < matches.length; i++) {
      var m = matches[i];
      if (m.key === "content" && m.indices && m.indices.length > 0) {
        var idx = m.indices[0];
        var start = Math.max(0, idx[0] - 30);
        var end = Math.min(item.content.length, idx[1] + 30);
        var snippet = (start > 0 ? "..." : "") + item.content.substring(start, end) + (end < item.content.length ? "..." : "");
        return highlightMatch(snippet, m.value.substring(idx[0], idx[1] + 1));
      }
      if (m.key === "headings" && m.indices && m.indices.length > 0) {
        var arr = item.headings;
        for (var h = 0; h < arr.length; h++) {
          if (arr[h].toLowerCase().indexOf(m.value.toLowerCase()) !== -1) {
            return highlightMatch(arr[h], m.value);
          }
        }
      }
    }
    return "";
  }

  function highlightMatch(text, match) {
    if (!match) return escHtml(text);
    var escaped = escHtml(text);
    var escapedMatch = escHtml(match);
    return escaped.replace(new RegExp(escapeRegex(escapedMatch), "gi"), "<mark>$&</mark>");
  }

  function escapeRegex(s) {
    return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
  }

  // Close search global
  window.closeSearch = closeSearch;

  // Event listeners
  searchInput.addEventListener("input", function () {
    clearTimeout(debounceTimer);
    debounceTimer = setTimeout(function () {
      doSearch(searchInput.value);
    }, 200);
  });

  document.getElementById("searchClose").addEventListener("click", closeSearch);
  searchOverlay.addEventListener("click", function (e) {
    if (e.target === searchOverlay) closeSearch();
  });

  // Keyboard shortcut: Ctrl+K / Cmd+K
  document.addEventListener("keydown", function (e) {
    if ((e.ctrlKey || e.metaKey) && e.key === "k") {
      e.preventDefault();
      openSearch();
    }
    if (e.key === "Escape" && searchOverlay.classList.contains("active")) {
      closeSearch();
    }
  });

  // Sidebar search button
  document.getElementById("sidebarSearchBtn").addEventListener("click", openSearch);
  var mobileSearchBtn = document.getElementById("searchBtnMobile");
  if (mobileSearchBtn) mobileSearchBtn.addEventListener("click", openSearch);

  // Navigate on result click
  searchResults.addEventListener("click", function (e) {
    var item = e.target.closest(".search-result-item");
    if (item) {
      closeSearch();
    }
  });

  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); }
})();
