/* Site-wide search. One index built from SX_DATA + SX_STUDIES, a trigger injected
   into the header beside the CTA, and an overlay opened by click, "/" or cmd-K. */
const SRCH_D = window.SX_DATA;

const SX_INDEX = (function () {
  const D = SRCH_D, S = window.SX_STUDIES || {}, out = [];
  const add = (kind, title, sub, href, kw) => out.push({ kind, title, sub, href, kw: (title + " " + (sub || "") + " " + (kw || "")).toLowerCase() });
  D.solutions.forEach((s) => add("solution", s.name, s.summary, "/solutions#" + s.id, [s.group, s.practice, s.tag].join(" ")));
  D.projects.forEach((p) => {
    const study = !!S[p.slug] || p.slug === "lesco";
    const href = study ? (p.slug === "lesco" ? "/lesco" : "/case?p=" + p.slug) : "/work#" + p.slug;
    add(study ? "case study" : "project", p.title, p.client + " · " + p.year, href, [p.short, p.sector, p.practice, p.country, p.summary, p.brief].filter(Boolean).join(" "));
  });
  D.practices.forEach((p) => add("practice", p.title, p.what || p.note, p.slug === "document-intelligence" ? "/document-intelligence" : "/practices#" + p.slug, [p.group, p.note, p.body].filter(Boolean).join(" ")));
  D.industries.forEach((i) => add("sector", i.name, i.summary, "/industries#" + i.id, i.tag));
  D.stack.forEach((g) => g.items.forEach((t) => add("technology", t, g.title, "/technology#" + g.id, g.description)));
  D.faqs.forEach((q) => add("question", q.question, q.answer.slice(0, 110), "/faq", q.answer));
  [
    ["page", "Work", "Every documented programme, filterable", "/work"],
    ["page", "Solutions", "Systems you can order, with the runs behind them", "/solutions"],
    ["page", "Practices", "The ten things we do", "/practices"],
    ["page", "Technology stack", "Every technology, by layer", "/technology"],
    ["page", "Industries", "Sectors we have delivered into", "/industries"],
    ["page", "About", "Who you work with, and how we engage", "/about"],
    ["page", "Book a call", "Tell us what is not working", "/about#start"],
  ].forEach((p) => add(p[0], p[1], p[2], p[3]));
  return out;
})();

const SX_SUGGEST = ["Utility CIS & billing", "MetersBoard", "Document intelligence", "AI agents", "Work"];

function sxSearch(q) {
  const query = q.trim().toLowerCase();
  if (!query) return SX_INDEX.filter((e) => SX_SUGGEST.includes(e.title)).slice(0, 6);
  const toks = query.split(/\s+/);
  return SX_INDEX.map((e) => {
    const t = e.title.toLowerCase();
    if (!toks.every((tk) => e.kw.includes(tk))) return null;
    let s = 10;
    if (t.startsWith(query)) s = 100;
    else if (t.includes(query)) s = 70;
    else if (toks.every((tk) => t.includes(tk))) s = 50;
    else if (e.kw.includes(query)) s = 30;
    if (e.kind === "case study") s += 6;
    if (e.kind === "solution") s += 4;
    return { ...e, s };
  }).filter(Boolean).sort((a, b) => b.s - a.s).slice(0, 12);
}

function SiteSearch({ mobile }) {
  const [host, setHost] = React.useState(null);
  const [open, setOpen] = React.useState(false);
  const [q, setQ] = React.useState("");
  const [sel, setSel] = React.useState(0);
  const input = React.useRef(null);
  const results = React.useMemo(() => sxSearch(q), [q]);

  React.useEffect(() => {
    const cta = Array.from(document.querySelectorAll("header a")).find((a) => a.textContent.trim() === "Book a call");
    if (!cta || !cta.parentNode) return;
    const el = document.createElement("div");
    el.style.display = "flex";
    cta.parentNode.insertBefore(el, cta.parentNode.firstChild);
    setHost(el);
    return () => el.remove();
  }, [mobile]);

  React.useEffect(() => {
    const onKey = (e) => {
      if (!open && (e.key === "/" || ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k")) && !/^(input|textarea)$/i.test(document.activeElement?.tagName || "")) {
        e.preventDefault(); setOpen(true);
      } else if (open && e.key === "Escape") { setOpen(false); }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [open]);

  React.useEffect(() => { if (open) { setSel(0); setTimeout(() => input.current?.focus(), 20); } }, [open]);
  React.useEffect(() => { setSel(0); }, [q]);

  const onFieldKey = (e) => {
    if (e.key === "ArrowDown") { e.preventDefault(); setSel((i) => Math.min(i + 1, results.length - 1)); }
    else if (e.key === "ArrowUp") { e.preventDefault(); setSel((i) => Math.max(i - 1, 0)); }
    else if (e.key === "Enter" && results[sel]) { e.preventDefault(); location.href = results[sel].href; }
  };

  const trigger = (
    <button type="button" className={"sx-search-trigger" + (mobile ? " icon" : "")} aria-label="Search the site" onClick={() => setOpen(true)}>
      <SearchGlyph />
      {!mobile && <><span>search</span><span className="k">/</span></>}
    </button>
  );

  return (
    <>
      {host && ReactDOM.createPortal(trigger, host)}
      {open && (
        <div className="sx-search-scrim" onMouseDown={(e) => { if (e.target === e.currentTarget) setOpen(false); }}>
          <div className="sx-search-panel" aria-label="Site search">
            <div className="sx-search-field">
              <SearchGlyph />
              <input ref={input} value={q} onChange={(e) => setQ(e.target.value)} onKeyDown={onFieldKey}
                placeholder="Search solutions, projects, practices, technologies" aria-label="Search" />
              <button type="button" onClick={() => setOpen(false)} aria-label="Close search"
                style={{ appearance: "none", background: "none", border: "1px solid var(--border-default)", borderRadius: 4, color: "var(--text-quiet)", fontFamily: "var(--font-mono)", fontSize: 10, padding: "3px 7px", cursor: "pointer" }}>esc</button>
            </div>
            {results.length > 0 ? (
              <ul className="sx-search-list">
                {results.map((r, i) => (
                  <li key={r.kind + r.href + r.title} data-sel={i === sel ? "1" : "0"} onMouseEnter={() => setSel(i)}>
                    <a href={r.href}>
                      <span style={{ minWidth: 0, flex: 1 }}>
                        <span className="t">{r.title}</span>
                        {r.sub && <span className="s">{r.sub}</span>}
                      </span>
                      <span className="k">{r.kind}</span>
                    </a>
                  </li>
                ))}
              </ul>
            ) : (
              <div style={{ padding: "26px 16px", textAlign: "center" }}>
                <p className="sx-small" style={{ color: "var(--text-body)", margin: 0 }}>Nothing matched “{q}”.</p>
                <p className="sx-caption" style={{ color: "var(--text-quiet)", marginTop: 8, textTransform: "none" }}>Try billing, ocr, agent, thingsboard, or a country.</p>
              </div>
            )}
            <div className="sx-search-foot">
              <span>{q.trim() ? results.length + " result" + (results.length === 1 ? "" : "s") : "suggested"}</span>
              <span style={{ marginLeft: "auto" }}>↑↓ move · ⏎ open · esc close</span>
            </div>
          </div>
        </div>
      )}
    </>
  );
}

function SearchGlyph() {
  return (
    <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" aria-hidden style={{ flexShrink: 0 }}>
      <circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" />
    </svg>
  );
}

Object.assign(window, { SiteSearch, SX_INDEX, sxSearch, SearchGlyph });
