// src/lib/sites/site-scoped-gate.tsx — gate partagé des sections qui n'ont
// aucun sens sans site (keywords, backlink, pages, gsc, flight-checker,
// projects, content).
//
// Un membre (ni owner ni admin) dont l'org ne lui a partagé AUCUN site voit une
// explication au lieu de tableaux vides sans cause. Posé au layout de SEGMENT —
// pas à la racine du groupe (app), et pas en rewrite dans le proxy (un rewrite y
// provoque un self-fetch RSC en 500, cf. content/layout.tsx). La racine gaterait
// aussi settings/support, c'est-à-dire précisément les pages dont un membre
// bloqué a besoin pour se débloquer (changer son mot de passe, voir qui est
// propriétaire, ouvrir un ticket).
import "server-only";
import { cache } from "react";
import { NoSiteAccessNotice } from "@/components/site/no-site-access-notice";
// Pendant une impersonation le support ne doit pas heurter les impasses de la
// cible : on rend la section réelle. Le détecteur est partagé et dédupé par
// requête, comme les autres lectures ci-dessous.
import { isImpersonating } from "@/lib/auth/impersonation-guard";
import { getSitesForActiveOrg, hasFullSiteAccess } from "./access";
import { shouldShowNoSiteAccess } from "./no-site-access";

/**
 * Rend `<NoSiteAccessNotice />` quand la section site-scoped n'a rien à montrer
 * au caller, sinon `null` (la page rend normalement).
 * Usage dans un layout de section : `return (await siteScopedGate()) ?? children;`
 */
export const siteScopedGate = cache(
  async (): Promise<React.ReactNode | null> => {
    const [sites, fullAccess, impersonating] = await Promise.all([
      getSitesForActiveOrg(),
      hasFullSiteAccess(),
      isImpersonating(),
    ]);
    if (!shouldShowNoSiteAccess(sites.length, fullAccess, impersonating)) {
      return null;
    }
    return <NoSiteAccessNotice />;
  },
);
