/**
 * @copyright 2026 NHCarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */

import { FastifyPluginAsync } from "fastify";
import fastifyPlugin from "fastify-plugin";
import fastifyRateLimit from "@fastify/rate-limit";
import { AuditService } from "../services/audit.service";
import { AuditAction, AuditCategory } from "@library/shared-types";

const rateLimitPlugin: FastifyPluginAsync = async (app) => {
  await app.register(fastifyRateLimit, {
    max: async (request) => {
      // Try to get user from JWT
      try {
        await request.jwtVerify();
        // Authenticated users get higher limits
        return 500;
      } catch {
        // Unauthenticated users get lower limits
        return 100;
      }
    },
    timeWindow: "1 minute",
    allowList: async (request) => {
      // Bypass rate limiting entirely for admin users
      try {
        await request.jwtVerify();
        return request.user?.isAdmin === true;
      } catch {
        return false;
      }
    },
    errorResponseBuilder: (request) => {
      // Log rate limit exceeded event
      AuditService.log({
        action: AuditAction.rateLimitExceeded,
        category: AuditCategory.security,
        details: `Rate limit exceeded for URL: ${request.url}`,
        success: false,
      }, request).catch(() => {
        // Ignore logging errors to avoid blocking the response
      });

      return {
        statusCode: 429,
        error: "Too Many Requests",
        message: "You have exceeded the rate limit. Please try again later.",
      };
    },
  });
};

export default fastifyPlugin(rateLimitPlugin);
