/**
 * In-memory rate limiter for auth endpoints.
 * Uses a sliding window approach per IP address.
 *
 * For production at scale, replace with Redis-backed (e.g. Upstash).
 * This in-memory implementation works for single-instance deployments.
 */

interface RateLimitEntry {
  count: number;
  resetAt: number;
}

const store = new Map<string, RateLimitEntry>();

// Cleanup stale entries every 5 minutes
setInterval(() => {
  const now = Date.now();
  for (const [key, entry] of store) {
    if (now > entry.resetAt) {
      store.delete(key);
    }
  }
}, 5 * 60 * 1000);

export interface RateLimitConfig {
  /** Max requests within the window */
  max: number;
  /** Window duration in seconds */
  windowSeconds: number;
}

export interface RateLimitResult {
  allowed: boolean;
  remaining: number;
  resetAt: number;
}

/**
 * Check rate limit for a given key (typically IP + endpoint).
 */
export function checkRateLimit(key: string, config: RateLimitConfig): RateLimitResult {
  const now = Date.now();
  const entry = store.get(key);

  if (!entry || now > entry.resetAt) {
    // New window
    store.set(key, { count: 1, resetAt: now + config.windowSeconds * 1000 });
    return { allowed: true, remaining: config.max - 1, resetAt: now + config.windowSeconds * 1000 };
  }

  if (entry.count >= config.max) {
    return { allowed: false, remaining: 0, resetAt: entry.resetAt };
  }

  entry.count++;
  return { allowed: true, remaining: config.max - entry.count, resetAt: entry.resetAt };
}

/**
 * Extract client IP from request headers (works behind reverse proxy).
 */
export function getClientIp(headers: Headers): string {
  return (
    headers.get("x-forwarded-for")?.split(",")[0]?.trim() ||
    headers.get("x-real-ip") ||
    "unknown"
  );
}

// Pre-defined rate limit configs for auth endpoints
export const AUTH_RATE_LIMITS = {
  register: { max: 5, windowSeconds: 900 } as RateLimitConfig,       // 5 per 15 min
  login: { max: 10, windowSeconds: 900 } as RateLimitConfig,         // 10 per 15 min
  forgotPassword: { max: 3, windowSeconds: 3600 } as RateLimitConfig, // 3 per hour
  resetPassword: { max: 5, windowSeconds: 900 } as RateLimitConfig,  // 5 per 15 min
  resendVerification: { max: 3, windowSeconds: 3600 } as RateLimitConfig, // 3 per hour
  verifyEmail: { max: 10, windowSeconds: 900 } as RateLimitConfig,   // 10 per 15 min
} as const;
