import {
  CanActivate,
  ExecutionContext,
  ForbiddenException,
  Injectable,
} from '@nestjs/common'
import { ActorService } from './actor.service.js'
import type { AuthentikJwtPayload } from './jwt-payload.interface.js'

// Applied AFTER JwtAuthGuard. Enforces that the request is coming from an
// operator session — both proofs required:
//   1. Token audience is 'dezky-operator' (the operator OAuth client)
//   2. The DB-resolved User has platformAdmin=true
//
// Either proof alone is insufficient. The token claim makes "is this a
// privileged session" derivable from the JWT alone; the DB check ensures
// revocation works without waiting for the token to expire.
@Injectable()
export class OperatorGuard implements CanActivate {
  constructor(private readonly actor: ActorService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const req = context.switchToHttp().getRequest<{ user?: AuthentikJwtPayload }>()
    const jwt = req.user
    if (!jwt) {
      throw new ForbiddenException('Authentication required (JwtAuthGuard must run first)')
    }

    const aud = Array.isArray(jwt.aud) ? jwt.aud : [jwt.aud]
    if (!aud.includes('dezky-operator')) {
      throw new ForbiddenException('This endpoint requires an operator-scoped token')
    }

    const actor = await this.actor.resolve(jwt)
    if (!actor.platformAdmin) {
      throw new ForbiddenException('platformAdmin role required')
    }

    return true
  }
}
