import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import type { AuthenticatedUser } from '../auth/current-user.decorator';
import {
  PERMISSION_KEY,
  RequiredPermission,
} from './require-permission.decorator';
import { PermissionsService } from './permissions.service';

/** Second guard global (après JwtAuthGuard) : applique @RequirePermission
 *  en relisant la matrice EN BASE — le JWT ne porte jamais de droits. */
@Injectable()
export class PermissionsGuard implements CanActivate {
  constructor(
    private readonly reflector: Reflector,
    private readonly permissionsService: PermissionsService,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const required = this.reflector.getAllAndOverride<RequiredPermission>(
      PERMISSION_KEY,
      [context.getHandler(), context.getClass()],
    );
    if (!required) return true; // pas d'exigence déclarée (ex. routes @Public)

    const user: AuthenticatedUser | undefined = context
      .switchToHttp()
      .getRequest().user;
    if (!user) throw new ForbiddenException();

    const allowed = await this.permissionsService.can(
      user.roleId,
      required.category,
      required.right,
    );
    if (!allowed) {
      throw new ForbiddenException(
        `Droit manquant : ${required.category}.${required.right}`,
      );
    }
    return true;
  }
}
