/**
 * In-memory sliding-window rate limiter.
 *
 * This is correct *because* there is exactly one process (PLANNING.md §2, §10):
 * no cluster, no PM2, no Redis. State is a Map of hit timestamps per key, pruned
 * on read. It resets when the process restarts — acceptable for abuse
 * throttling, where a brief window reset after a deploy is harmless.
 *
 * Used by the enquiry flow (§9: 5/hour + 20/day per IP hash) and, from step 4,
 * by admin login (per-IP + per-phone).
 */
export interface LimiterResult {
  allowed: boolean;
  /** Seconds until the oldest hit in the window expires (0 when allowed). */
  retryAfterSec: number;
  remaining: number;
}

export interface WindowLimiter {
  hit(key: string, limit: number, windowMs: number): LimiterResult;
  /** Drop a key's history — e.g. after a successful login. */
  reset(key: string): void;
}

export function createWindowLimiter(): WindowLimiter {
  const hits = new Map<string, number[]>();

  return {
    hit(key, limit, windowMs) {
      const now = Date.now();
      const cutoff = now - windowMs;
      const recent = (hits.get(key) ?? []).filter((t) => t > cutoff);

      if (recent.length >= limit) {
        hits.set(key, recent);
        const retryAfterSec = Math.max(1, Math.ceil((recent[0] + windowMs - now) / 1000));
        return { allowed: false, retryAfterSec, remaining: 0 };
      }

      recent.push(now);
      hits.set(key, recent);
      return { allowed: true, retryAfterSec: 0, remaining: limit - recent.length };
    },

    reset(key) {
      hits.delete(key);
    },
  };
}
