const rateLimit = require('express-rate-limit');

// In-memory store for per-recipient email tracking
const emailTracker = new Map();

// Helper function to clean up expired entries
function cleanupExpiredEntries() {
  const now = Date.now();
  for (const [key, timestamp] of emailTracker.entries()) {
    if (now - timestamp > 5 * 60 * 1000) { // 5 minutes
      emailTracker.delete(key);
    }
  }
}

// Clean up expired entries every minute
setInterval(cleanupExpiredEntries, 60 * 1000);

// General API rate limiter
const general = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per windowMs
  message: {
    error: 'Too many requests from this IP, please try again later.',
    retryAfter: 15 * 60 // 15 minutes in seconds
  },
  standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
  legacyHeaders: false, // Disable the `X-RateLimit-*` headers
  // Use a custom key generator that's safer with trust proxy
  keyGenerator: (req) => {
    // Fallback to connection remote address if req.ip is not available
    return req.ip || req.connection?.remoteAddress || 'unknown';
  },
});

// Email sending rate limiter (general - keeps existing behavior)
const email = rateLimit({
  windowMs: 60 * 60 * 1000, // 1 hour
  max: 10, // limit each IP to 10 emails per hour
  message: {
    error: 'Too many emails sent from this IP, please try again later.',
    retryAfter: 60 * 60 // 1 hour in seconds
  },
  standardHeaders: true,
  legacyHeaders: false,
  skipSuccessfulRequests: false, // Don't skip counting successful requests
  // Use a custom key generator that's safer with trust proxy
  keyGenerator: (req) => {
    // Fallback to connection remote address if req.ip is not available
    return req.ip || req.connection?.remoteAddress || 'unknown';
  },
});

// Custom middleware for per-recipient email rate limiting
const perRecipientEmailLimiter = (req, res, next) => {
  const clientIp = req.ip || req.connection?.remoteAddress || 'unknown';
  const recipientEmail = req.body.recipientEmail;
  
  if (!recipientEmail) {
    return next(); // Let validation middleware handle missing recipient
  }
  
  const trackingKey = `${clientIp}:${recipientEmail}`;
  const now = Date.now();
  const lastSent = emailTracker.get(trackingKey);
  
  if (lastSent && (now - lastSent) < 5 * 60 * 1000) { // 5 minutes
    const timeRemaining = Math.ceil((5 * 60 * 1000 - (now - lastSent)) / 1000);
    return res.status(429).json({
      success: false,
      error: 'Rate limit exceeded',
      message: `You can only send one email per representative every 5 minutes. Please wait ${Math.ceil(timeRemaining / 60)} more minutes before sending another email to this representative.`,
      retryAfter: timeRemaining,
      rateLimitType: 'per-recipient'
    });
  }
  
  // Store the current timestamp for this IP-recipient combination
  emailTracker.set(trackingKey, now);
  next();
};

// Represent API rate limiter (more restrictive)
const representAPI = rateLimit({
  windowMs: 60 * 1000, // 1 minute
  max: 60, // match the Represent API limit of 60 requests per minute
  message: {
    error: 'Represent API rate limit exceeded, please try again later.',
    retryAfter: 60 // 1 minute in seconds
  },
  standardHeaders: true,
  legacyHeaders: false,
  // Use a custom key generator that's safer with trust proxy
  keyGenerator: (req) => {
    // Fallback to connection remote address if req.ip is not available
    return req.ip || req.connection?.remoteAddress || 'unknown';
  },
});

module.exports = {
  general,
  email,
  perRecipientEmailLimiter,
  representAPI
};