import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import type { Session } from "./auth";

/**
 * Garde-fous serveur pour les routes protégées.
 * À utiliser dans les `layout.tsx` d'admin / client (Server Components).
 *
 * Différence vs middleware :
 * - Le middleware redirige rapidement les requêtes sans cookie (perf Edge).
 * - Ces guards valident cryptographiquement la session + vérifient le rôle.
 *
 * Implémentation : on hit directement l'endpoint /api/auth/get-session
 * de Better Auth via fetch loopback. Plus fiable que `auth.api.getSession`
 * qui dans certains environnements (proxy + Server Components) ne voit pas
 * le cookie correctement.
 */

export async function getSession(): Promise<Session | null> {
  const c = await cookies();
  const cookieString = c
    .getAll()
    .map((x) => `${x.name}=${x.value}`)
    .join("; ");
  if (!cookieString) return null;

  // En prod le container écoute sur 0.0.0.0:3000. On hit en loopback pour
  // éviter le round-trip via Apache/Cloudflare et les soucis de hostname.
  const baseUrl =
    process.env.INTERNAL_AUTH_URL ??
    process.env.BETTER_AUTH_URL ??
    "http://localhost:3000";

  try {
    const res = await fetch(`${baseUrl}/api/auth/get-session`, {
      headers: { cookie: cookieString },
      cache: "no-store",
    });
    if (!res.ok) return null;
    const data = (await res.json()) as Session | null;
    if (!data || !("session" in data)) return null;
    return data;
  } catch (err) {
    console.error("[guards] getSession fetch failed:", err);
    return null;
  }
}

export async function requireAdmin() {
  const session = await getSession();
  if (!session) {
    redirect("/login?from=/socialexadmin");
  }
  if (session.user.role !== "admin") {
    redirect("/espace-client");
  }
  return session;
}

export async function requireClient() {
  const session = await getSession();
  if (!session) {
    redirect("/login?from=/espace-client");
  }
  // Un admin peut consulter l'espace client (pour debug / impersonation soft).
  // À durcir si besoin.
  return session;
}
