// rate-limiter.ts — Sliding window rate limiter
// v1: Claude (initial implementation with known TODOs)
// v2: ChatGPT (fixed memory leak, added response metadata, cleanup interval)

interface RateLimitConfig {
  windowMs: number;
  maxRequests: number;
}

interface RateLimitResult {
  limited: boolean;
  remaining: number;
  resetMs: number;
  retryAfterMs: number | null;
}

const store = new Map<string, number[]>();

// Fix: periodic cleanup of expired keys (was: memory leak)
const CLEANUP_INTERVAL = 60_000;
setInterval(() => {
  const now = Date.now();
  for (const [key, timestamps] of store) {
    const recent = timestamps.filter(t => t > now - 3_600_000); // keep 1hr max
    if (recent.length === 0) {
      store.delete(key);
    } else {
      store.set(key, recent);
    }
  }
}, CLEANUP_INTERVAL);

export function checkRateLimit(key: string, config: RateLimitConfig): RateLimitResult {
  const now = Date.now();
  const windowStart = now - config.windowMs;

  const timestamps = (store.get(key) || []).filter(t => t > windowStart);
  const remaining = Math.max(0, config.maxRequests - timestamps.length);
  const oldestInWindow = timestamps[0] || now;
  const resetMs = oldestInWindow + config.windowMs - now;

  if (timestamps.length >= config.maxRequests) {
    store.set(key, timestamps);
    return {
      limited: true,
      remaining: 0,
      resetMs,
      retryAfterMs: resetMs,
    };
  }

  timestamps.push(now);
  store.set(key, timestamps);

  return {
    limited: false,
    remaining: remaining - 1,
    resetMs: config.windowMs,
    retryAfterMs: null,
  };
}
