﻿import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
} from "@nestjs/common";
import { UserRole } from "../entities/usuario.entity";
import { PERMISSION_METADATA_KEY } from "../decorators/require-permission.decorator";
import { DEFAULT_PERMISSIONS_BY_ROLE, PermissionMap } from "../default-permissions";

@Injectable()
export class PermissionGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const handler = context.getHandler();
    const controller = context.getClass();

    const requirement =
      Reflect.getMetadata(PERMISSION_METADATA_KEY, handler) ||
      Reflect.getMetadata(PERMISSION_METADATA_KEY, controller);

    if (!requirement) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const user = request.user;

    if (!user) {
      throw new ForbiddenException("Usuario no autenticado");
    }

    if (user.rol === UserRole.SUPER_ADMIN) {
      return true;
    }

    const basePermissions: PermissionMap =
      DEFAULT_PERMISSIONS_BY_ROLE[user.rol] || {};
    const userPermissions: PermissionMap = {
      ...basePermissions,
      ...(user.permissions || {}),
    };

    const currentLevel = userPermissions[requirement.module] || "none";

    if (requirement.level === "read") {
      if (currentLevel === "read" || currentLevel === "write") {
        return true;
      }
      throw new ForbiddenException(
        `Sin permiso de lectura para módulo ${requirement.module}`,
      );
    }

    if (currentLevel === "write") {
      return true;
    }

    throw new ForbiddenException(
      `Sin permiso de escritura para módulo ${requirement.module}`,
    );
  }
}
