let Redis = null;
let Ratelimit = null;
let modulesLoaded = false;
let loadError = null;
let redisUnconfiguredLogged = false;
let redis = null;
let authRateLimiterInstance = null;
let apiRateLimiterInstance = null;
let strictRateLimiterInstance = null;
let readRateLimiterInstance = null;
let writeRateLimiterInstance = null;
let webhookRateLimiterInstance = null;
async function loadUpstashModules() {
  if (modulesLoaded) return !loadError;
  try {
    const [ratelimitModule, redisModule] = await Promise.all([
      import("@upstash/ratelimit"),
      import("@upstash/redis")
    ]);
    Ratelimit = ratelimitModule.Ratelimit;
    Redis = redisModule.Redis;
    if (process.env.UPSTASH_REDIS_REST_URL && process.env.UPSTASH_REDIS_REST_TOKEN) {
      redis = new Redis({
        url: process.env.UPSTASH_REDIS_REST_URL,
        token: process.env.UPSTASH_REDIS_REST_TOKEN
      });
      authRateLimiterInstance = new Ratelimit({
        redis,
        limiter: Ratelimit.slidingWindow(5, "15 m"),
        analytics: true,
        prefix: "ratelimit:auth",
        ephemeralCache: /* @__PURE__ */ new Map()
      });
      apiRateLimiterInstance = new Ratelimit({
        redis,
        limiter: Ratelimit.slidingWindow(100, "1 m"),
        analytics: true,
        prefix: "ratelimit:api",
        ephemeralCache: /* @__PURE__ */ new Map()
      });
      strictRateLimiterInstance = new Ratelimit({
        redis,
        limiter: Ratelimit.slidingWindow(10, "1 h"),
        analytics: true,
        prefix: "ratelimit:strict",
        ephemeralCache: /* @__PURE__ */ new Map()
      });
      readRateLimiterInstance = new Ratelimit({
        redis,
        limiter: Ratelimit.slidingWindow(200, "1 m"),
        analytics: true,
        prefix: "ratelimit:read",
        ephemeralCache: /* @__PURE__ */ new Map()
      });
      writeRateLimiterInstance = new Ratelimit({
        redis,
        limiter: Ratelimit.slidingWindow(50, "1 m"),
        analytics: true,
        prefix: "ratelimit:write",
        ephemeralCache: /* @__PURE__ */ new Map()
      });
      webhookRateLimiterInstance = new Ratelimit({
        redis,
        limiter: Ratelimit.slidingWindow(500, "1 h"),
        analytics: true,
        prefix: "ratelimit:webhook",
        ephemeralCache: /* @__PURE__ */ new Map()
      });
    }
    modulesLoaded = true;
    return true;
  } catch (error) {
    loadError = error;
    modulesLoaded = true;
    if (process.env.NODE_ENV !== "production") {
      console.warn("[RateLimit] Upstash modules not available, using fallback:", error.message);
    }
    return false;
  }
}
const authRateLimiter = null;
const apiRateLimiter = null;
const strictRateLimiter = null;
const DEFAULT_TIER_LIMITS = {
  auth: 5,
  api: 100,
  strict: 10,
  read: 200,
  write: 50,
  webhook: 500
};
async function checkRateLimit(identifier, type = "api") {
  await loadUpstashModules();
  const limiterMap = {
    auth: authRateLimiterInstance,
    api: apiRateLimiterInstance,
    strict: strictRateLimiterInstance,
    read: readRateLimiterInstance,
    write: writeRateLimiterInstance,
    webhook: webhookRateLimiterInstance
  };
  const limiter = limiterMap[type];
  if (!limiter) {
    if (!redisUnconfiguredLogged) {
      redisUnconfiguredLogged = true;
      console.error(
        "[RateLimit] CRITICAL: Rate limiting is DISABLED (Redis unavailable).",
        "Set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN to enable distributed rate limiting.",
        "All requests are currently allowed through without limit enforcement."
      );
    }
    return {
      success: true,
      remaining: DEFAULT_TIER_LIMITS[type],
      reset: Date.now() + 6e4,
      limit: DEFAULT_TIER_LIMITS[type]
    };
  }
  try {
    const result = await limiter.limit(identifier);
    const retryAfter = result.success ? void 0 : Math.ceil((result.reset - Date.now()) / 1e3);
    return {
      success: result.success,
      remaining: result.remaining,
      reset: result.reset,
      limit: result.limit,
      retryAfter
    };
  } catch (error) {
    console.error("[RateLimit] Redis error:", error);
    return {
      success: true,
      remaining: DEFAULT_TIER_LIMITS[type],
      reset: Date.now() + 6e4,
      limit: DEFAULT_TIER_LIMITS[type]
    };
  }
}
async function isRedisConfigured() {
  await loadUpstashModules();
  return redis !== null;
}
function maybeRedisConfigured() {
  return !!(process.env.UPSTASH_REDIS_REST_URL && process.env.UPSTASH_REDIS_REST_TOKEN);
}
function getRateLimitHeaders(result) {
  const headers = {
    "X-RateLimit-Remaining": String(result.remaining),
    "X-RateLimit-Reset": String(result.reset)
  };
  if (result.limit) {
    headers["X-RateLimit-Limit"] = String(result.limit);
  }
  if (result.retryAfter !== void 0 && result.retryAfter > 0) {
    headers["Retry-After"] = String(result.retryAfter);
  }
  return headers;
}
function createRateLimitResponse(result) {
  return new Response(
    JSON.stringify({
      error: "Too Many Requests",
      message: "Rate limit exceeded. Please try again later.",
      retryAfter: result.retryAfter
    }),
    {
      status: 429,
      headers: {
        "Content-Type": "application/json",
        ...getRateLimitHeaders(result)
      }
    }
  );
}
export {
  apiRateLimiter,
  authRateLimiter,
  checkRateLimit,
  createRateLimitResponse,
  getRateLimitHeaders,
  isRedisConfigured,
  maybeRedisConfigured,
  strictRateLimiter
};
