import {
  Injectable,
  CanActivate,
  ExecutionContext,
  UnauthorizedException,
} from '@nestjs/common';
import { PrismaService } from '../../../prisma/prisma.service';

/**
 * ApiKeyGuard validates the X-API-Key header against the api_keys table.
 *
 * API keys are scoped to a specific club and have defined access scopes.
 * Used for server-to-server integrations (1C, external systems).
 *
 * @example
 * @UseGuards(ApiKeyGuard)
 * @Get('/external/clients')
 * getClientsExternal() { ... }
 */
@Injectable()
export class ApiKeyGuard implements CanActivate {
  constructor(private readonly prisma: PrismaService) {}

  async canActivate(context: ExecutionContext): Promise<boolean> {
    const request = context.switchToHttp().getRequest();
    const apiKey = request.headers['x-api-key'] as string | undefined;

    if (!apiKey) {
      throw new UnauthorizedException('X-API-Key header is required');
    }

    const result = await this.prisma.$queryRawUnsafe<
      {
        id: string;
        clubId: string;
        scopes: string[];
        isActive: boolean;
      }[]
    >(
      `SELECT id, "clubId", scopes, "isActive" FROM api_keys WHERE key = $1`,
      apiKey,
    );

    if (!result.length || !result[0].isActive) {
      throw new UnauthorizedException('Invalid or inactive API key');
    }

    const keyData = result[0];

    // Update lastUsedAt
    await this.prisma.$executeRawUnsafe(
      `UPDATE api_keys SET "lastUsedAt" = NOW() WHERE id = $1`,
      keyData.id,
    );

    request.user = {
      sub: `api-key:${keyData.id}`,
      clubId: keyData.clubId,
      role: 'api_key',
      scopes: keyData.scopes,
    };

    return true;
  }
}
