
import { Injectable, CanActivate, ExecutionContext, UnauthorizedException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { ERole } from './roles.service';
import { ROLES_KEY } from './roles.decorator';
import { IS_PUBLIC_KEY } from '../common/decorators/public.decorator';

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    // console.log('Triggered roles.guard.ts')
    const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    // console.log('isPublic', isPublic)
    if (isPublic) return true;

    const requiredRoles = this.reflector.getAllAndOverride<ERole[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    // console.log('requiredRoles', requiredRoles)
    if (!requiredRoles) return true;

    const req = context.switchToHttp().getRequest();
    // console.log('req.user.roles', req.user.roles)
    if(!req.user) process.exit(1);
    // console.log('test',requiredRoles.some((role) => req.user.roles?.find((ur: any) => ur.name === role)))
    return requiredRoles.some((role) => req.user.roles?.find((ur: any) => ur.name === role));
  }

  handleRequest(err: any, user: any, info: any) {
    // console.log('handleRequest, roles.guard')
    // console.log(err)
    // console.log(user)
    // console.log(info)
    // You can throw an exception based on either "info" or "err" arguments
    if (err || !user) {
      throw err || new UnauthorizedException();
    }
    return user;
  }
}
