const jwt = require('jsonwebtoken');
const User = require('../models/User');

const protect = async (req, res, next) => {
    let token;

    // 1. Try to get token from Authorization header
    if (req.headers.authorization && req.headers.authorization.startsWith('Bearer')) {
        token = req.headers.authorization.split(' ')[1];
    }
    // 2. Try to get token from cookies (if used)
    else if (req.cookies && req.cookies.token) {
        token = req.cookies.token;
    }
    // 3. Try to get token from request body (used by navigator.sendBeacon which cannot set headers)
    else if (req.body && req.body._token) {
        token = req.body._token;
    }

    // Validation: Missing token
    if (!token) {
        return res.status(401).json({ message: 'No token provided' });
    }

    // Validation: Malformed JWT (must have 2 dots)
    if (token.split('.').length !== 3) {
        return res.status(401).json({ message: 'Malformed token' });
    }

    try {
        // 🔓 Try the current strong JWT_SECRET first
        let decoded;
        try {
            decoded = jwt.verify(token, process.env.JWT_SECRET);
        } catch (primaryErr) {
            // 🛟 Fallback: accept tokens signed with the legacy secret (old mobile apps)
            // Set JWT_SECRET_LEGACY in env to enable. Remove once all clients have re-logged in.
            const legacy = process.env.JWT_SECRET_LEGACY;
            if (legacy && legacy.length > 0) {
                try {
                    decoded = jwt.verify(token, legacy);
                } catch (legacyErr) {
                    throw primaryErr; // both failed — original error wins
                }
            } else {
                throw primaryErr;
            }
        }

        req.user = await User.findById(decoded.userId).select('-password');

        if (!req.user) {
            return res.status(401).json({ message: 'المستخدم غير موجود' });
        }

        if (!req.user.isActive) {
            return res.status(403).json({ message: 'حسابك موقوف. يرجى التواصل مع الإدارة.' });
        }

        // 🔒 Security: Verify role consistency between JWT and DB
        if (decoded.role && decoded.role !== req.user.role) {
            return res.status(401).json({ message: 'Token role mismatch — please login again' });
        }

        // 🔒 Security: Check scope for restricted tokens (e.g. upload_only)
        if (decoded.scope && decoded.scope !== 'full') {
            const allowedPaths = ['/api/auth/upload-documents'];
            if (!allowedPaths.some(p => req.originalUrl.includes(p))) {
                return res.status(403).json({ message: 'هذا التوكن مقيّد بمهام محددة فقط' });
            }
        }

        next();
    } catch (error) {
        // Return 401 instead of throwing
        return res.status(401).json({ message: 'Invalid or expired token' });
    }
};

// ==========================================
// 🔒 Role-Based Access Middleware
// ==========================================

const adminOnly = (req, res, next) => {
    if (req.user && req.user.role === 'admin') {
        next();
    } else {
        res.status(403).json({ message: 'غير مصرح، هذه الصلاحية للمسؤولين فقط' });
    }
};

const captainOnly = (req, res, next) => {
    if (req.user && req.user.role === 'captain') {
        next();
    } else {
        res.status(403).json({ message: 'غير مصرح، هذه الصلاحية للكباتن فقط' });
    }
};

const clientOnly = (req, res, next) => {
    if (req.user && (req.user.role === 'client' || req.user.role === 'customer')) {
        next();
    } else {
        res.status(403).json({ message: 'غير مصرح، هذه الصلاحية للعملاء فقط' });
    }
};

const merchantOnly = (req, res, next) => {
    if (req.user && req.user.role === 'merchant') {
        next();
    } else {
        res.status(403).json({ message: 'غير مصرح، هذه الصلاحية للتجار فقط' });
    }
};

module.exports = { protect, adminOnly, captainOnly, clientOnly, merchantOnly };