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

interface RequestWithHeaders {
  headers?: Record<string, string | string[]>;
  ip?: string;
  connection?: { remoteAddress?: string };
  url?: string;
}

/**
 * OrchestratorThrottlerGuard - Rate limiting guard for orchestrator API endpoints
 *
 * Uses the X-Forwarded-For header for client IP identification when behind a proxy,
 * falling back to the direct connection IP.
 *
 * Usage:
 * @UseGuards(OrchestratorThrottlerGuard)
 * @Controller('agents')
 * export class AgentsController { ... }
 */
@Injectable()
export class OrchestratorThrottlerGuard extends ThrottlerGuard {
  /**
   * Get the client IP address for rate limiting tracking
   * Prioritizes X-Forwarded-For header for proxy setups
   */
  protected getTracker(req: Record<string, unknown>): Promise<string> {
    const request = req as RequestWithHeaders;
    const headers = request.headers;

    // Check X-Forwarded-For header first (for proxied requests)
    if (headers) {
      const forwardedFor = headers["x-forwarded-for"];
      if (forwardedFor) {
        // Get the first IP in the chain (original client)
        const ips = Array.isArray(forwardedFor) ? forwardedFor[0] : forwardedFor;
        if (ips) {
          const clientIp = ips.split(",")[0]?.trim();
          if (clientIp) {
            return Promise.resolve(clientIp);
          }
        }
      }
    }

    // Fallback to direct connection IP
    const ip = request.ip ?? request.connection?.remoteAddress ?? "unknown";
    return Promise.resolve(ip);
  }

  /**
   * Custom error message for rate limit exceeded
   */
  protected throwThrottlingException(context: ExecutionContext): Promise<void> {
    const request = context.switchToHttp().getRequest<RequestWithHeaders>();
    const endpoint = request.url ?? "unknown";

    throw new ThrottlerException(
      `Rate limit exceeded for endpoint ${endpoint}. Please try again later.`
    );
  }
}
