import { Injectable, Logger } from '@nestjs/common';
import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
import { UserRole } from 'common/enum/UserRole.enum';

@ValidatorConstraint({ async: true })
@Injectable()
export class RoleHierarchyValidator implements ValidatorConstraintInterface {
  private logger = new Logger('RoleHierarchyValidator');

  validate(role: UserRole, args: ValidationArguments): boolean {
    const currentUser: any = args.object['currentUser']; // Extracting currentUser from the DTO

    this.logger.debug(`Current user: ${JSON.stringify(currentUser)}`);

    if (currentUser) {
      const roleHierarchy = [UserRole.USER, UserRole.ADMIN, UserRole.SUPER_ADMIN];

      // Get the index of the current user's role and the role to be assigned
      const currentUserRoleIndex = roleHierarchy.indexOf(currentUser.role);
      const newRoleIndex = roleHierarchy.indexOf(role);

      // If the current user's role is not in the hierarchy, return false
      if (currentUserRoleIndex === -1) {
        return false;
      }

      // SUPER_ADMIN can assign any role
      if (currentUser.role === UserRole.SUPER_ADMIN) {
        return true;
      }

      // ADMIN can assign either ADMIN or USER role but cannot assign SUPER_ADMIN
      if (currentUser.role === UserRole.ADMIN) {
        // If the new role is SUPER_ADMIN, deny it
        if (role === UserRole.SUPER_ADMIN) {
          return false;
        }
        // Otherwise, allow assigning ADMIN or USER role
        return newRoleIndex >= currentUserRoleIndex;
      }

      // If current user's role is USER, they can't assign any role
      return false;
    }
    return false;
  }

  defaultMessage(): string {
    return "You do not have permission to change this user's role based on your role hierarchy";
  }
}
