/* search.jsx — vyhľadávanie Ctrl K podľa artboardu "3 · Globálne vyhľadávanie".
   v1 (PLAN.md 1.3): hľadá v aplikáciách a rýchlych akciách z config.jsx, všetko lokálne.
   Tikety a zariadenia pribudnú s backendom (PLAN.md 7.1).
   Vystavuje window.SearchDialog, window.useSkratkaHladania.

   Prístupnosť: vzor combobox + listbox — fokus ostáva v poli, šípky menia aria-activedescendant.
*/
(function () {
  "use strict";

  const { useState, useEffect, useRef, useMemo } = React;

  // "Notebook" nájde aj "notebooky", "zariadenia" aj "zariadení" — bez diakritiky a veľkých písmen.
  function normalizuj(s) {
    return String(s || "").normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase();
  }

  // Skóre 0 = nezhoduje sa. Každé slovo dopytu sa musí niekde nájsť; vyššie skóre, keď sa
  // nájde v názve (a ešte vyššie na jeho začiatku) než v popise či kľúčových slovách.
  function skore(polozka, slova) {
    const nazov = normalizuj(polozka.nazov + " " + (polozka.kratky || ""));
    const ostatne = normalizuj((polozka.klucoveSlova || "") + " " + (polozka.popis || ""));
    let spolu = 0;
    for (const slovo of slova) {
      if (nazov.startsWith(slovo) || nazov.includes(" " + slovo)) spolu += 4;
      else if (nazov.includes(slovo)) spolu += 3;
      else if (ostatne.split(/\s+/).some((w) => w.startsWith(slovo))) spolu += 2;
      else if (ostatne.includes(slovo)) spolu += 1;
      else return 0;
    }
    return spolu;
  }

  function hladaj(dopyt, apps, akcie) {
    const slova = normalizuj(dopyt).split(/\s+/).filter(Boolean);
    const zoradit = (zoznam) => {
      if (slova.length === 0) return zoznam;
      return zoznam
        .map((p) => ({ p, s: skore(p, slova) }))
        .filter((x) => x.s > 0)
        .sort((a, b) => b.s - a.s)
        .map((x) => x.p);
    };
    return [
      { id: "apps", nazov: "Aplikácie", polozky: zoradit(apps).map((a) => ({ ...a, druh: "app" })) },
      { id: "akcie", nazov: "Akcie", polozky: zoradit(akcie).map((a) => ({ ...a, druh: "akcia" })) },
    ].filter((sk) => sk.polozky.length > 0);
  }

  function jeAktivna(p) {
    if (p.druh === "app") return Boolean(p.url) && p.stav !== "pripravujeme";
    return p.typ === "odhlasit" || Boolean(p.url);
  }

  function SearchDialog({ apps, akcie, onZavriet, onOdhlasit }) {
    const [dopyt, setDopyt] = useState("");
    const [aktivny, setAktivny] = useState(0);
    const pole = useRef(null);
    const zoznam = useRef(null);

    const skupiny = useMemo(() => hladaj(dopyt, apps, akcie), [dopyt, apps, akcie]);
    // Plochý zoznam len vybrateľných položiek — šípky preskakujú tie, čo sa nedajú otvoriť.
    const vyberatelne = useMemo(() => skupiny.flatMap((sk) => sk.polozky).filter(jeAktivna), [skupiny]);

    useEffect(() => { setAktivny(0); }, [dopyt]);

    useEffect(() => {
      const predtym = document.activeElement; // ešte pred presunom fokusu do poľa
      pole.current && pole.current.focus();
      document.body.classList.add("bez-scrollu");
      return () => {
        document.body.classList.remove("bez-scrollu");
        // Fokus späť na tlačidlo, ktoré dialóg otvorilo.
        if (predtym && predtym.focus && predtym !== document.body) predtym.focus();
      };
    }, []);

    // Aktívna položka vždy viditeľná pri pohybe šípkami.
    useEffect(() => {
      const el = zoznam.current && zoznam.current.querySelector('[data-aktivna="true"]');
      if (el) el.scrollIntoView({ block: "nearest" });
    }, [aktivny, skupiny]);

    function otvor(p) {
      if (!jeAktivna(p)) return;
      if (p.typ === "odhlasit") { onOdhlasit(); return; }
      window.location.href = p.url;
    }

    function klaves(e) {
      if (e.key === "ArrowDown") {
        e.preventDefault();
        if (vyberatelne.length) setAktivny((i) => (i + 1) % vyberatelne.length);
      } else if (e.key === "ArrowUp") {
        e.preventDefault();
        if (vyberatelne.length) setAktivny((i) => (i - 1 + vyberatelne.length) % vyberatelne.length);
      } else if (e.key === "Enter") {
        e.preventDefault();
        if (vyberatelne[aktivny]) otvor(vyberatelne[aktivny]);
      } else if (e.key === "Escape") {
        e.preventDefault();
        onZavriet();
      } else if (e.key === "Tab") {
        // Dialóg je modálny — Tab nesmie odísť na stránku pod ním.
        e.preventDefault();
      }
    }

    const aktivnaPolozka = vyberatelne[aktivny];
    const idPolozky = (p) => "hladanie-" + p.druh + "-" + p.id;

    return (
      <div className="hladanie" onMouseDown={(e) => { if (e.target === e.currentTarget) onZavriet(); }}>
        <div className="hladanie__okno" role="dialog" aria-modal="true" aria-label="Vyhľadávanie">
          <div className="hladanie__hlava">
            <Icon name="hladat" size={22} />
            <label htmlFor="hladanie-pole" className="sr-only">Hľadať</label>
            <input
              id="hladanie-pole"
              ref={pole}
              type="text"
              role="combobox"
              aria-expanded="true"
              aria-controls="hladanie-vysledky"
              aria-activedescendant={aktivnaPolozka ? idPolozky(aktivnaPolozka) : undefined}
              aria-autocomplete="list"
              autoComplete="off"
              spellCheck="false"
              placeholder="Hľadať aplikácie a akcie…"
              value={dopyt}
              onChange={(e) => setDopyt(e.target.value)}
              onKeyDown={klaves}
            />
            <button type="button" className="hladanie__zavriet" onClick={onZavriet} aria-label="Zavrieť vyhľadávanie">
              <span className="kbd hladanie__esc">Esc</span>
              <Icon name="zavriet" size={22} className="hladanie__x" />
            </button>
          </div>

          <div className="hladanie__telo" id="hladanie-vysledky" role="listbox" aria-label="Výsledky" ref={zoznam}>
            {skupiny.length === 0 && (
              <div className="hladanie__prazdne">
                <p>Pre „{dopyt}“ sa nič nenašlo.</p>
                <p>Hľadanie v tiketoch a zariadeniach zatiaľ nie je k dispozícii.</p>
              </div>
            )}
            {skupiny.map((sk) => (
              <div key={sk.id} role="group" aria-labelledby={"hladanie-sk-" + sk.id}>
                <p className="hladanie__skupina" id={"hladanie-sk-" + sk.id}>{sk.nazov}</p>
                {sk.polozky.map((p) => {
                  const aktivna = jeAktivna(p);
                  const index = vyberatelne.findIndex((v) => v.id === p.id && v.druh === p.druh);
                  const vybrana = index !== -1 && index === aktivny;
                  return (
                    <div
                      key={p.druh + p.id}
                      id={idPolozky(p)}
                      role="option"
                      aria-selected={vybrana ? "true" : "false"}
                      aria-disabled={aktivna ? undefined : "true"}
                      data-aktivna={vybrana ? "true" : "false"}
                      className={"hladanie__polozka" + (vybrana ? " je-vybrana" : "") + (aktivna ? "" : " je-neaktivna")}
                      onMouseMove={() => { if (index !== -1 && !vybrana) setAktivny(index); }}
                      onClick={() => otvor(p)}
                    >
                      {p.druh === "app"
                        ? <span className="hladanie__ikona" style={{ background: p.farba, color: p.farbaIkony }}><Icon name={p.ikona} size={20} /></span>
                        : <span className="hladanie__ikona hladanie__ikona--akcia"><Icon name={p.ikona} size={20} strokeWidth={2.2} /></span>}
                      <span className="hladanie__text">
                        <span className="hladanie__nazov">{p.nazov}</span>
                        {p.popis && <span className="hladanie__popis">{p.popis}</span>}
                      </span>
                      {!aktivna && <span className="stitok">{p.stav === "pripravujeme" ? "Pripravujeme" : "Bez adresy"}</span>}
                      {vybrana && <span className="hladanie__enter">Enter</span>}
                    </div>
                  );
                })}
              </div>
            ))}
          </div>

          <div className="hladanie__pata">
            <span><span className="kbd">↑</span> <span className="kbd">↓</span> pohyb</span>
            <span><span className="kbd">Enter</span> otvoriť</span>
            <span><span className="kbd">Esc</span> zavrieť</span>
            <span className="hladanie__pata-info">Zatiaľ hľadá v aplikáciách a akciách</span>
          </div>
        </div>
      </div>
    );
  }

  // Ctrl+K (Windows) / ⌘K (Mac) otvorí vyhľadávanie odkiaľkoľvek na domovskej obrazovke.
  // preventDefault: Chrome aj Firefox majú na Ctrl+K vlastné hľadanie v paneli s adresou.
  function useSkratkaHladania(otvor) {
    useEffect(() => {
      function klaves(e) {
        if ((e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && e.key.toLowerCase() === "k") {
          e.preventDefault();
          otvor();
        }
      }
      document.addEventListener("keydown", klaves);
      return () => document.removeEventListener("keydown", klaves);
    }, [otvor]);
  }

  Object.assign(window, { SearchDialog, useSkratkaHladania });
})();
