/* auth.jsx — prihlásenie cez Microsoft (MSAL.js), rovnaký vzor ako v Helpdesku.
   Vystavuje window.HUB_AUTH = { login(), logout(), getToken(), getIdTokenClaims(), getAccount(), ensureReady(), nakonfigurovany }.
   Authorization Code + PKCE (MSAL to robí automaticky pre "spa" redirectUri).
*/
(function () {
  "use strict";

  // Fáza 1 potrebuje len meno, e-mail, oddelenie a fotku prihláseného — User.Read stačí
  // a nevyžaduje admin consent. Ďalšie scope (napr. token pre Worker Helpdesku kvôli živým
  // číslam na dlaždiciach) pribudnú až vo fáze 3, každý samostatným volaním — nikdy nemiešať
  // scope dvoch rôznych resources v jednom acquireToken* volaní (viď auth.jsx v Helpdesku).
  const GRAPH_SCOPES = ["https://graph.microsoft.com/User.Read"];

  const cfg = window.HUB_CONFIG;
  const nakonfigurovany = Boolean(cfg.CLIENT_ID);

  // Bez CLIENT_ID by MSAL pri vytváraní zlyhal — hub sa vtedy len vyrenderuje s hláškou
  // o chýbajúcej registrácii (app.jsx), nič sa neprihlasuje.
  const msalInstance = nakonfigurovany
    ? new msal.PublicClientApplication({
        auth: {
          clientId: cfg.CLIENT_ID,
          authority: "https://login.microsoftonline.com/" + cfg.TENANT_ID,
          // Len origin, presne ako je zaregistrovaný Redirect URI v Entra ID.
          redirectUri: window.location.origin,
          postLogoutRedirectUri: window.location.origin,
        },
        cache: {
          // localStorage, aby prihlásenie prežilo zatvorenie záložky (rovnaká voľba a rovnaký
          // kompromis ako v Helpdesku: token leží v prehliadači, kým sa používateľ neodhlási
          // alebo token nevyprší — na zdieľaných počítačoch treba prehodnotiť).
          cacheLocation: "localStorage",
          storeAuthStateInCookie: false,
        },
      })
    : null;

  // Redirect flow namiesto popup — popup je na mobile (hlavne Safari/iOS) nespoľahlivý.
  let ready = null;
  function ensureReady() {
    if (!msalInstance) return Promise.resolve();
    if (!ready) {
      ready = msalInstance.initialize()
        .then(() => msalInstance.handleRedirectPromise())
        .then((result) => { if (result && result.account) msalInstance.setActiveAccount(result.account); });
    }
    return ready;
  }

  function getAccount() {
    if (!msalInstance) return null;
    const active = msalInstance.getActiveAccount();
    if (active) return active;
    const accounts = msalInstance.getAllAccounts();
    if (accounts.length === 0) return null;
    msalInstance.setActiveAccount(accounts[0]);
    return accounts[0];
  }

  // Stránka sa prenaviguje na login.microsoftonline.com; účet sa nastaví po návrate v ensureReady().
  // Ak je používateľ už prihlásený do M365 (Outlook, Teams), Microsoft ho väčšinou pustí bez hesla.
  function login() {
    return msalInstance.loginRedirect({ scopes: GRAPH_SCOPES });
  }

  // Úplné odhlásenie aj z Microsoft relácie (rovnako ako Helpdesk) — na zdieľanom počítači
  // nesmie po odhlásení z hubu zostať otvorená M365 relácia.
  function logout() {
    return msalInstance.logoutRedirect({ account: getAccount() });
  }

  async function getToken() {
    return (await acquire(false)).accessToken;
  }

  // Údaje z ID tokenu (napr. "acct": 0 = člen tenantu, 1 = hosť). Uložený ID token môže byť
  // starší než nastavenie v Entra (Token configuration) — forceRefresh si od Microsoftu vypýta
  // čerstvý bez opätovného prihlásenia.
  async function getIdTokenClaims({ forceRefresh = false } = {}) {
    if (!forceRefresh) {
      const account = getAccount();
      if (account && account.idTokenClaims) return account.idTokenClaims;
    }
    return (await acquire(forceRefresh)).idTokenClaims || {};
  }

  async function acquire(forceRefresh) {
    await ensureReady();
    const account = getAccount();
    if (!account) throw new Error("Nie ste prihlásený.");
    try {
      return await msalInstance.acquireTokenSilent({ scopes: GRAPH_SCOPES, account, forceRefresh });
    } catch (err) {
      if (err instanceof msal.InteractionRequiredAuthError) {
        await msalInstance.acquireTokenRedirect({ scopes: GRAPH_SCOPES, account });
        // Stránka sa prenavigovala na Microsoft — nikdy nevrátiť prázdny výsledok, na ktorom by
        // volajúci spadol (.accessToken z undefined), kým navigácia nedobehne.
        return new Promise(() => {});
      }
      throw err;
    }
  }

  window.HUB_AUTH = { login, logout, getToken, getIdTokenClaims, getAccount, ensureReady, nakonfigurovany };
})();
