/**
 * Server-side admin guard.
 *
 * Use in server components, route handlers, and server actions to assert
 * the caller has role=ADMIN. Redirects to /login on missing session and
 * to / on insufficient role.
 *
 * Usage:
 *   const admin = await requireAdmin();      // throws redirect on failure
 *   // ... admin code ...
 */
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { auth } from "@/lib/auth";

export type AdminContext = {
  userId: string;
  email: string;
  name: string;
  role: "ADMIN";
};

export async function getAdminContext(): Promise<AdminContext | null> {
  const session = await auth.api.getSession({ headers: await headers() });
  if (!session?.user) return null;
  const role = (session.user as { role?: string }).role ?? "USER";
  if (role !== "ADMIN") return null;
  return {
    userId: session.user.id,
    email: session.user.email,
    name: session.user.name,
    role: "ADMIN",
  };
}

export async function requireAdmin(): Promise<AdminContext> {
  const session = await auth.api.getSession({ headers: await headers() });
  if (!session?.user) {
    redirect("/login?from=/admin");
  }
  const role = (session.user as { role?: string }).role ?? "USER";
  if (role !== "ADMIN") {
    // Logged in but not admin: bounce to home, not back to login (prevents loop)
    redirect("/?error=admin_required");
  }
  return {
    userId: session.user.id,
    email: session.user.email,
    name: session.user.name,
    role: "ADMIN",
  };
}

/** Write an audit log entry. Best-effort: failures don't block the action. */
export async function audit(input: {
  actorId: string;
  actorName: string;
  action: string;
  target?: string;
  metadata?: Record<string, unknown>;
  ipAddress?: string;
}): Promise<void> {
  try {
    const { prisma } = await import("@/lib/db");
    await prisma.auditLog.create({
      data: {
        actorId: input.actorId,
        actorName: input.actorName,
        action: input.action,
        target: input.target ?? null,
        metadata: input.metadata ? JSON.parse(JSON.stringify(input.metadata)) : undefined,
        ipAddress: input.ipAddress ?? null,
      },
    });
  } catch (err) {
    console.warn("[audit] failed to write log:", err);
  }
}
