import { redirect } from "next/navigation";
import type { Session } from "next-auth";
import { UserRole } from "@prisma/client";

import { auth } from "@/auth";

// =====================================================================
// Auth-Utils für Server Components, Server Actions, Route Handlers
// ---------------------------------------------------------------------
// Wir kapseln die Session-Auflösung an einer Stelle, damit jede
// geschützte Route denselben Sicherheits-Pfad geht:
//
//   1. `getSession()`         → optional, gibt `null` zurück
//   2. `requireSession()`     → eingeloggt, sonst Redirect /login
//   3. `requireKitaSession()` → eingeloggt + kitaId vorhanden + Privacy-Consent
//   4. `requireRole()`        → zusätzlich Rollen-Whitelist
//
// Mandanten-Isolation: NIEMALS `session.user.kitaId` ungeprüft an Prisma
// reichen. Über `requireKitaSession` ist garantiert, dass der Wert
// nicht-null ist und der Consent-Zeitstempel gesetzt wurde.
// =====================================================================

export type AuthenticatedSession = Session & {
  user: NonNullable<Session["user"]>;
};

export type KitaSession = AuthenticatedSession & {
  user: AuthenticatedSession["user"] & { kitaId: string };
};

export async function getSession(): Promise<Session | null> {
  return auth();
}

export async function requireSession(): Promise<AuthenticatedSession> {
  const session = await auth();
  if (!session?.user?.id) {
    redirect("/login");
  }
  return session as AuthenticatedSession;
}

/**
 * Garantiert: eingeloggter User MIT Mandantenzuordnung UND akzeptierter
 * Datenschutzerklärung. Genau diese Funktion ist der Single-Point-of-Truth
 * für alle Tenant-gebundenen Server Actions / Page Components.
 */
export async function requireKitaSession(): Promise<KitaSession> {
  const session = await requireSession();

  if (!session.user.kitaId) {
    // Superadmins haben keine Kita → eigene Oberfläche.
    if (session.user.role === UserRole.SUPERADMIN) {
      redirect("/admin");
    }
    // Frisch registrierte Gründer → in den Onboarding-Wizard.
    redirect("/onboarding");
  }

  // DSGVO-Gate: Ohne Privacy-Consent → erst Consent einholen.
  // Wir prüfen das hier zentral statt in jeder Route einzeln.
  const consent = await consentCheck(session.user.id);
  if (!consent) {
    redirect("/onboarding/consent");
  }

  return session as KitaSession;
}

export async function requireRole(
  allowed: UserRole[],
): Promise<AuthenticatedSession> {
  const session = await requireSession();
  if (!allowed.includes(session.user.role)) {
    redirect("/forbidden");
  }
  return session;
}

// ---------------------------------------------------------------------
// interne Helfer
// ---------------------------------------------------------------------

async function consentCheck(userId: string | undefined): Promise<boolean> {
  if (!userId) return false;

  // Lazy-Import, damit `auth-utils` selbst Edge-kompatibel bleibt
  // (Prisma läuft nur in Node-Runtime).
  const { prisma } = await import("@/lib/prisma");
  const user = await prisma.user.findUnique({
    where: { id: userId },
    select: { privacyPolicyAcceptedAt: true },
  });
  return !!user?.privacyPolicyAcceptedAt;
}
