import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { UserRole } from '@prisma/client';
import { PERMISSIONS_KEY } from '../decorators/permissions.decorator';

function toPermissionList(value: unknown): string[] {
  if (!value) return [];
  if (Array.isArray(value)) return value.filter((v) => typeof v === 'string');
  return [];
}

@Injectable()
export class PermissionsGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    const requiredAny =
      this.reflector.getAllAndOverride<string[]>(PERMISSIONS_KEY, [
        context.getHandler(),
        context.getClass(),
      ]) ?? [];

    if (requiredAny.length === 0) return true;

    const req = context.switchToHttp().getRequest();
    const user = req?.user as
      | { role?: UserRole; permissions?: unknown }
      | undefined;
    if (!user?.role) return true;

    if (user.role === UserRole.ADMIN || user.role === UserRole.SUPERADMIN)
      return true;
    if (user.role !== UserRole.SUBADMIN) return true;

    const perms = toPermissionList(user.permissions);
    const ok = requiredAny.some((p) => perms.includes(p));
    if (!ok) throw new ForbiddenException('Insufficient permissions');
    return true;
  }
}
