/**
 * Admin Guard
 *
 * Restricts access to system-level admin operations.
 * System administrators are configured via the SYSTEM_ADMIN_IDS environment variable.
 *
 * Configuration:
 *   SYSTEM_ADMIN_IDS=uuid1,uuid2,uuid3 (comma-separated list of user IDs)
 *
 * Note: Workspace ownership does NOT grant system admin access. These are separate concepts:
 *   - Workspace owner: Can manage their workspace and its members
 *   - System admin: Can perform system-level operations across all workspaces
 */

import {
  Injectable,
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Logger,
} from "@nestjs/common";
import type { AuthenticatedRequest } from "../../common/types/user.types";

@Injectable()
export class AdminGuard implements CanActivate {
  private readonly logger = new Logger(AdminGuard.name);
  private readonly systemAdminIds: Set<string>;

  constructor() {
    // Load system admin IDs from environment variable
    const adminIdsEnv = process.env.SYSTEM_ADMIN_IDS ?? "";
    this.systemAdminIds = new Set(
      adminIdsEnv
        .split(",")
        .map((id) => id.trim())
        .filter((id) => id.length > 0)
    );

    if (this.systemAdminIds.size === 0) {
      this.logger.warn(
        "No system administrators configured. Set SYSTEM_ADMIN_IDS environment variable."
      );
    } else {
      this.logger.log(
        `System administrators configured: ${String(this.systemAdminIds.size)} user(s)`
      );
    }
  }

  /**
   * Check if a user ID is a system administrator
   */
  isSystemAdmin(userId: string): boolean {
    return this.systemAdminIds.has(userId);
  }

  canActivate(context: ExecutionContext): boolean {
    const request = context.switchToHttp().getRequest<AuthenticatedRequest>();
    const user = request.user;

    if (!user) {
      throw new ForbiddenException("User not authenticated");
    }

    if (!this.isSystemAdmin(user.id)) {
      this.logger.warn(`Non-admin user ${user.id} attempted admin operation`);
      throw new ForbiddenException("This operation requires system administrator privileges");
    }

    return true;
  }
}
