// public/faq.jsx — window.FaqList + helpers. Renders the FAQ content pool
// (window.FAQ, compiled from content/faq.json by scripts/build-data.ts) as
// an accordion. Used in two places:
//   - a project panel's FAQ tab   (entries whose `projects` include the key)
//   - the dedicated FAQ surface   (all topic-tagged entries, grouped by tag)
//
// Each entry's answer (e.a[lang]) is an array of BLOCKS:
//   "string"        → paragraph
//   { h: "string" } → sub-heading
//   { ul: [..] }    → bullet list
// (mirrors the "FAQ entry format" section of docs/editing-map.md).
(function () {
  // Visible when it's for everyone, or it's US-gated and the visitor's
  // residence is the US — the same gate the Tax tab uses (profile.residency).
  // (No entry is currently US-gated: per Chris, Jul 2026, the "US Investors"
  // section is visible to everyone. The mechanism stays for future entries.)
  function faqVisible(entry, profile) {
    if (!entry) return false;
    if (entry.audience === "us") return !!(profile && profile.residency === "us");
    return true;
  }
  window.faqVisible = faqVisible;

  // Entries for a surface, honoring the visitor profile.
  //   { project: "GD207" } → entries for that project's panel FAQ tab
  //   (no project)         → the general FAQ surface (any topic-tagged entry)
  function faqEntries(opts) {
    opts = opts || {};
    var all = window.FAQ || [];
    return all.filter(function (e) {
      if (opts.project != null) {
        if (!e.projects || e.projects.indexOf(opts.project) === -1) return false;
      } else if (!e.tags || !e.tags.length) {
        return false;
      }
      return faqVisible(e, opts.profile);
    });
  }
  window.faqEntries = faqEntries;

  // Topic-tag keys present in a list, in FAQ_CATEGORIES (menu) order.
  function faqCategories(entries) {
    var keys = Object.keys(window.FAQ_CATEGORIES || {});
    return keys.filter(function (k) {
      return (entries || []).some(function (e) { return e.tags && e.tags.indexOf(k) !== -1; });
    });
  }
  window.faqCategories = faqCategories;

  function Blocks(props) {
    var blocks = props.blocks || [];
    return blocks.map(function (b, i) {
      if (typeof b === "string") return b ? <p key={i} className="r-faq-p">{b}</p> : null;
      if (b && b.h) return <p key={i} className="r-faq-subh">{b.h}</p>;
      if (b && b.ul) {
        return (
          <ul key={i} className="r-faq-ul">
            {b.ul.map(function (li, j) { return <li key={j}>{li}</li>; })}
          </ul>
        );
      }
      return null;
    });
  }
  window.FaqBlocks = Blocks;

  // entries: pre-filtered list. lang: "en"|"es". accordionName groups the
  // <details> so only one stays open at a time (native exclusive accordion).
  function FaqList(props) {
    var entries = props.entries || [];
    var lang = props.lang || "en";
    var name = props.accordionName || "r-faq";
    if (!entries.length) return null;
    return (
      <div className={"r-faq" + (props.dark ? " r-faq--dark" : "")}>
        {entries.map(function (e) {
          var blocks = (e.a && (e.a[lang] || e.a.en)) || [];
          if (e.intro) {
            return <div key={e.id} className="r-faq-intro"><Blocks blocks={blocks} /></div>;
          }
          var q = window.pickLang(e.q, lang);
          return (
            <details key={e.id} className="r-faq-item" name={name}>
              <summary className="r-faq-q">
                <span className="r-faq-mark" aria-hidden="true">›</span>
                <span>{q}</span>
              </summary>
              <div className="r-faq-a"><Blocks blocks={blocks} /></div>
            </details>
          );
        })}
      </div>
    );
  }
  window.FaqList = FaqList;

  // ── Dedicated FAQ surface (?view=faq) ────────────────────────────────
  // Full-screen overlay over the app:
  // owns open state, syncs URL state, exposes window.openFaq(). Renders all
  // topic-tagged entries grouped by tag; a multi-tagged question appears
  // under every one of its sections. The sticky tab row is a jump-nav —
  // clicking a tab scrolls to that section (nothing is filtered out) and the
  // active tab follows the scroll position.
  function FaqSurface(props) {
    var React2 = React, useState = React2.useState, useEffect = React2.useEffect, useRef = React2.useRef;
    var lang = props.lang || "en";
    var es = lang === "es";
    var fromUrl = (window.urlState && window.urlState.getFaq) ? window.urlState.getFaq() : null;
    var open = useState(!!(fromUrl && fromUrl.open));
    var isOpen = open[0], setOpen = open[1];
    var catState = useState(null); // highlighted tab (scrollspy)
    var cat = catState[0], setCat = catState[1];
    var surfaceRef = useRef(null);
    var barRef = useRef(null);
    // While a tab-click smooth-scroll is in flight the click owns the
    // highlight; the scrollspy defers so it can't flicker mid-animation
    // (same pattern as detail.jsx's jumpLockRef).
    var jumpLockRef = useRef(null);

    function jumpTo(c) {
      setCat(c);
      var root = surfaceRef.current;
      var el = root && root.querySelector('[data-faq-cat="' + c + '"]');
      if (!el) return;
      if (jumpLockRef.current) clearTimeout(jumpLockRef.current);
      jumpLockRef.current = setTimeout(function () { jumpLockRef.current = null; }, 900);
      var reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
      // Offset by the live sticky-header height (head + tabs; the tab row
      // wraps to two lines on narrow widths, so a fixed offset would land
      // underneath it).
      var barH = barRef.current ? barRef.current.getBoundingClientRect().height : 0;
      var top = root.scrollTop + el.getBoundingClientRect().top - root.getBoundingClientRect().top - barH - 10;
      root.scrollTo({ top: Math.max(0, top), behavior: reduce ? "auto" : "smooth" });
    }

    useEffect(function () {
      window.openFaq = function () { setOpen(true); };
      function onOpen() {
        setOpen(true);
        if (window.posthog) window.posthog.capture("faq_opened");
      }
      window.addEventListener("reurbano:open-faq", onOpen);
      return function () {
        window.removeEventListener("reurbano:open-faq", onOpen);
        if (window.openFaq) delete window.openFaq;
      };
    }, []);
    useEffect(function () {
      if (window.urlState && window.urlState.setFaq) window.urlState.setFaq(isOpen);
    }, [isOpen]);
    useEffect(function () {
      if (!isOpen) return;
      function onKey(e) { if (e.key === "Escape") setOpen(false); }
      window.addEventListener("keydown", onKey);
      return function () { window.removeEventListener("keydown", onKey); };
    }, [isOpen]);

    // Scrollspy: highlight the last section whose top has passed the sticky
    // header. Attached to the surface (the scroll container).
    useEffect(function () {
      if (!isOpen) return;
      var root = surfaceRef.current;
      if (!root) return;
      function onScroll() {
        if (jumpLockRef.current) return;
        var barBottom = barRef.current ? barRef.current.getBoundingClientRect().bottom : 0;
        var sections = root.querySelectorAll("[data-faq-cat]");
        var current = sections.length ? sections[0].getAttribute("data-faq-cat") : null;
        for (var i = 0; i < sections.length; i++) {
          if (sections[i].getBoundingClientRect().top <= barBottom + 24) {
            current = sections[i].getAttribute("data-faq-cat");
          }
        }
        setCat(current);
      }
      onScroll();
      root.addEventListener("scroll", onScroll, { passive: true });
      return function () { root.removeEventListener("scroll", onScroll); };
    }, [isOpen]);

    if (!isOpen) return null;
    var title = es ? "Preguntas frecuentes" : "Frequently asked questions";
    var entries = faqEntries({ profile: props.profile });
    var cats = faqCategories(entries);
    var CATS = window.FAQ_CATEGORIES || {};
    return (
      <div ref={surfaceRef} className={"r-faq-surface" + (props.dark ? " dark" : "")} role="dialog" aria-modal="true" aria-label={title}>
        <div className="r-faq-surface-inner">
          {/* Head + tabs stick together, so the close button and the section
              nav both stay reachable while the body scrolls under them. */}
          <div ref={barRef} className="r-faq-sticky">
            <div className="r-faq-surface-head">
              <h2>{title}</h2>
              <button className="r-faq-close" onClick={function () { setOpen(false); }} aria-label={es ? "Cerrar" : "Close"}>×</button>
            </div>
            <div className="r-faq-filterbar" role="tablist" aria-label={es ? "Secciones" : "Sections"}>
              {cats.map(function (c) {
                return (
                  <button key={c} className={"r-faq-f" + (cat === c ? " on" : "")} onClick={function () { jumpTo(c); }}>
                    {window.pickLang(CATS[c] || {}, lang)}
                  </button>
                );
              })}
            </div>
          </div>
          <div className="r-faq-surface-body">
            {cats.map(function (c) {
              var items = entries.filter(function (e) { return e.tags && e.tags.indexOf(c) !== -1; });
              if (!items.length) return null;
              return (
                <div key={c} className="r-faq-cat" data-faq-cat={c}>
                  <p className="r-faq-cat-h">{window.pickLang(CATS[c] || {}, lang)}</p>
                  <window.FaqList entries={items} lang={lang} dark={props.dark} accordionName="r-faq-general" />
                </div>
              );
            })}
          </div>
        </div>
      </div>
    );
  }
  window.FaqSurface = FaqSurface;
})();
