import { timingSafeEqual } from 'crypto';
import { NextRequest } from 'next/server';

const adminWindows = new Map<string, { count: number; resetAt: number }>();

export function checkAdminLimit(ip: string): boolean {
  const now = Date.now();

  // Purge stale entries to prevent unbounded Map growth
  if (adminWindows.size > 5000) {
    for (const [k, v] of adminWindows) {
      if (now > v.resetAt) adminWindows.delete(k);
    }
  }

  const win = adminWindows.get(ip);
  if (!win || now > win.resetAt) {
    adminWindows.set(ip, { count: 1, resetAt: now + 60_000 });
    return true;
  }
  if (win.count >= 10) return false;
  win.count++;
  return true;
}

export function checkAuth(req: NextRequest): boolean {
  const secret = process.env.ADMIN_SECRET;
  if (!secret) return false;
  const header = req.headers.get('authorization');
  if (!header) return false;
  const expected = `Bearer ${secret}`;
  // Constant-time comparison to prevent timing attacks
  if (header.length !== expected.length) return false;
  return timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}

export function getClientIp(req: NextRequest): string {
  // Use last hop from XFF — less gameable than first hop on a single-proxy setup
  const xff = req.headers.get('x-forwarded-for');
  if (xff) {
    const parts = xff.split(',');
    return parts[parts.length - 1].trim();
  }
  return '0.0.0.0';
}
