const Role = require('../models/Role');

exports.checkModulePermission = (moduleName, actionName) => {
  return async (req, res, next) => {
    try {
      const role = await Role.findById(req.user.roleId);
      
      if (!role || !role.isActive) {
        return res.status(403).json({
          success: false,
          message: 'Invalid or inactive role'
        });
      }

      const modulePermission = role.modulePermissions.find(
        mp => mp.moduleName === moduleName
      );
      
      if (!modulePermission) {
        return res.status(403).json({
          success: false,
          message: `You don't have access to '${moduleName}' module`
        });
      }
      
      const hasPermission = modulePermission.permissions.get(actionName);
      
      if (!hasPermission) {
        return res.status(403).json({
          success: false,
          message: `You don't have '${actionName}' permission for '${moduleName}' module`
        });
      }
      
      req.userRole = role;
      next();
      
    } catch (error) {
      res.status(500).json({
        success: false,
        message: 'Error checking permissions'
      });
    }
  };
};

exports.checkSpecialPermission = (permission) => {
  return async (req, res, next) => {
    try {
      const role = await Role.findById(req.user.roleId);
      
      if (!role || !role.specialPermissions.includes(permission)) {
        return res.status(403).json({
          success: false,
          message: `You don't have '${permission}' special permission`
        });
      }
      
      next();
    } catch (error) {
      res.status(500).json({
        success: false,
        message: 'Error checking special permissions'
      });
    }
  };
};

// NEW: Company-based permission check for multi-company users
exports.checkCompanyAccess = () => {
  return async (req, res, next) => {
    try {
      // For global scope users (root, super_admin), allow access to all companies
      const userRole = await Role.findById(req.user.roleId);
      if (userRole.scope === 'global') {
        req.userRole = userRole;
        return next();
      }

      // For company/partner scope users, check if they have access to target companies
      if (req.body.companies || req.params.companyId || req.query.companyId) {
        const targetCompanies = [];
        
        // Extract target companies from request
        if (req.body.companies) {
          targetCompanies.push(...req.body.companies);
        }
        if (req.params.companyId) {
          targetCompanies.push(req.params.companyId);
        }
        if (req.query.companyId) {
          targetCompanies.push(req.query.companyId);
        }

        // Check if current user has access to ALL target companies
        const hasAccessToAll = targetCompanies.every(targetCompanyId => 
          req.user.companies.some(userCompany => 
            userCompany.toString() === targetCompanyId.toString()
          )
        );

        if (!hasAccessToAll) {
          return res.status(403).json({
            success: false,
            message: 'You can only access your assigned companies'
          });
        }
      }

      // For users without specific company targets, check if they share any company
      // with the target user (if userId is provided)
      if (req.params.id || req.body.userId || req.query.userId) {
        const targetUserId = req.params.id || req.body.userId || req.query.userId;
        const targetUser = await Role.findById(targetUserId).select('companies');
        
        if (targetUser && targetUser.companies && targetUser.companies.length > 0) {
          const hasCommonCompany = targetUser.companies.some(targetCompany => 
            req.user.companies.some(userCompany => 
              targetCompany.toString() === userCompany.toString()
            )
          );
          
          if (!hasCommonCompany) {
            return res.status(403).json({
              success: false,
              message: 'Access denied: No common companies with target user'
            });
          }
        }
      }

      req.userRole = userRole;
      next();
      
    } catch (error) {
      res.status(500).json({
        success: false,
        message: 'Error checking company access'
      });
    }
  };
};