/* =========================================================
   STATE
   ========================================================= */

let index = [];
let activeIndex = -1;

const box = document.getElementById("search-box");
const results = document.getElementById("search-results");

/* =========================================================
   LOAD SEARCH INDEX
   ========================================================= */

fetch("/search-index.json")
  .then(r => r.json())
  .then(data => {
    index = Array.isArray(data) ? data : [];
  })
  .catch(err => {
    console.error("Failed to load search index:", err);
  });

/* =========================================================
   RENDER RESULTS
   ========================================================= */

function renderResults(items) {
  clearResults();

  items.forEach((entry, i) => {
    const row = document.createElement("div");
    row.dataset.index = i;

    const link = document.createElement("a");
    link.href = entry.url;
    link.textContent = entry.title;

    link.addEventListener("click", ev => {
      ev.preventDefault();
      ev.stopPropagation();
      clearSearch();
      pushPane(entry.url);
    });

    row.appendChild(link);

    row.addEventListener("mouseenter", () => setActive(i));
    row.addEventListener("mouseleave", clearActive);

    results.appendChild(row);
  });
}

/* =========================================================
   ACTIVE ITEM HANDLING
   ========================================================= */

function setActive(i) {
  const items = [...results.children];

  items.forEach(el => el.classList.remove("active"));

  if (items[i]) {
    items[i].classList.add("active");
    activeIndex = i;
  }
}

function clearActive() {
  [...results.children].forEach(el => el.classList.remove("active"));
  activeIndex = -1;
}

/* =========================================================
   INPUT HANDLER
   ========================================================= */

box.addEventListener("input", () => {
  const query = box.value.trim().toLowerCase();

  clearResults();
  if (query.length < 2) return;

  const matches = index
    .map(entry => ({
      ...entry,
      score: fuzzyScore(query, entry.title)
    }))
    .filter(entry => entry.score > 0)
    .sort((a, b) => b.score - a.score)
    .slice(0, 20); // optional cap

  renderResults(matches);
});

/* =========================================================
   KEYBOARD NAVIGATION
   ========================================================= */

box.addEventListener("keydown", e => {
  const items = [...results.children];
  if (!items.length) return;

  switch (e.key) {
    case "ArrowDown":
      e.preventDefault();
      setActive((activeIndex + 1) % items.length);
      break;

    case "ArrowUp":
      e.preventDefault();
      setActive((activeIndex - 1 + items.length) % items.length);
      break;

    case "Enter":
      if (activeIndex < 0) return;

      e.preventDefault();
      e.stopPropagation();

      const link = items[activeIndex].querySelector("a");
      if (link) {
        clearSearch();
        pushPane(link.getAttribute("href"));
      }
      break;

    case "Escape":
      clearSearch();
      break;
  }
});

/* =========================================================
   CLICK OUTSIDE TO CLOSE
   ========================================================= */

document.addEventListener("click", e => {
  if (!e.target.closest(".banner-search")) {
    clearSearch();
  }
});

/* =========================================================
   HELPERS
   ========================================================= */

function clearResults() {
  results.innerHTML = "";
}

function clearSearch() {
  clearResults();
  activeIndex = -1;
}
function fuzzyScore(query, text) {
  query = query.toLowerCase();
  text = text.toLowerCase();

  let score = 0;
  let qi = 0;
  let consecutive = 0;

  for (let ti = 0; ti < text.length && qi < query.length; ti++) {
    if (text[ti] === query[qi]) {
      qi++;
      consecutive++;
      score += 5 + consecutive * 2; // reward runs
    } else {
      consecutive = 0;
    }
  }

  if (qi !== query.length) return 0;

  score += Math.max(0, 20 - text.length);

  return score;
}
