import { getCurrentUser } from "./user";
import { AuthenticatedUser, PermissionString, SystemRoleId } from "@/types/auth";

export class UnauthorizedError extends Error {
  constructor(message = "Unauthorized: Please sign in to continue") {
    super(message);
    this.name = "UnauthorizedError";
  }
}

export class ForbiddenError extends Error {
  constructor(message = "Forbidden: You do not have permission to perform this action") {
    super(message);
    this.name = "ForbiddenError";
  }
}

/**
 * Ensures user is authenticated and not suspended
 */
export async function requireAuth(): Promise<AuthenticatedUser> {
  const user = await getCurrentUser();
  if (!user) {
    throw new UnauthorizedError();
  }
  if (user.is_suspended) {
    throw new ForbiddenError(`Account suspended: ${user.suspended_reason || "Contact support"}`);
  }
  if (!user.is_active) {
    throw new ForbiddenError("Account is inactive");
  }
  return user;
}

/**
 * Ensures user has a specific granular permission
 */
export async function requirePermission(permission: PermissionString): Promise<AuthenticatedUser> {
  const user = await requireAuth();

  // Super Admin automatically bypasses all permission checks
  if (user.roles.includes("SUPER_ADMIN")) {
    return user;
  }

  if (!user.permissions.includes(permission)) {
    throw new ForbiddenError(`Missing required permission: ${permission}`);
  }

  return user;
}

/**
 * Ensures user has one of the specified system roles
 */
export async function requireRole(allowedRoles: SystemRoleId[]): Promise<AuthenticatedUser> {
  const user = await requireAuth();

  if (user.roles.includes("SUPER_ADMIN")) {
    return user;
  }

  const hasRole = user.roles.some((r) => allowedRoles.includes(r));
  if (!hasRole) {
    throw new ForbiddenError(`Action requires one of the following roles: ${allowedRoles.join(", ")}`);
  }

  return user;
}
