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

const authenticateToken = async (req, res, next) => {
  try {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

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

    const decoded = jwt.verify(token, config.jwt.secret);
    
    const user = await User.findOne({
      where: { 
        id: decoded.userId,
        status: 'ACTIVE', 
        is_active: true 
      },
      attributes: { exclude: ['password_hash'] }
    });

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

    if (user.is_locked) {
      return res.status(403).json({
        success: false,
        message: 'User account is locked'
      });
    }

    req.user = {
      userId: decoded.userId,
      companyId: decoded.companyId,
      username: decoded.username,
      isSuperAdmin: user.is_super_admin
    };
    next();
  } catch (error) {
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({
        success: false,
        message: 'Token has expired'
      });
    }
    if (error.name === 'JsonWebTokenError') {
      return res.status(401).json({
        success: false,
        message: 'Invalid token'
      });
    }
    next(error);
  }
};

const authorize = (...roles) => {
  return async (req, res, next) => {
    try {
      if (!req.user) {
        return res.status(401).json({
          success: false,
          message: 'Authentication required'
        });
      }

      // If user is super admin, allow access
      if (req.user.is_super_admin) {
        return next();
      }

      // Get user roles
      const userRoles = await req.user.getRoles();
      const userRoleCodes = userRoles.map(role => role.role_code);

      // Check if user has any of the required roles
      const hasRequiredRole = roles.some(role => userRoleCodes.includes(role));

      if (!hasRequiredRole) {
        return res.status(403).json({
          success: false,
          message: 'Insufficient permissions'
        });
      }

      next();
    } catch (error) {
      next(error);
    }
  };
};

module.exports = {
  authenticate: authenticateToken,
  authenticateToken,
  authorize
};

