// server/middleware/rate-limit.ts

/**
 * Rate limiting middleware for auth endpoints
 *
 * Prevents brute force attacks on login/registration
 *
 * Limits:
 * - /api/auth/login: 5 attempts per 15 minutes per IP
 * - /api/auth/register: 3 attempts per hour per IP
 */

interface RateLimitEntry {
  count: number
  resetAt: number
}

// In-memory rate limit store (use Redis in production!)
const rateLimitStore = new Map<string, RateLimitEntry>()

// Clean up expired entries every 5 minutes
setInterval(
  () => {
    const now = Date.now()
    for (const [key, entry] of rateLimitStore.entries()) {
      if (entry.resetAt < now) {
        rateLimitStore.delete(key)
      }
    }
  },
  5 * 60 * 1000
)

export default defineEventHandler((event) => {
  const path = event.path

  // Only apply to auth endpoints
  if (!path.startsWith('/api/auth/')) {
    return
  }

  // Get client IP
  const ip = getRequestIP(event, { xForwardedFor: true }) || 'unknown'

  // Define rate limits per endpoint
  const limits: Record<string, { maxAttempts: number; windowMs: number }> = {
    '/api/auth/login': { maxAttempts: 5, windowMs: 15 * 60 * 1000 }, // 5 per 15min
    '/api/auth/register': { maxAttempts: 3, windowMs: 60 * 60 * 1000 }, // 3 per hour
  }

  const limit = limits[path]
  if (!limit) {
    return // No rate limit for this endpoint
  }

  // Check rate limit
  const key = `${ip}:${path}`
  const now = Date.now()
  const entry = rateLimitStore.get(key)

  if (!entry || entry.resetAt < now) {
    // First attempt or window expired - reset counter
    rateLimitStore.set(key, {
      count: 1,
      resetAt: now + limit.windowMs,
    })
    return
  }

  // Increment counter
  entry.count++

  if (entry.count > limit.maxAttempts) {
    // Rate limit exceeded
    const retryAfter = Math.ceil((entry.resetAt - now) / 1000)

    setResponseStatus(event, 429)
    setResponseHeader(event, 'Retry-After', retryAfter.toString())

    throw createError({
      statusCode: 429,
      statusMessage: 'Too many requests',
      data: {
        retryAfter,
        message: `Too many attempts. Please try again in ${retryAfter} seconds.`,
      },
    })
  }
})
