type RateLimitOptions = {
  route: string;
  windowMs: number;
  maxAttempts: number;
};

type RateLimitBucket = {
  count: number;
  resetAt: number;
};

const buckets = new Map<string, RateLimitBucket>();

function clientIp(request: Request) {
  const forwardedFor = request.headers.get("x-forwarded-for")?.split(",")[0]?.trim();
  const realIp = request.headers.get("x-real-ip")?.trim();
  return forwardedFor || realIp || "unknown";
}

function cleanupExpired(now: number) {
  for (const [key, bucket] of buckets.entries()) {
    if (bucket.resetAt <= now) buckets.delete(key);
  }
}

// In-memory per-process limiter for local/demo hardening.
// Production multi-instance/serverless deployments should use durable shared storage
// such as Redis, Upstash, Cloudflare/WAF rules, or provider-native rate limiting.
export function checkRateLimit(request: Request, options: RateLimitOptions) {
  const now = Date.now();
  cleanupExpired(now);

  const key = `${options.route}:${clientIp(request)}`;
  const current = buckets.get(key);

  if (!current || current.resetAt <= now) {
    buckets.set(key, { count: 1, resetAt: now + options.windowMs });
    return { allowed: true, retryAfterSeconds: 0 };
  }

  if (current.count >= options.maxAttempts) {
    return {
      allowed: false,
      retryAfterSeconds: Math.max(1, Math.ceil((current.resetAt - now) / 1000))
    };
  }

  current.count += 1;
  buckets.set(key, current);
  return { allowed: true, retryAfterSeconds: 0 };
}

export function isHoneypotFilled(value: FormDataEntryValue | string | null | undefined) {
  return typeof value === "string" && value.trim().length > 0;
}
