/**
 * cookbook.js  — fixed for the new tab-based layout
 *
 * Changes vs original:
 *  1. initCookbook() is exported so script.js can call it after tab content loads
 *  2. cellValue() scans ALL tr elements (not just tbody) — org-mode hides thead via CSS
 *     but the rows are still in the DOM under thead
 *  3. watchForPanes() now watches #content-area (the new tab container) instead of .stack-track
 *  4. Toolbar falls back to inserting before the first .outline-3 if .outline-2 is absent
 */

(function () {
  "use strict";

  // ── Core init — scoped to a content root ──────────────────────────────────

  function initCookbook(root) {
    if (root.dataset.cbInit) return;
    root.dataset.cbInit = "1";

    const recipes = Array.from(root.querySelectorAll(".outline-3"))
      .filter(el => el.querySelector("table.recipe-meta"));

    if (!recipes.length) return;

    // ── Helpers ─────────────────────────────────────────────────────────────

    function cellValue(table, label) {
      // Scan ALL tr elements — org-mode thead is hidden via CSS but rows are
      // still in the DOM there; relying only on tbody misses them.
      for (const row of table.querySelectorAll("tr")) {
        const cells = row.querySelectorAll("td");
        if (cells.length >= 2 && cells[0].textContent.trim() === label)
          return cells[1].textContent.trim();
      }
      return "";
    }

    function isCooked(table) {
      const v = cellValue(table, "Cooked");
      return Boolean(v && v !== "not yet made");
    }

    // ── Collect keywords ─────────────────────────────────────────────────────

    const allKeywords = new Set();
    recipes.forEach(block => {
      const kw = cellValue(block.querySelector("table.recipe-meta"), "Keywords");
      if (kw) kw.split(",").forEach(k => allKeywords.add(k.trim()));
    });

    // ── Build toolbar ────────────────────────────────────────────────────────

    const toolbar = document.createElement("div");
    toolbar.className = "cb-toolbar";
    toolbar.setAttribute("role", "search");
    toolbar.innerHTML = `
      <div class="cb-toolbar-inner">
        <input class="cb-search" type="search" placeholder="filter recipes…"
               aria-label="Filter recipes" autocomplete="off" spellcheck="false" />
        <div class="cb-filters" role="group" aria-label="Cook status">
          <button class="cb-filter-btn active" data-filter="all">all</button>
          <button class="cb-filter-btn" data-filter="cooked">✓ made</button>
          <button class="cb-filter-btn" data-filter="uncooked">✗ not yet</button>
        </div>
        <div class="cb-tags" role="group" aria-label="Filter by keyword"></div>
        <span class="cb-count" aria-live="polite"></span>
      </div>`;

    // Insert before first .outline-2; fall back to first .outline-3
    const insertTarget =
      root.querySelector(".outline-2") ||
      root.querySelector(".outline-3");

    if (insertTarget) {
      insertTarget.parentNode.insertBefore(toolbar, insertTarget);
    } else {
      // Last resort: prepend into root
      root.prepend(toolbar);
    }

    const searchInput = toolbar.querySelector(".cb-search");
    const filterBtns  = toolbar.querySelectorAll(".cb-filter-btn");
    const tagsWrap    = toolbar.querySelector(".cb-tags");
    const countEl     = toolbar.querySelector(".cb-count");

    // Keyword pills
    Array.from(allKeywords).sort().forEach(kw => {
      const btn = document.createElement("button");
      btn.className = "cb-tag";
      btn.textContent = kw;
      btn.dataset.tag = kw;
      btn.setAttribute("aria-pressed", "false");
      tagsWrap.appendChild(btn);
    });

    // ── State ────────────────────────────────────────────────────────────────

    let activeFilter = "all";
    let activeTags   = new Set();
    let query        = "";

    // ── Filter engine ────────────────────────────────────────────────────────

    function applyFilters() {
      let shown = 0;

      recipes.forEach(block => {
        const table  = block.querySelector("table.recipe-meta");
        const cooked = isCooked(table);
        const title  = (block.querySelector("h3")?.textContent ?? "").toLowerCase();
        const kwRaw  = cellValue(table, "Keywords");
        const kwLow  = kwLow  = kwRaw.toLowerCase();

        if (activeFilter === "cooked"   && !cooked) { hide(block); return; }
        if (activeFilter === "uncooked" &&  cooked) { hide(block); return; }

        if (activeTags.size) {
          const recipeKws = kwRaw.split(",").map(k => k.trim());
          if ([...activeTags].some(t => !recipeKws.includes(t))) { hide(block); return; }
        }

        if (query && !title.includes(query) && !kwLow.includes(query)) {
          hide(block); return;
        }

        show(block);
        shown++;
      });

      root.querySelectorAll(".outline-2").forEach(section => {
        const hasVisible = Array.from(section.querySelectorAll(".outline-3"))
          .some(b => b.style.display !== "none");
        section.style.display = hasVisible ? "" : "none";
      });

      countEl.textContent =
        shown === recipes.length
          ? `${shown} recipe${shown !== 1 ? "s" : ""}`
          : `${shown} / ${recipes.length}`;
    }

    function hide(el) { el.style.display = "none"; }
    function show(el) { el.style.display = ""; }

    // ── Events ───────────────────────────────────────────────────────────────

    searchInput.addEventListener("input", () => {
      query = searchInput.value.trim().toLowerCase();
      applyFilters();
    });

    filterBtns.forEach(btn => {
      btn.addEventListener("click", () => {
        filterBtns.forEach(b => b.classList.remove("active"));
        btn.classList.add("active");
        activeFilter = btn.dataset.filter;
        applyFilters();
      });
    });

    tagsWrap.addEventListener("click", e => {
      const btn = e.target.closest(".cb-tag");
      if (!btn) return;
      const tag = btn.dataset.tag;
      if (activeTags.has(tag)) {
        activeTags.delete(tag);
        btn.classList.remove("active");
        btn.setAttribute("aria-pressed", "false");
      } else {
        activeTags.add(tag);
        btn.classList.add("active");
        btn.setAttribute("aria-pressed", "true");
      }
      applyFilters();
    });

    // ── Badges ───────────────────────────────────────────────────────────────

    recipes.forEach(block => {
      const table  = block.querySelector("table.recipe-meta");
      const h3     = block.querySelector("h3");
      const cooked = isCooked(table);

      block.classList.add(cooked ? "cb-cooked" : "cb-uncooked");

      const badge = document.createElement("span");
      badge.className = "cb-badge " + (cooked ? "cb-badge-cooked" : "cb-badge-uncooked");
      badge.textContent = cooked ? "made" : "not yet";

      const tagSpan = h3.querySelector(".tag");
      if (tagSpan) h3.insertBefore(badge, tagSpan);
      else         h3.appendChild(badge);
    });

    applyFilters();
  }

  // ── Entry points ──────────────────────────────────────────────────────────

  function tryInitOnContent() {
    const content = document.getElementById("content");
    if (content && content.querySelector("table.recipe-meta")) {
      initCookbook(content);
    }
  }

  function watchForPanes() {
    // Watch #content-area — this is where script.js appends new .tab-content divs.
    // Falls back to watching document.body if #content-area isn't ready yet.
    const getTrack = () =>
      document.getElementById("content-area") || document.body;

    const observe = (track) => {
      const observer = new MutationObserver(mutations => {
        mutations.forEach(m => {
          m.addedNodes.forEach(node => {
            if (node.nodeType !== 1) return;
            // script.js appends .tab-content divs containing a div#content
            const content =
              (node.id === "content" ? node : null) ||
              node.querySelector("#content, .content");
            if (content && content.querySelector("table.recipe-meta")) {
              initCookbook(content);
            }
          });
        });
      });
      observer.observe(track, { childList: true, subtree: true });
    };

    const track = document.getElementById("content-area");
    if (track) {
      observe(track);
    } else {
      // content-area is built by script.js after DOMContentLoaded;
      // wait for it to appear then start observing.
      const bodyObserver = new MutationObserver(() => {
        const area = document.getElementById("content-area");
        if (area) {
          bodyObserver.disconnect();
          observe(area);
        }
      });
      bodyObserver.observe(document.body, { childList: true, subtree: false });
    }
  }

  // Expose for direct calls from script.js if needed:
  //   window.initCookbook(contentEl);
  window.initCookbook = initCookbook;

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", () => {
      tryInitOnContent();
      watchForPanes();
    });
  } else {
    tryInitOnContent();
    watchForPanes();
  }

})();
