import { AuthenticatedSocket } from "@/types/index.js";

type RateLimitData = {
  count: number;
  resetTime: number;
};

class RateLimiter {
  private limits = new Map<string, RateLimitData>();
  private readonly maxMessages: number;
  private readonly windowMs: number;

  constructor(maxMessages = 10, windowMs = 60000) {
    this.maxMessages = maxMessages;
    this.windowMs = windowMs;
  }

  checkLimit(userId: string) {
    const now = Date.now();
    const userLimit = this.limits.get(userId) ?? { count: 0, resetTime: now + this.windowMs };

    if (now > userLimit.resetTime) {
      userLimit.count = 0;
      userLimit.resetTime = now + this.windowMs;
    }

    userLimit.count++;
    this.limits.set(userId, userLimit);

    return userLimit.count <= this.maxMessages;
  }

  getRemainingTime(userId: string) {
    const userLimit = this.limits.get(userId);
    if (!userLimit) return 0;

    return Math.max(0, userLimit.resetTime - Date.now());
  }
}

export const messageRateLimiter = new RateLimiter(10, 60000); // 10 messages per minute

export const checkMessageRateLimit = (socket: AuthenticatedSocket) => {
  const canSend = messageRateLimiter.checkLimit(socket.userId);

  if (!canSend) {
    const remainingTime = messageRateLimiter.getRemainingTime(socket.userId);

    socket.emit("rate_limit_exceeded", {
      message: `Too many messages. Please wait ${Math.ceil(remainingTime / 1000)} seconds before sending another message.`,
      remainingTime,
    });
  }

  return canSend;
};
