import jwt from 'jsonwebtoken';
import { User } from '../models/index.js';

const getPermissions = (user) => {
    if (typeof user.permissions !== 'string') {
        return user.permissions;
    }

    try {
        return JSON.parse(user.permissions);
    } catch (error) {
        return {};
    }
};

const isAllowed = (value) => value === true || value === 'true' || value === 1 || value === '1';

export const authenticateUser = async (req, res, next) => {
    try {
        const authHeader = req.headers.authorization;
        const token = authHeader?.startsWith('Bearer ') ? authHeader.split(' ')[1] : null;

        if (!token) {
            return res.status(401).json({
                success: false,
                message: 'Authentication token required'
            });
        }

        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        const user = await User.findByPk(decoded.id, {
            attributes: { exclude: ['password'] }
        });

        if (!user) {
            return res.status(401).json({
                success: false,
                message: 'Invalid authentication token'
            });
        }

        if (user.status !== 'active') {
            return res.status(403).json({
                success: false,
                message: 'User account is not active'
            });
        }

        req.user = user;
        next();
    } catch (error) {
        return res.status(401).json({
            success: false,
            message: 'Invalid or expired authentication token'
        });
    }
};

export const requirePermission = (moduleName) => [
    authenticateUser,
    (req, res, next) => {
        if (req.user.role === 'admin') {
            return next();
        }

        const permissions = getPermissions(req.user);

        if (isAllowed(permissions?.[moduleName]?.view)) {
            return next();
        }

        return res.status(403).json({
            success: false,
            message: `You do not have access to ${moduleName}`
        });
    }
];

export const requireAdmin = [
    authenticateUser,
    (req, res, next) => {
        if (req.user.role === 'admin') {
            return next();
        }

        return res.status(403).json({
            success: false,
            message: 'Only admin can perform this action'
        });
    }
];

export const requireAdminOrFirstAdmin = async (req, res, next) => {
    try {
        const adminCount = await User.count({
            where: { role: 'admin' }
        });

        if (adminCount === 0) {
            req.isFirstAdminSetup = true;
            return next();
        }

        return authenticateUser(req, res, () => {
            if (req.user.role === 'admin') {
                return next();
            }

            return res.status(403).json({
                success: false,
                message: 'Only admin can perform this action'
            });
        });
    } catch (error) {
        return res.status(500).json({
            success: false,
            message: 'Internal server error'
        });
    }
};

export const requireFirstAdminSetup = async (req, res, next) => {
    try {
        const adminCount = await User.count({
            where: { role: 'admin' }
        });

        if (adminCount > 0) {
            return res.status(409).json({
                success: false,
                message: 'Admin already exists. Please login and create users from user management.'
            });
        }

        req.isFirstAdminSetup = true;
        next();
    } catch (error) {
        return res.status(500).json({
            success: false,
            message: 'Internal server error'
        });
    }
};
