// Einfacher In-Memory-Rate-Limiter (ein Container, eine Instanz → genügt).
// Fixed-Window pro Schlüssel (Standard: Client-IP). Bei Überschreitung 429.
// Hinter einem Reverse-Proxy liefert X-Forwarded-For die echte IP.

const buckets = new Map(); // key -> { count, reset }

function clientIp(c) {
  const xff = c.req.header('x-forwarded-for');
  if (xff) return xff.split(',')[0].trim();
  return c.req.header('x-real-ip') || 'unknown';
}

// max Anfragen je windowMs. keyFn erlaubt eigene Schlüssel (z.B. IP+E-Mail).
export function rateLimit({ max = 10, windowMs = 60_000, keyFn = clientIp } = {}) {
  return async (c, next) => {
    const key = keyFn(c);
    const now = Date.now();
    let b = buckets.get(key);
    if (!b || now > b.reset) { b = { count: 0, reset: now + windowMs }; buckets.set(key, b); }
    b.count += 1;
    if (b.count > max) {
      const retry = Math.ceil((b.reset - now) / 1000);
      c.header('Retry-After', String(retry));
      return c.json({ error: 'Zu viele Anfragen — bitte später erneut.' }, 429);
    }
    await next();
  };
}

// Speicher sauber halten: abgelaufene Buckets periodisch wegräumen.
setInterval(() => {
  const now = Date.now();
  for (const [k, b] of buckets) if (now > b.reset) buckets.delete(k);
}, 5 * 60_000).unref?.();
