import { prisma } from "./prisma";

type RateLimitResult = {
  ok: boolean;
  remaining: number;
  resetAt: Date;
};

const parseNumber = (value: string | undefined, fallback: number) => {
  if (!value) return fallback;
  const parsed = Number(value);
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
};

export const getRateLimitConfig = (envKey: string, defaultLimit: number) => {
  const limit = parseNumber(process.env[envKey], defaultLimit);
  const windowMinutes = parseNumber(process.env.RATE_LIMIT_WINDOW_MINUTES, 15);
  return { limit, windowMs: windowMinutes * 60 * 1000 };
};

export async function checkRateLimit({
  key,
  limit,
  windowMs
}: {
  key: string;
  limit: number;
  windowMs: number;
}): Promise<RateLimitResult> {
  const now = new Date();
  const resetAt = new Date(now.getTime() + windowMs);

  const existing = await prisma.rateLimit.findUnique({ where: { key } });
  if (!existing || existing.resetAt <= now) {
    await prisma.rateLimit.upsert({
      where: { key },
      update: { count: 1, resetAt },
      create: { key, count: 1, resetAt }
    });
    return { ok: true, remaining: Math.max(0, limit - 1), resetAt };
  }

  if (existing.count >= limit) {
    return { ok: false, remaining: 0, resetAt: existing.resetAt };
  }

  const updated = await prisma.rateLimit.update({
    where: { key },
    data: { count: { increment: 1 } }
  });

  return {
    ok: true,
    remaining: Math.max(0, limit - updated.count),
    resetAt: updated.resetAt
  };
}
