import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { PrismaService } from '../../prisma/prisma.service';
import { REQUIRE_MODULE_KEY } from '../decorators/require-module.decorator';

/**
 * ModuleGuard checks whether a specific module is enabled for the club.
 *
 * Used with @RequireModule('sip') decorator. Queries the club_modules table
 * to verify the module is active before allowing access.
 */
@Injectable()
export class ModuleGuard implements CanActivate {
  constructor(
    private readonly reflector: Reflector,
    private readonly prisma: PrismaService,
  ) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const requiredModule = this.reflector.getAllAndOverride<string>(REQUIRE_MODULE_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);

    if (!requiredModule) {
      return true;
    }

    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
    const request: { user?: { clubId?: string } } = context.switchToHttp().getRequest();
    const clubId = request.user?.clubId;

    if (!clubId) {
      throw new ForbiddenException('Club context is required');
    }

    const result = await this.prisma.$queryRawUnsafe<{ enabled: boolean }[]>(
      `SELECT enabled FROM club_modules WHERE "clubId" = $1 AND "moduleId" = $2`,
      clubId,
      requiredModule,
    );

    if (!result.length || !result[0].enabled) {
      throw new ForbiddenException(`Module "${requiredModule}" is not enabled for this club`);
    }

    return true;
  }
}
