// Caffè Italia · session + rôle admin
// ===================================
// Un seul endroit répond à « qui est connecté, et est-ce un admin ».
// Chargé après src/supabase.jsx, avant components / admin / account / app.

const { useState: _auUseState, useEffect: _auUseEffect } = React;

// « Mon email est-il dans admin_emails ? »
// La policy admin_emails_self_read restreint déjà la requête à la ligne de
// l'appelant : inutile de passer l'email, et impossible d'énumérer les autres.
// Fail closed — toute erreur renvoie false.
window.fetchIsAdmin = async function fetchIsAdmin(){
  if (!window.sb) return false;
  try {
    const { data, error } = await window.sb.from("admin_emails").select("email").limit(1);
    if (error) return false;
    return (data || []).length > 0;
  } catch {
    return false;
  }
};

// undefined = pas encore chargé · null = déconnecté · objet = session active
// ─── Mode « récupération de mot de passe » ─────────────────────────────────
// Supabase n'émet PASSWORD_RECOVERY qu'une fois, au moment où il consomme le
// lien reçu par email — c'est-à-dire avant que React ne soit monté. On écoute
// donc dès le chargement de ce fichier (juste après la création du client) et
// on retient l'événement dans une variable de module : un composant qui monte
// après coup le retrouve au lieu de l'avoir manqué.
// Détecté deux fois, exprès. L'événement PASSWORD_RECOVERY est asynchrone :
// il peut arriver après le premier rendu. Le fragment de l'URL, lui, est là
// dès maintenant — ce fichier est chargé bien avant que React ne monte.
let _recoveryMode = /(?:^|[#&])type=recovery(?:&|$)/.test(
  window.__INITIAL_HASH__ || window.location.hash || "");
const _recoveryWatchers = new Set();

function _setRecovery(on){
  _recoveryMode = on;
  _recoveryWatchers.forEach(fn => fn(on));
}

if (window.sb) {
  window.sb.auth.onAuthStateChange((event) => {
    if (event === "PASSWORD_RECOVERY") _setRecovery(true);
  });
}

// Appelé quand le nouveau mot de passe a été enregistré, ou que l'utilisateur
// abandonne : on repasse sur l'écran de compte normal.
window.exitRecoveryMode = () => _setRecovery(false);

function useRecoveryMode(){
  const [on, setOn] = _auUseState(_recoveryMode);
  _auUseEffect(() => {
    _recoveryWatchers.add(setOn);
    setOn(_recoveryMode);            // rattrape un événement déjà passé
    return () => { _recoveryWatchers.delete(setOn); };
  }, []);
  return on;
}

function useSession(){
  const [session, setSession] = _auUseState(undefined);
  _auUseEffect(() => {
    if (!window.sb) { setSession(null); return; }
    window.sb.auth.getSession().then(({ data }) => setSession(data.session));
    const { data: sub } = window.sb.auth.onAuthStateChange((_event, sess) => setSession(sess));
    return () => sub.subscription.unsubscribe();
  }, []);
  return session;
}

// ready ne passe à true que lorsque la question « est-ce un admin » est
// tranchée. Rendre un écran avant ce moment ferait clignoter le mauvais.
function useAdmin(){
  const session = useSession();
  const key = session === undefined ? "loading" : (session ? session.user.id : "anon");
  const [state, setState] = _auUseState({ key: null, isAdmin: false, ready: false });

  _auUseEffect(() => {
    if (session === undefined) { setState({ key, isAdmin: false, ready: false }); return; }
    if (!session)              { setState({ key, isAdmin: false, ready: true  }); return; }
    let cancelled = false;
    setState({ key, isAdmin: false, ready: false });
    (async () => {
      const ok = await window.fetchIsAdmin();
      if (!cancelled) setState({ key, isAdmin: ok, ready: true });
    })();
    return () => { cancelled = true; };
  }, [key]);

  // Le state est produit par un effet, qui ne tourne qu'après le rendu. Tant
  // qu'il porte une clé différente de la session courante, il est périmé :
  // on renvoie « pas encore tranché » plutôt que la réponse d'une autre session.
  const settled = state.key === key;
  return {
    session,
    isAdmin: settled ? state.isAdmin : false,
    ready:   settled ? state.ready   : false,
  };
}
