import "server-only";
import { cache } from "react";
import { forbidden, redirect } from "next/navigation";
import {
  type AccessScope,
  type Permission,
  hasPermission,
  resolveScope,
} from "@/lib/auth/permissions";
import { readSessionCookie } from "@/server/auth/session-cookie";
import { type ValidatedSession, validateSessionToken } from "@/server/auth/session-service";

/**
 * Sesión de la petición actual. `cache` evita validarla más de una vez por request
 * aunque la consulten el layout, la página y varios componentes.
 */
export const getCurrentSession = cache(async (): Promise<ValidatedSession | null> => {
  const token = await readSessionCookie();
  if (!token) return null;
  return validateSessionToken(token);
});

/** Para páginas del panel: sin sesión válida redirige al login. */
export async function requireSession(): Promise<ValidatedSession> {
  const session = await getCurrentSession();
  if (!session) redirect("/admin/login?expired=1");
  return session;
}

/** Para páginas del panel: sin el permiso responde 403 (forbidden.tsx). */
export async function requirePermission(permission: Permission): Promise<ValidatedSession> {
  const session = await requireSession();
  if (!hasPermission(session.permissions, permission)) forbidden();
  return session;
}

/** Exige al menos una de las variantes ("all" u "own") y devuelve el alcance resultante. */
export async function requireScope(
  base: Parameters<typeof resolveScope>[1],
): Promise<{ session: ValidatedSession; scope: Exclude<AccessScope, "none"> }> {
  const session = await requireSession();
  const scope = resolveScope(session.permissions, base);
  if (scope === "none") forbidden();
  return { session, scope };
}
