// src/lib/auth/impersonation-guard.ts — détecteur d'impersonation partagé.
import "server-only";
import { headers } from "next/headers";
import { cache } from "react";
import { auth } from "@/lib/auth";

/** Forme minimale que Better Auth renvoie : `session.session.impersonatedBy`
 *  est posé (id du super-admin) le temps de l'impersonation, absent sinon. */
type MaybeImpersonatedSession = {
  session?: { impersonatedBy?: string | null } | null;
} | null;

/**
 * Prédicat pur, testable sans mock : cette session est-elle une impersonation ?
 * Ne pas appeler directement depuis une Server Action — utiliser
 * `isImpersonating()`, qui lit la session courante.
 */
export function sessionIsImpersonated(session: MaybeImpersonatedSession) {
  return Boolean(session?.session?.impersonatedBy);
}

/**
 * Pendant une impersonation, Better Auth remplace `session.user` par la
 * personne cible : toute écriture clée sur `session.user.id` atterrit donc sur
 * SON compte. Les Server Actions qui persistent une préférence ou un état
 * utilisateur doivent sauter leur écriture DB quand ceci est vrai.
 *
 * Les effets propres au navigateur de l'opérateur (cookies, état de session)
 * restent légitimes : c'est la persistance en base qui ne l'est pas.
 *
 * Dédupé par requête (`cache`) et ne lève jamais : hors contexte de requête
 * (build, script, test) la réponse est `false`.
 */
export const isImpersonating = cache(async (): Promise<boolean> => {
  try {
    const session = await auth.api.getSession({ headers: await headers() });
    return sessionIsImpersonated(session as MaybeImpersonatedSession);
  } catch {
    // Hors contexte de requête : pas d'impersonation possible.
    return false;
  }
});
