import { Injectable, ExecutionContext } from "@nestjs/common";
import { ThrottlerGuard, ThrottlerException } from "@nestjs/throttler";
import { Request } from "express";

/**
 * Custom ThrottlerGuard that tracks rate limits by API key instead of IP
 *
 * This guard extracts the API key from the X-API-Key header and uses it
 * as the tracking key for rate limiting. This ensures that different API
 * keys have independent rate limits.
 */
@Injectable()
export class ThrottlerApiKeyGuard extends ThrottlerGuard {
  /**
   * Generate tracking key based on API key from X-API-Key header
   *
   * If no API key is present, falls back to IP-based tracking.
   */
  protected getTracker(req: Request): Promise<string> {
    const apiKey = req.headers["x-api-key"] as string | undefined;

    if (apiKey) {
      // Track by API key
      return Promise.resolve(`apikey:${apiKey}`);
    }

    // Fallback to IP tracking
    const ip = req.ip ?? req.socket.remoteAddress ?? "unknown";
    return Promise.resolve(`ip:${ip}`);
  }

  /**
   * Override to add custom error handling and logging
   */
  protected async throwThrottlingException(context: ExecutionContext): Promise<void> {
    const request = context.switchToHttp().getRequest<Request>();
    const tracker = await this.getTracker(request);

    // Log rate limit violations for security monitoring
    console.warn(`Rate limit exceeded for ${tracker} on ${request.method} ${request.url}`);

    throw new ThrottlerException("Rate limit exceeded. Please try again later.");
  }
}
