import { Request, Response, NextFunction } from 'express';
import { getUserById } from './userStore.js';

// ============================================================
//  Auth Middleware — Session-based avec vérification passwordChangedAt
// ============================================================

/**
 * Middleware d'authentification.
 * Vérifie que l'utilisateur est connecté ET que sa session n'a pas été
 * invalidée par un changement de mot de passe.
 */
const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
    const session = req.session as any;

    if (!session.user || !session.user.id) {
        return res.status(401).json({ error: "Non autorisé. Veuillez vous connecter." });
    }

    // Bloquer les APIs si changement de mot de passe requis
    if (session.user.mustChangePassword && req.path !== '/api/change-password' && req.path !== '/api/logout') {
        return res.status(403).json({ error: "Changement de mot de passe obligatoire.", mustChangePassword: true });
    }

    // Vérifier que le user existe encore et que le password n'a pas changé depuis le login
    const user = getUserById(session.user.id);
    if (!user) {
        // User supprimé depuis le login → détruire la session
        session.destroy(() => {});
        return res.status(401).json({ error: "Session invalide. Veuillez vous reconnecter." });
    }

    // Comparer loginAt avec passwordChangedAt — si le password a changé après le login, invalider
    if (session.user.loginAt && user.passwordChangedAt) {
        const loginTime = new Date(session.user.loginAt).getTime();
        const passwordChangeTime = new Date(user.passwordChangedAt).getTime();
        if (passwordChangeTime > loginTime) {
            session.destroy(() => {});
            return res.status(401).json({ error: "Votre mot de passe a été modifié. Veuillez vous reconnecter." });
        }
    }

    next();
};

/**
 * Middleware admin.
 * Doit être utilisé APRÈS authMiddleware (session.user déjà vérifié).
 * Vérifie que l'utilisateur a le rôle admin.
 */
export const requireAdmin = (req: Request, res: Response, next: NextFunction) => {
    const session = req.session as any;

    if (!session.user || session.user.role !== 'admin') {
        return res.status(403).json({ error: "Accès refusé. Droits administrateur requis." });
    }

    next();
};

/**
 * Middleware de vue d'authentification.
 * Identique à authMiddleware mais redirige vers /login au lieu de retourner du JSON.
 */
export const viewAuthMiddleware = (req: Request, res: Response, next: NextFunction) => {
    const session = req.session as any;

    if (!session.user || !session.user.id) {
        return res.redirect('/login');
    }

    // Même vérification passwordChangedAt
    const user = getUserById(session.user.id);
    if (!user) {
        session.destroy(() => {});
        return res.redirect('/login');
    }

    if (session.user.loginAt && user.passwordChangedAt) {
        const loginTime = new Date(session.user.loginAt).getTime();
        const passwordChangeTime = new Date(user.passwordChangedAt).getTime();
        if (passwordChangeTime > loginTime) {
            session.destroy(() => {});
            return res.redirect('/login');
        }
    }

    next();
};

/**
 * Middleware de vue exigeant le rôle admin.
 * Redirige les non-admins vers /trending en déposant un cookie d'erreur.
 */
export const viewRequireAdmin = (req: Request, res: Response, next: NextFunction) => {
    const session = req.session as any;

    if (!session.user || session.user.role !== 'admin') {
        res.cookie('authError', "Accès refusé. Droits administrateur requis.", { maxAge: 10000 });
        return res.redirect('/trending');
    }

    next();
};

export default authMiddleware;
