/* app.jsx — Root: rozhodne, či ukázať prihlásenie alebo domovskú obrazovku.

   Stavy: "nacitavam" → "login" | "ready" | "host" | "neovereny" (posledné dva hub nepustí ďalej)

   Náhľad bez prihlásenia: na localhost s ?nahlad=1 sa domovská obrazovka vyrenderuje s vymysleným
   používateľom, aby sa dalo ladiť UI aj bez Entra registrácie. Na produkčnej adrese to nefunguje
   (a nič by to neodhalilo — hub vo fáze 1 nemá žiadne dáta, len odkazy).
*/
(function () {
  "use strict";

  const { useState, useEffect } = React;
  const cfg = window.HUB_CONFIG;
  const auth = window.HUB_AUTH;

  const LOKALNE = ["localhost", "127.0.0.1", "[::1]"].includes(window.location.hostname);
  const NAHLAD_PARAM = LOKALNE ? new URLSearchParams(window.location.search).get("nahlad") : null;
  const NAHLAD = NAHLAD_PARAM === "1";
  // ?nahlad=1&rola=superadmin|admin|zamestnanec (predvolene superadmin)
  const NAHLAD_ROLA = (LOKALNE && new URLSearchParams(window.location.search).get("rola")) || "superadmin";
  // ?nahlad=host / ?nahlad=neovereny — obrazovka odmietnutého účtu bez prihlásenia
  const NAHLAD_HOST = NAHLAD_PARAM === "host" || NAHLAD_PARAM === "neovereny" ? NAHLAD_PARAM : null;

  // Dnu smie LEN interný človek tenantu PROPLUSCO — za každých okolností (rozhodnutie Jakuba,
  // 2026-10-05). Hostia (B2B guest účty pozvané napr. do Teams) sa na Microsofte prihlásiť vedia,
  // lebo sú v adresári tenantu, preto rozhoduje hub podľa ID tokenu:
  //   tid  = náš tenant
  //   acct = 0 (člen; 1 = hosť) — Entra → Token configuration → optional claim "acct"
  // Čokoľvek iné, vrátane chýbajúceho "acct", NEPUSTÍ. Ak by niekto "acct" v Entra zmazal,
  // nedostane sa dnu nikto, kým sa nastavenie nevráti — vedome zvolené pred rizikom, že by
  // prešiel hosť.
  //
  // Vracia { stav: "clen" | "host" | "neovereny", rola }.
  async function overClenstvo() {
    let claims = await auth.getIdTokenClaims();
    // Uložený token môže byť starší než nastavenie v Entra → vypýtať čerstvý.
    if (claims.acct === undefined) claims = await auth.getIdTokenClaims({ forceRefresh: true });
    if (claims.tid !== cfg.TENANT_ID) return { stav: "neovereny" };
    if (claims.acct === 1 || claims.acct === "1") return { stav: "host" };
    if (claims.acct === 0 || claims.acct === "0") return { stav: "clen", rola: rolaZClaims(claims) };
    console.error("ID token neobsahuje 'acct' — Entra ID → PLUS Hub → Token configuration → optional claim acct (ID). Bez neho hub nepustí nikoho.");
    return { stav: "neovereny" };
  }

  // App role z Entra ("roles" v ID tokene) → "superadmin" | "admin" | "zamestnanec".
  // Bez roly = zamestnanec, teda najmenej. Rola sa v tokene objaví až po novom prihlásení
  // (alebo keď uložený token vyprší, cca do hodiny).
  function rolaZClaims(claims) {
    const roly = Array.isArray(claims.roles) ? claims.roles.map((r) => cfg.ROLY[r]).filter(Boolean) : [];
    if (roly.includes("superadmin")) return "superadmin";
    if (roly.includes("admin")) return "admin";
    return "zamestnanec";
  }

  function firmaPodlaEmailu(email) {
    const domena = String(email || "").split("@")[1];
    return (domena && cfg.FIRMA_PODLA_DOMENY[domena.toLowerCase()]) || "";
  }

  // Základ z MSAL účtu (je hneď k dispozícii, bez sieťového volania); Graph ho neskôr doplní.
  function pouzivatelZUctu(account) {
    const meno = account.name || account.username;
    return {
      meno,
      krstne: String(meno).trim().split(/\s+/)[0],
      email: account.username,
      firma: firmaPodlaEmailu(account.username),
      oddelenie: "",
      fotka: null,
    };
  }

  function Nacitavam() {
    return (
      <div className="boot" role="status">
        <PlusMark size={40} className="boot__plus" />
        <span>Načítavam…</span>
      </div>
    );
  }

  function Root() {
    const [stav, setStav] = useState(NAHLAD ? "ready" : NAHLAD_HOST || "nacitavam");
    const [pouzivatel, setPouzivatel] = useState(NAHLAD
      ? { meno: "Náhľad Používateľ", krstne: "Náhľad", email: "nahlad@proplusco.sk", firma: "PROPLUSCO", oddelenie: "IT", fotka: null, rola: NAHLAD_ROLA }
      : NAHLAD_HOST ? { meno: "Hosť", email: "host@example.com" } : null);
    const [chyba, setChyba] = useState(null);
    const [presmerovavam, setPresmerovavam] = useState(false);

    useEffect(() => {
      if (NAHLAD || NAHLAD_HOST) return;
      if (!auth.nakonfigurovany) { setStav("login"); return; }
      let zruseny = false;
      auth.ensureReady()
        .then(async () => {
          if (zruseny) return;
          const account = auth.getAccount();
          if (!account) { setStav("login"); return; }
          const { stav: clenstvo, rola } = await overClenstvo();
          if (zruseny) return;
          setPouzivatel({ ...pouzivatelZUctu(account), rola });
          setStav(clenstvo === "clen" ? "ready" : clenstvo);
        })
        .catch((err) => {
          if (zruseny) return;
          // Typicky zrušené prihlásenie alebo zamietnutý prístup (napr. používateľ nie je
          // priradený k aplikácii v Entra ID) — ukáž prihlásenie s hláškou, nie prázdnu stránku.
          console.error("Prihlásenie zlyhalo:", err);
          setChyba(zrozumitelnaChyba(err));
          setStav("login");
        });
      return () => { zruseny = true; };
    }, []);

    // Doplnenie profilu z Graphu (oddelenie, krstné meno, fotka) — best-effort, chyba nič neblokuje.
    useEffect(() => {
      if (stav !== "ready" || NAHLAD) return;
      let zruseny = false;
      let fotkaUrl = null;
      window.HUB_GRAPH.getProfil()
        .then((p) => {
          if (zruseny) return;
          setPouzivatel((u) => ({
            ...u,
            meno: p.displayName || u.meno,
            krstne: p.givenName || u.krstne,
            email: p.mail || p.userPrincipalName || u.email,
            oddelenie: p.department || "",
          }));
        })
        .catch((err) => console.warn("Profil z Graphu sa nenačítal:", err));
      window.HUB_GRAPH.getFotka().then((url) => {
        fotkaUrl = url;
        if (!zruseny && url) setPouzivatel((u) => ({ ...u, fotka: url }));
      });
      return () => {
        zruseny = true;
        if (fotkaUrl) URL.revokeObjectURL(fotkaUrl);
      };
    }, [stav]);

    function login() {
      setChyba(null);
      setPresmerovavam(true);
      auth.login().catch((err) => {
        setPresmerovavam(false);
        setChyba(zrozumitelnaChyba(err));
      });
    }

    function logout() {
      if (NAHLAD || NAHLAD_HOST) { window.location.href = "./"; return; }
      auth.logout();
    }

    if (stav === "nacitavam") return <Nacitavam />;
    if (stav === "host" || stav === "neovereny") {
      return <HostScreen dovod={stav} email={pouzivatel.email} onLogout={logout} />;
    }
    if (stav === "login") {
      return (
        <LoginScreen
          onLogin={login}
          chyba={chyba}
          stav={!auth.nakonfigurovany ? "nenakonfigurovany" : presmerovavam ? "presmerovavam" : "ready"}
        />
      );
    }
    return <HomeScreen pouzivatel={pouzivatel} apps={cfg.APPS} onLogout={logout} />;
  }

  function zrozumitelnaChyba(err) {
    const kod = (err && (err.errorCode || err.code)) || "";
    const text = String((err && (err.errorMessage || err.message)) || "");
    if (kod === "user_cancelled" || /AADSTS65004|access_denied/i.test(text)) {
      return "Prihlásenie bolo zrušené. Skúste to znova.";
    }
    if (/AADSTS50105/.test(text)) {
      return "Váš účet nemá prístup k PLUS Hubu. Obráťte sa na IT oddelenie.";
    }
    return "Prihlásenie sa nepodarilo. Skúste to znova, a ak to nepomôže, obráťte sa na IT oddelenie.";
  }

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