import { HttpStatus, Injectable } from '@nestjs/common';
import { ThrottlerGuard } from '@nestjs/throttler';
import { AppException, ErrorCode } from '../../common/errors';

/**
 * Rate limits voice extraction per user, not per IP: the default tracker keys on `req.ip`,
 * which behind nginx means the whole deployment shares one bucket unless `trust proxy` is
 * set, and one clinic could then lock out every other.
 */
@Injectable()
export class VoiceThrottlerGuard extends ThrottlerGuard {
  protected getTracker(req: Record<string, unknown>): Promise<string> {
    const user = req?.user as { id?: unknown } | undefined;
    if (typeof user?.id === 'string' && user.id) {
      return Promise.resolve(`voice:user:${user.id}`);
    }
    // Unauthenticated requests never reach here, but fall back rather than share a bucket.
    const ip = typeof req?.ip === 'string' ? req.ip : 'unknown';
    return Promise.resolve(`voice:ip:${ip}`);
  }

  /** Without this, ThrottlerException surfaces as INTERNAL_ERROR — there is no 429 fallback. */
  protected throwThrottlingException(): Promise<void> {
    throw new AppException(
      ErrorCode.VOICE_RATE_LIMITED,
      HttpStatus.TOO_MANY_REQUESTS,
    );
  }
}
