import { logger } from '@goodgo/logger';
import { Request, Response, NextFunction } from 'express';
import rateLimit from 'express-rate-limit';

import { rbacService } from '../modules/rbac/rbac.service';

/**
 * EN: Pre-configured rate limiters for different user tiers
 * VI: Rate limiters được cấu hình trước cho các cấp độ người dùng khác nhau
 */
const superAdminLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 1000,
  standardHeaders: true,
  legacyHeaders: false,
  handler: (_req, res) => {
    res.status(429).json({
      success: false,
      error: {
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Too many requests, please try again later',
      },
    });
  },
});

const adminLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 500,
  standardHeaders: true,
  legacyHeaders: false,
  handler: (_req, res) => {
    res.status(429).json({
      success: false,
      error: {
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Too many requests, please try again later',
      },
    });
  },
});

const moderatorLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 300,
  standardHeaders: true,
  legacyHeaders: false,
  handler: (_req, res) => {
    res.status(429).json({
      success: false,
      error: {
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Too many requests, please try again later',
      },
    });
  },
});

const userLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
  standardHeaders: true,
  legacyHeaders: false,
  handler: (_req, res) => {
    res.status(429).json({
      success: false,
      error: {
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Too many requests, please try again later',
      },
    });
  },
});

const guestLimiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 50,
  standardHeaders: true,
  legacyHeaders: false,
  handler: (_req, res) => {
    res.status(429).json({
      success: false,
      error: {
        code: 'RATE_LIMIT_EXCEEDED',
        message: 'Too many requests, please try again later',
      },
    });
  },
});

/**
 * EN: Dynamic rate limiting based on user role
 * VI: Giới hạn tốc độ động dựa trên vai trò người dùng
 */
export const dynamicRateLimit = async (
  req: Request,
  res: Response,
  next: NextFunction
): Promise<void> => {
  try {
    const userId = (req as any).user?.id || (req as any).user?.sub;

    let limiter = guestLimiter;

    if (userId) {
      // Get user roles
      const roles = await rbacService.getUserRoles(userId);

      // Select limiter based on role
      if (roles.includes('SUPER_ADMIN')) {
        limiter = superAdminLimiter;
      } else if (roles.includes('ADMIN')) {
        limiter = adminLimiter;
      } else if (roles.includes('MODERATOR')) {
        limiter = moderatorLimiter;
      } else {
        limiter = userLimiter;
      }
    }

    // Apply selected rate limiter
    limiter(req, res, next);
  } catch (error) {
    logger.error('Rate limit middleware error', { error });
    // Continue on error (don't block requests)
    next();
  }
};
