/**
 * 速率限制纯函数与常量（audit-P1-6）
 *
 * 此文件仅包含与具体后端实现无关的纯函数和常量：
 * - `RATE_LIMIT_RULES`：常用场景的预定义规则
 * - `rateLimitKey`：限流 key 构造器
 * - `rateLimitHeaders`：将结果转换为标准 HTTP 限流响应头
 *
 * 这些函数不依赖任何后端实现，可在所有 runtime（含 edge）使用。
 */

import type { RateLimitResult } from "./types"

/**
 * 预定义的速率限制规则。
 *
 * 时间单位均为毫秒。
 */
export const RATE_LIMIT_RULES = {
  LOGIN: { limit: 5, windowMs: 15 * 60 * 1000 }, // 15 分钟内 5 次
  API: { limit: 100, windowMs: 60 * 1000 }, // 每分钟 100 次
  UPLOAD: { limit: 10, windowMs: 60 * 1000 }, // 每分钟 10 次
  AI_CHAT: { limit: 20, windowMs: 60 * 1000 }, // 每分钟 20 次
  PASSWORD_CHANGE: { limit: 5, windowMs: 60 * 1000 }, // 每分钟 5 次
  /**
   * audit-P1-8：家长绑定子女速率限制。
   *
   * 三因子验证（生日 365 × 手机后4 10000 = 3.65M 组合）虽然空间大，
   * 但单次 onboarding Action 内可循环调用 10 次（children.length ≤ 10），
   * 无独立速率限制时被撤销子女关系的家长可反复尝试枚举绑定。
   *
   * 限制每小时 5 次（5 次完整 onboarding 提交，每次最多 10 个子女 = 50 次尝试/小时），
   * 远低于枚举 3.65M 组合所需量级，同时不误伤正常用户（家长极少在 1 小时内反复提交）。
   */
  ONBOARDING_BIND: { limit: 5, windowMs: 60 * 60 * 1000 }, // 每小时 5 次
} as const

/**
 * 由前缀与标识符构造限流 key。
 *
 * 例如 `rateLimitKey("login", "1.2.3.4:user@example.com")` -> `"login:1.2.3.4:user@example.com"`。
 */
export function rateLimitKey(prefix: string, identifier: string): string {
  return `${prefix}:${identifier}`
}

/**
 * 将限流结果转换为标准 HTTP 限流响应头。
 *
 * 符合 IETF draft-ietf-httpapi-ratelimit-headers 规范：
 * - `X-RateLimit-Limit`：窗口内最大次数
 * - `X-RateLimit-Remaining`：剩余可用次数
 * - `X-RateLimit-Reset`：窗口重置时间（Unix 秒）
 * - `Retry-After`：失败时距重置的秒数
 */
export function rateLimitHeaders(
  result: RateLimitResult,
): Record<string, string> {
  return {
    "X-RateLimit-Limit": String(result.remaining + (result.success ? 1 : 0)),
    "X-RateLimit-Remaining": String(result.remaining),
    "X-RateLimit-Reset": String(Math.ceil(result.resetTime / 1000)),
    ...(result.success
      ? {}
      : { "Retry-After": String(Math.ceil(result.retryAfterMs / 1000)) }),
  }
}
