import { HttpError } from './errors.js';

export function createIpRateLimiter({ windowMs, max, message }) {
  const clients = new Map();

  return {
    check(ip) {
      const now = Date.now();
      const key = ip || 'unknown';
      const current = clients.get(key);
      const bucket = current && current.resetAt > now
        ? current
        : { count: 0, resetAt: now + windowMs };

      bucket.count += 1;
      clients.set(key, bucket);
      pruneExpired(clients, now);

      if (bucket.count > max) {
        const error = new HttpError(429, message || 'Rate limit exceeded.');
        error.retryAfterSeconds = Math.max(1, Math.ceil((bucket.resetAt - now) / 1000));
        error.rateLimit = {
          limit: max,
          remaining: 0,
          resetAt: new Date(bucket.resetAt).toISOString()
        };
        throw error;
      }

      return {
        limit: max,
        remaining: Math.max(0, max - bucket.count),
        resetAt: new Date(bucket.resetAt).toISOString()
      };
    }
  };
}

function pruneExpired(clients, now) {
  if (clients.size < 10_000) return;
  for (const [key, bucket] of clients) {
    if (bucket.resetAt <= now) clients.delete(key);
  }
}
