/**
 * Rate Limiting simples em memoria para APIs de maquina.
 * Adequado para VPS single-node. Para escalar horizontalmente,
 * considerar usar Redis ou outro store distribuido.
 */

type RateLimitEntry = {
  count: number
  resetAt: number
}

// Store em memoria - limpo automaticamente
const store = new Map<string, RateLimitEntry>()

export type RateLimitResult = {
  allowed: boolean
  remaining: number
  resetAt: number
  retryAfterMs: number
}

/**
 * Verifica se uma requisicao deve ser permitida baseado no rate limit.
 *
 * @param key - Identificador unico (ex: `chat-poll:${token}`)
 * @param maxRequests - Numero maximo de requisicoes permitidas na janela
 * @param windowMs - Tamanho da janela em milissegundos
 * @returns Resultado com status e informacoes de limite
 */
export function checkRateLimit(
  key: string,
  maxRequests: number,
  windowMs: number
): RateLimitResult {
  const now = Date.now()
  const entry = store.get(key)

  // Se nao existe entrada ou expirou, criar nova
  if (!entry || entry.resetAt <= now) {
    const resetAt = now + windowMs
    store.set(key, { count: 1, resetAt })
    return {
      allowed: true,
      remaining: maxRequests - 1,
      resetAt,
      retryAfterMs: 0,
    }
  }

  // Se atingiu o limite
  if (entry.count >= maxRequests) {
    return {
      allowed: false,
      remaining: 0,
      resetAt: entry.resetAt,
      retryAfterMs: entry.resetAt - now,
    }
  }

  // Incrementar contador
  entry.count++
  return {
    allowed: true,
    remaining: maxRequests - entry.count,
    resetAt: entry.resetAt,
    retryAfterMs: 0,
  }
}

/**
 * Limites pre-definidos para APIs de maquina
 */
export const RATE_LIMITS = {
  // Polling: 60 req/min (permite polling a cada 1s)
  CHAT_POLL: { maxRequests: 60, windowMs: 60_000 },
  // Mensagens: 30 req/min
  CHAT_MESSAGES: { maxRequests: 30, windowMs: 60_000 },
  // Sessoes: 30 req/min
  CHAT_SESSIONS: { maxRequests: 30, windowMs: 60_000 },
  // Upload: 10 req/min
  CHAT_UPLOAD: { maxRequests: 10, windowMs: 60_000 },
} as const

/**
 * Gera headers de rate limit para a resposta HTTP
 */
export function rateLimitHeaders(result: RateLimitResult): Record<string, string> {
  return {
    "X-RateLimit-Remaining": String(result.remaining),
    "X-RateLimit-Reset": String(Math.ceil(result.resetAt / 1000)),
    ...(result.allowed ? {} : { "Retry-After": String(Math.ceil(result.retryAfterMs / 1000)) }),
  }
}

// Limpar entradas expiradas a cada 60 segundos
if (typeof setInterval !== "undefined") {
  setInterval(() => {
    const now = Date.now()
    for (const [key, entry] of store) {
      if (entry.resetAt <= now) {
        store.delete(key)
      }
    }
  }, 60_000)
}
