const WINDOW_MS = 10 * 60 * 1000;
const MAX_ATTEMPTS = 8;
const BLOCK_MS = 15 * 60 * 1000;

const attempts = new Map();

const getKey = (req) => {
    const ip = req.ip || req.headers['x-forwarded-for'] || req.connection?.remoteAddress || 'unknown';
    const username = String(req.body?.username || '').trim().toLowerCase();
    return `${ip}:${username}`;
};

const pruneOldEntries = (now) => {
    for (const [key, entry] of attempts.entries()) {
        const windowExpired = now - entry.windowStart > WINDOW_MS;
        const blockExpired = !entry.blockedUntil || now >= entry.blockedUntil;

        if (windowExpired && blockExpired) {
            attempts.delete(key);
        }
    }
};

const loginRateLimit = (req, res, next) => {
    const now = Date.now();
    pruneOldEntries(now);

    const key = getKey(req);
    const entry = attempts.get(key) || {
        count: 0,
        windowStart: now,
        blockedUntil: 0
    };

    if (entry.blockedUntil && now < entry.blockedUntil) {
        const retryAfterSeconds = Math.ceil((entry.blockedUntil - now) / 1000);
        return res.status(429).json({
            success: false,
            title: 'Too Many Attempts',
            msg: 'Too many login attempts. Please try again later.',
            data: null,
            retryAfterSeconds
        });
    }

    if (now - entry.windowStart > WINDOW_MS) {
        entry.count = 0;
        entry.windowStart = now;
        entry.blockedUntil = 0;
    }

    entry.count += 1;

    if (entry.count > MAX_ATTEMPTS) {
        entry.blockedUntil = now + BLOCK_MS;
        attempts.set(key, entry);

        return res.status(429).json({
            success: false,
            title: 'Too Many Attempts',
            msg: 'Too many login attempts. Please try again later.',
            data: null,
            retryAfterSeconds: Math.ceil(BLOCK_MS / 1000)
        });
    }

    attempts.set(key, entry);
    return next();
};

loginRateLimit.clearForRequest = (req) => {
    const key = getKey(req);
    attempts.delete(key);
};

module.exports = loginRateLimit;
