import { Request, Response, NextFunction } from "express";
import { User } from "../models/User";

interface RateLimitConfig {
  limit: number;
  windowMs: number;
}

const rateLimits: Record<string, RateLimitConfig> = {
  guest: { limit: 3, windowMs: 60 * 60 * 1000 }, // 3 req in 1 hour
  logged_in: { limit: 8, windowMs: 60 * 60 * 1000 }, // 8 req in 1 hour
  premium: { limit: 20, windowMs: 60 * 60 * 1000 }, // 20 req in 1 hour
};

const requestStore = new Map<string, { count: number; expiresAt: number }>();

export const throttleMiddleware = async (
  req: Request,
  res: Response,
  next: NextFunction
): Promise<void> => {
  try {
    const ip = req.ip || req.connection.remoteAddress || "unknown";
    const token = req.headers["authorization"];
    let userType: "guest" | "logged_in" | "premium" = "guest";
    let userId: string | null = null;

    if (token) {
      try {
        const user = await User.query().findById(token); // Replace with actual decoding
        if (user) {
          userType = user.is_premium;
          userId = String(user.id);
        }
      } catch (err: any) {
        console.error("User lookup failed:", err.message);
      }
    }

    const identifier = userId || ip;
    const { limit, windowMs } = rateLimits[userType];
    const now = Date.now();

    let userData = requestStore.get(identifier);

    if (!userData || now > userData.expiresAt) {
      userData = { count: 1, expiresAt: now + windowMs };
      requestStore.set(identifier, userData);
    } else {
      userData.count++;
      if (userData.count > limit) {
        const retryAfter = Math.ceil((userData.expiresAt - now) / 1000);
        res.status(429).json({
          message: `Too many requests. Try again in ${retryAfter} seconds.`,
        });
        return; // ✅ Important: return nothing (void)
      }
    }

    next();
  } catch (error) {
    console.error("Throttle error:", error);
    res.status(500).json({ message: "Internal server error" });
  }
};
