// iConference — KI-Begriffserklärung / AI Glossary. Uses window.GLOSSARY.
const { useState, useEffect, useMemo, useRef } = React;

function norm(s) { return s.toLowerCase().replace(/[\u2011-]/g, "-"); }

function icInitialLang(def) {
  try {
    const u = new URLSearchParams(location.search).get("lang");
    if (u === "de" || u === "en") return u;
  } catch (e) {}
  return def || "de";
}

function Bar({ lang, setLang, t }) {
  return (
    <div className="gbar">
      <img src="../assets/iconference-logo-white.png" alt="iConference" />
      <div className="divider"></div>
      <div className="ttl">{lang === "de" ? <React.Fragment>KI-Begriffe<span> · Glossar</span></React.Fragment> : <React.Fragment>AI<span> Glossary</span></React.Fragment>}</div>
      <div className="right">
        <a className="back" href={"../index.html?lang=" + lang}><i data-lucide="arrow-left"></i>{t.back}</a>
        <div className="lang">
          <button className={lang === "de" ? "on" : ""} onClick={() => setLang("de")}>DE</button>
          <button className={lang === "en" ? "on" : ""} onClick={() => setLang("en")}>EN</button>
        </div>
      </div>
    </div>
  );
}

function Toc({ groups, active, t, total }) {
  return (
    <nav className="gtoc">
      <div className="gtoc-title">{t.tocTitle}</div>
      <ul>
        {groups.map((g) => (
          <li key={g.id}>
            <a className={active === g.id ? "on" : ""} href={"#g-" + g.id}>
              <i data-lucide={g.icon}></i>
              <span>{g.title}</span>
              <em>{g.terms.length}</em>
            </a>
          </li>
        ))}
      </ul>
      <div className="gtoc-foot"><b>{total}</b> {t.countLabel}</div>
    </nav>
  );
}

function Term({ tm, q }) {
  return (
    <div className={"gterm" + (tm.star ? " star" : "")}>
      <div className="gterm-name">
        {tm.term}
        {tm.sub && <span className="gterm-sub">{tm.sub}</span>}
        {tm.star && <span className="gterm-core"><i data-lucide="star"></i></span>}
      </div>
      <p className="gterm-def">{tm.def}</p>
    </div>
  );
}

function Group({ g }) {
  return (
    <section id={"g-" + g.id} className="ggroup">
      <div className="ggroup-head">
        <div className="ggroup-ico"><i data-lucide={g.icon}></i></div>
        <h2>{g.title}</h2>
        <span className="ggroup-count">{g.terms.length}</span>
      </div>
      {g.intro && <p className="ggroup-intro">{g.intro}</p>}
      <div className="gterms">
        {g.terms.map((tm) => <Term key={tm.term} tm={tm} />)}
      </div>
    </section>
  );
}

function App() {
  const [lang, setLang] = useState(() => icInitialLang("de"));
  const [q, setQ] = useState("");
  const [active, setActive] = useState("");
  const t = window.GLOSSARY[lang];

  const filtered = useMemo(() => {
    const needle = norm(q.trim());
    if (!needle) return t.groups;
    return t.groups
      .map((g) => ({ ...g, terms: g.terms.filter((tm) => norm(tm.term + " " + tm.def + " " + (tm.sub || "")).includes(needle)) }))
      .filter((g) => g.terms.length > 0);
  }, [q, t]);

  const total = useMemo(() => t.groups.reduce((n, g) => n + g.terms.length, 0), [t]);

  useEffect(() => { if (window.lucide) window.lucide.createIcons(); });
  useEffect(() => { document.documentElement.lang = lang; }, [lang]);

  // active section highlight on scroll
  useEffect(() => {
    if (q.trim()) return;
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) setActive(e.target.id.replace("g-", "")); });
    }, { rootMargin: "-30% 0px -60% 0px" });
    document.querySelectorAll(".ggroup").forEach((el) => obs.observe(el));
    return () => obs.disconnect();
  }, [q, lang, filtered.length]);

  return (
    <div className="gpage">
      <Bar lang={lang} setLang={setLang} t={t} />

      <header className="ghero">
        <div className="ghero-in">
          <div className="geyebrow">{t.eyebrow}</div>
          <h1>{t.h1a}<em>{t.h1em}</em>{t.h1b}</h1>
          <p className="glead">{t.lead}</p>
          <div className="gsearch">
            <i data-lucide="search"></i>
            <input type="text" value={q} onChange={(e) => setQ(e.target.value)} placeholder={t.searchPh} />
            {q && <button className="gsearch-x" onClick={() => setQ("")}><i data-lucide="x"></i></button>}
          </div>
        </div>
      </header>

      <div className="gbody">
        <Toc groups={t.groups} active={active} t={t} total={total} />
        <main className="gmain">
          {filtered.length === 0 ? (
            <div className="gempty">
              <div className="gempty-ico"><i data-lucide="search-x"></i></div>
              <h3>{t.noResultsH}</h3>
              <p>{t.noResults}</p>
              <button className="gbtn" onClick={() => setQ("")}>{t.clear}</button>
            </div>
          ) : (
            filtered.map((g) => <Group key={g.id} g={g} />)
          )}
          <div className="gfoot"><i data-lucide="git-commit-horizontal"></i>{t.foot}</div>
        </main>
      </div>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
