
var Department = require("../models/department");
var Project_user = require("../models/project_user");
var Project = require("../models/project");
var Group = require("../models/group");
var operatingHoursService = require("./operatingHoursService");
var winston = require('../config/winston');
const departmentEvent = require('../event/departmentEvent');
const Request = require('../models/request');
const RoleConstants = require ('../models/roleConstants')
var cacheEnabler = require("../services/cacheEnabler");
var cacheUtil = require("../utils/cacheUtil");

class DepartmentService {

  createDefault(project_id, createdBy) {
    return this.create('Default Department', project_id, 'assigned', createdBy, true);
  }

  create(name, id_project, routing, createdBy, isdefault) {

    if (!isdefault) {
      isdefault = false;
    }
    
    var that = this;
    return new Promise(function (resolve, reject) {
        var newDepartment = new Department({
          routing: routing,
          name: name,
          id_project: id_project,
          default: isdefault,
          createdBy: createdBy,
          updatedBy: createdBy
        });
    
        return newDepartment.save(function (err, savedDepartment) {
          if (err) {
            winston.error('--- > ERROR ', err);
            reject(err);
          }
          winston.verbose('Default Department created', savedDepartment.toObject());
          return resolve(savedDepartment);
        });
      });
  }

  nextOperator (array, index) {
    winston.debug('array: ', array);
    winston.debug('index: ' + index);

    index = index || 0;
  
    if (array === undefined || array === null)
      array = [];
    else if (!Array.isArray(array))
      throw new Error('Expecting argument to RoundRound to be an Array');
  
    // return function () {
        index++;
      if (index >= array.length) index = 0;
      winston.debug('index: ' + index);
      return array[index];
    // };
}


roundRobin(operatorSelectedEvent) {

  var that = this;
 

  return new Promise(function (resolve, reject) {

    if (operatorSelectedEvent.department.routing !== 'assigned') {       
      winston.debug('It isnt an assigned request');  
      return resolve(operatorSelectedEvent);
    }

    // db.getCollection('requests').find({id_project: "5c12662488379d0015753c49", participants: { $exists: true, $ne: [] }}).sort({_id:-1}).limit(1)
    
      // https://stackoverflow.com/questions/14789684/find-mongodb-records-where-array-field-is-not-empty
      let query = {id_project: operatorSelectedEvent.id_project, 
        hasBot:false, preflight:false, status: { $gt: 100 }, 
        participants: { $exists: true, $ne: [] }};
      
      winston.debug('query', query);            

      // let lastRequests = await 
      // requestcachefarequi nocachepopulatereqired
      Request.find(query).sort({_id:-1}).limit(1).exec(function (err, lastRequests) {  // cache_attention  use_lean use_select
          if (err) {
              winston.error('Error getting request for RoundRobinOperator', err); 
              return reject(err);
          }
         
          
          winston.debug('lastRequests',lastRequests); 

          if (lastRequests.length==0) {
              winston.debug('roundRobin lastRequest not found. fall back to random info',operatorSelectedEvent); 
              winston.verbose('roundRobin lastRequest not found. fall back to random'); 
              //first request use default random algoritm
              // return 0;
              return resolve(operatorSelectedEvent);
          }

          // var start = Date.now();
          // var res = sleep(5000);
          // var end = Date.now();
          // // res is the actual time that we slept for
          // console.log(res + ' ~= ' + (end - start) + ' ~= 1000');


          let lastRequest = lastRequests[0];
          winston.debug('lastRequest:'+ JSON.stringify(lastRequest)); 

          let lastOperatorId = lastRequest.participants[0];
          winston.debug('lastOperatorId: ' + lastOperatorId);


          // BUGFIX (node:74274) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'id_user' of undefined
          //   at /Users/andrealeo/dev/chat21/tiledesk-server/services/requestService.js:55:56
          //   at processTicksAndRejections (internal/process/next_tick.js:81:5)
          // (node:74274) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)          
          if (operatorSelectedEvent.available_agents && operatorSelectedEvent.available_agents.length==0) {
            winston.debug('operatorSelectedEvent.available_agents empty ', operatorSelectedEvent.available_agents);
            return resolve(operatorSelectedEvent);
          }          


            //when the agent has a custom auth jwt. so he has uuid_user and not id_user
          // error: uncaughtException: Cannot read property 'toString' of undefined
          // 2021-10-14T08:54:00.099370+00:00 app[web.1]: TypeError: Cannot read property 'toString' of undefined
          // 2021-10-14T08:54:00.099371+00:00 app[web.1]:     at /app/services/departmentService.js:130:119
          // 2021-10-14T08:54:00.099372+00:00 app[web.1]:     at Array.findIndex (<anonymous>)
          // 2021-10-14T08:54:00.099372+00:00 app[web.1]:     at /app/services/departmentService.js:130:74
          // 2021-10-14T08:54:00.099372+00:00 app[web.1]:     at /app/node_modules/mongoose/lib/model.js:5074:18
          // 2021-10-14T08:54:00.099381+00:00 app[web.1]:     at processTicksAndRejections (internal/process/task_q

          // https://stackoverflow.com/questions/15997879/get-the-index-of-the-object-inside-an-array-matching-a-condition
          let lastOperatorIndex = operatorSelectedEvent.available_agents.findIndex(projectUser =>  {
                if (projectUser.id_user) {
                  return projectUser.id_user.toString() === lastOperatorId;
                } else { //when the agent has a custom auth jwt. so he has uuid_user and not id_user
                  return projectUser.uuid_user === lastOperatorId;
                }
              }
            );

          
          // if lastOperatorIndex is -1(last operator is not available)->  that.nextOperator increment index +1 so it's work


  

          winston.debug('lastOperatorIndex: ' + lastOperatorIndex);

          winston.debug('operatorSelectedEvent.available_agents: ', operatorSelectedEvent.available_agents);

          
          let nextOperator = that.nextOperator(operatorSelectedEvent.available_agents, lastOperatorIndex);

          
          winston.debug('roundRobin nextOperator: ' ,nextOperator.toJSON());
          
          


          // operatorSelectedEvent.operators = [{id_user: nextOperator.id_user}];
          operatorSelectedEvent.operators = [nextOperator];

          operatorSelectedEvent.lastOperatorId = lastOperatorId;
          operatorSelectedEvent.lastRequest = lastRequest;
          operatorSelectedEvent.lastOperatorIndex = lastOperatorIndex;


          return resolve(operatorSelectedEvent);
      });
  
    });
}



getOperators(departmentid, projectid, nobot, disableWebHookCall, context) {

  winston.debug('context0.0',context);

  var that = this;
  return new Promise(function (resolve, reject) {
       // console.log("»»» »»» --> DEPT ID ", departmentid);


    let q = Project.findOne({_id: projectid, status: 100})
    if (cacheEnabler.project) { 
      q.cache(cacheUtil.longTTL, "projects:id:"+projectid)  //project_cache
      winston.debug('project cache enabled for getOperators');
    }
    return q.exec(function(err, project){
      if (err) {
        winston.error('Project findById ', err);
        return reject(err);
      }
      if (!project) {
        winston.error("Project not found with id ", projectid);
        return reject({ success: false, msg: "Project not found with id "});
      }


      // if not defined
      // TODO questo lo abiliterei solo esplicitamete se si flagga opzione su progetto per performance
      if (disableWebHookCall==undefined) {
              //if pro enabled disableWebHookCall = false
                              //secondo me qui manca un parentesi tonda per gli or
        if (project.profile && (project.profile.type === 'free' && project.trialExpired === false) || (project.profile.type === 'payment' && project.isActiveSubscription === true)) {
          // winston.info('disableWebHookCall pro');
          disableWebHookCall = false;
        } else {
          disableWebHookCall = true;
        }
      }
      
   


      let query;
      if (departmentid == 'default' || departmentid == undefined) {
        query = { default: true, id_project: projectid };
      } else {
        query = { _id: departmentid };
      }
       // console.log('query', query);
      return Department.findOne(query).exec(function (err, department) {
        // return Department.findOne(query).exec().then(function (department) {

        if (err) {
          winston.error('-- > 1 DEPT FIND BY ID ERR ', err)
          return reject(err);
        }
        // console.log("department", department);
        if (!department) {
          // TODO: error log removed due to attempt to reduces logs when no department is found
          winston.verbose("Department not found for projectid: "+ projectid +" for query: ", query, context);
          return reject({ success: false, msg: 'Department not found for projectid: '+ projectid +' for query: ' + JSON.stringify(query) });
        }
        // console.log('OPERATORS - »»» DETECTED ROUTING ', department.routing)
        // console.log('OPERATORS - »»» DEPARTMENT - ID BOT ', department.id_bot)

        // start code FOR DEBUG
        // NOTE: TO TEST '?nobot = true' see in the tiledesk dashboard: mongodb-department.service > testAssignesFunction
        if (nobot) {
          // console.log('nobot IS == true ? ', nobot)
          // console.log('»»»» »»»» nobot is == TRUE - JUMP TO ASSIGNED / POOLED ')
        } else if (!nobot) {
          // console.log('nobot IS != true ', nobot)
          if ((department.id_bot == null || department.id_bot == undefined)) {
            // console.log('»»»» »»»» BOT IS UNDEFINED or NULL and nobot is != TRUE - JUMP TO ASSIGNED / POOLED')
          } else {
            // console.log('»»»» »»»» BOT EXIST and nobot is != TRUE - ASSIGN THE SELECTED BOT ')
          }
        }
        // /.end code FOR DEBUG 

        // IF EXIST THE BOT AND nobot IS NOT UNDEFINED IN OPERATORS IS RETURNED THE ID OF THE BOT
        if ((department.id_bot != null || department.id_bot != undefined) && (!nobot)) {

          // if (department.id_group == null || department.id_group == undefined) {
          // MAKE X 'BOT' AS FOR 'ASSIGNED' AND 'POOLED': IF THERE IS A GROUP THE BOT WILL BE VISIBLE ONLY BY THE GROUP MEMBERS 
          // OTHERWISE THE BOT WILL BE VISIBLE TO ALL USERS (BECAUSE THERE IS NO GROUP)

          // console.log('OPERATORS - »»»» BOT IS DEFINED - !!! DEPT HAS NOT GROUP ID')
          // console.log('OPERATORS - »»»» BOT IS DEFINED -> ID BOT', department.id_bot);
          // console.log('OPERATORS - »»»» nobot ', nobot)
          winston.debug("main_flow_cache_2 departmentService project users");
          
          
          // rolequery
          // var role = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
          // var qpu = Project_user.find({ id_project: projectid, role: { $in : role }, status: "active" });
          var qpu = Project_user.find({ id_project: projectid, roleType: RoleConstants.TYPE_AGENTS, status: "active" });

          
          // use this. $in doesn't use index very well
          // var qpu = Project_user.findOne({ id_project: projectid, $or: [{ "role": RoleConstants.AGENT }, { "role": RoleConstants.SUPERVISOR }, { "role":  RoleConstants.ADMIN }, { "role": RoleConstants.OWNER }], status: "active" })
          
          if (cacheEnabler.project_user) {
            qpu.cache(cacheUtil.queryTTL, projectid+":project_users:query:teammates:available") //request_cache
            winston.debug('project_user cache enabled');
          }
  
  
          return qpu.exec(function (err, project_users) {
            if (err) {
              winston.error('-- > 2 DEPT FIND BY ID ERR ', err)
              return reject(err);
            }
            // console.log('OPERATORS - BOT IS DEFINED - MEMBERS ', project_users)
            // console.log('OPERATORS - BOT IS DEFINED - MEMBERS LENGHT ', project_users.length);

            // getAvailableOperatorsWithOperatingHours: IN BASE ALLE 'OPERATING HOURS' DEL PROGETTO ESEGUE 
            // getAvailableOperator CHE RITORNA I PROJECT USER DISPONIBILI
            return that.getAvailableOperatorsWithOperatingHours(project_users, projectid).then(function (_available_agents) {

              // console.log("D -> [ OPERATORS - BOT IS DEFINED ] -> AVAILABLE PROJECT-USERS: ", _available_agents);

              // here subscription notifier??              
              return resolve ({ 
                              department: department, available_agents: _available_agents, agents: project_users, 
                              id_bot:department.id_bot, project: project,
                              context: context,
                              // botprefix
                              operators: [{ id_user: 'bot_' + department.id_bot }] 
                             });
            }).catch(function (error) {

              // winston.error("Write failed: ", error);

              winston.error("Error D -> [ OPERATORS - BOT IS DEFINED ] -> AVAILABLE PROJECT-USERS: ", error);

              return reject(error);
            });
            
          });
        }

        else { // if (department.routing === 'assigned' || department.routing === 'pooled') {
          // console.log('OPERATORS - routing ', department.routing, ' - PRJCT-ID ', projectid)
          // console.log('OPERATORS - routing ', department.routing, ' - DEPT GROUP-ID ', department.id_group)


          /* ---------------------------------------------------------------------------------
          *  findProjectUsersAllAndAvailableWithOperatingHours return: 
          *  * available_agents (available project users considering personal availability in the range of the operating hours) 
          *  * agents (i.e., all the project users) 
          *  * operators (i.e. the id of a user selected random from the available project users considering personal availability in the range of the operating hours)
          * --------------------------------------------------------------------------------*/
         winston.debug("context0",context);
          return that.findProjectUsersAllAndAvailableWithOperatingHours(projectid, department, disableWebHookCall, project, context).then(function (value) {

            // console.log('D-0 -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) - ROUTING - ', department.routing, '] ', value);
            value['department'] = department
            return resolve(value);

          }).catch(function (error) {
            winston.error('D-0 -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) - ROUTING - ', department.routing, ' ] -> ERROR: ', error);
            return reject(error);
          });
        }
      });
    });
  });
};

 findProjectUsersAllAndAvailableWithOperatingHours(projectid, department, disableWebHookCall, project, context) {
  var that = this;

  return new Promise(function (resolve, reject) {
    // console.log('D-1 -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) - ROUTING - ', department.routing, ' ], - ID GROUP', department.id_group);

    if (department.id_group != null) {

      return resolve(that.findProjectUsersAllAndAvailableWithOperatingHours_group(projectid, department, disableWebHookCall, project, context));

    } else {

      return resolve(that.findProjectUsersAllAndAvailableWithOperatingHours_nogroup(projectid, department, disableWebHookCall, project, context));

    }

  });
};

 findProjectUsersAllAndAvailableWithOperatingHours_group(projectid, department, disableWebHookCall, project, context) {
  var that = this;

  return new Promise(function (resolve, reject) {
    return Group.find({ _id: department.id_group, $or: [ { enabled: true }, { enabled: { $exists: false } } ] }).exec(function (err, group) {
      if (err) {
        winston.error('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> ERR ', err)
        return reject(err);
      }
      if (group) {
        // console.log('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> GROUP FOUND:: ', group);
        // console.log('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> MEMBERS LENGHT: ', group[0].members.length);
        // console.log('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> MEMBERS ID: ', group[0].members);

   

        // rolequery
        
         return Project_user.find({ id_project: projectid, id_user: { $in : group[0].members}, roleType: RoleConstants.TYPE_AGENTS, status: "active" }).exec(function (err, project_users) {          
        //  return Project_user.find({ id_project: projectid, id_user: { $in : group[0].members}, role: { $in : [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT]}, status: "active" }).exec(function (err, project_users) {         

          // console.log('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> PROJECT ID ', projectid);
          if (err) {
            // console.log('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> PROJECT USER - ERR ', err);
            return reject(err);
          }
          winston.debug("project_users",project_users);
          
          if (project_users && project_users.length > 0) {
            // console.log('D-2 GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> PROJECT USER (IN THE GROUP) LENGHT ', project_users.length);

            return that.getAvailableOperatorsWithOperatingHours(project_users, projectid).then(function (_available_agents) {
              var _available_agents = _available_agents
              // console.log('D-3 NO GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> AVAILABLE AGENT ', _available_agents);

              var selectedoperator = []
              if (department.routing === 'assigned') {                
                selectedoperator = that.getRandomAvailableOperator(_available_agents);
              }

              let objectToReturn = { available_agents: _available_agents, agents: project_users, operators: selectedoperator, department: department, group: group, id_project: projectid, project: project,  context: context };

              // var objectToReturnRoundRobin = objectToReturn;
              that.roundRobin(objectToReturn).then(function(objectToReturnRoundRobin){

                winston.debug("context2",context);
                departmentEvent.emit('operator.select.base1', {result:objectToReturnRoundRobin, disableWebHookCall: disableWebHookCall, resolve: resolve, reject: reject, context: context});

                //is resolved by departmentEvent or SubscriptionNotifier
                // return resolve(objectToReturnRoundRobin);
              });
              

            }).catch(function (error) {

              // winston.error("Write failed: ", error);
              winston.error('D-3 -> [ findProjectUsersAllAndAvailableWithOperatingHours_group ] - AVAILABLE AGENT - ERROR ', error);

              return reject(error);
              //sendError(error, res);
            });
           
          } else {
            // here subscription notifier??
            var objectToReturn = { available_agents: [], agents: [], operators: [], context: context };
            return resolve(objectToReturn);
          }

        })
      }
    });
  });
}


 findProjectUsersAllAndAvailableWithOperatingHours_nogroup(projectid, department, disableWebHookCall, project, context) {

  var that = this;

  return new Promise(function (resolve, reject) {

    // var role = [RoleConstants.OWNER, RoleConstants.ADMIN, RoleConstants.SUPERVISOR, RoleConstants.AGENT];
// rolequery
    var qpu = Project_user.find({ id_project: projectid, roleType: RoleConstants.TYPE_AGENTS, status: "active" });
    // var qpu = Project_user.find({ id_project: projectid, role: { $in : role }, status: "active" });
          
    // use this. $in doesn't use index very well    
    if (cacheEnabler.project_user) {
      qpu.cache(cacheUtil.queryTTL, projectid+":project_users:query:teammates:available") //request_cache
      winston.debug('project_user cache enabled');
    }
    // return Project_user.find({ id_project: projectid , role: { $in : role }, status: "active" }).exec(function (err, project_users) {
    return qpu.exec(function (err, project_users) {


      if (err) {
        winston.error('D-3 NO GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> ERR ', err)
        return reject(err);
      }
      // console.log('D-3 NO GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] ->  MEMBERS LENGHT ', project_users.length)
      // console.log('D-3 NO GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] ->  MEMBERS ', project_users)


      if (project_users && project_users.length > 0) {
        
        return that.getAvailableOperatorsWithOperatingHours(project_users, projectid).then(function (_available_agents) {
          var _available_agents = _available_agents
          // console.log('D-3 NO GROUP -> [ FIND PROJECT USERS: ALL and AVAILABLE (with OH) ] -> AVAILABLE AGENT ', _available_agents);

          var selectedoperator = []
          if (department.routing === 'assigned') {
            selectedoperator = that.getRandomAvailableOperator(_available_agents);
          }

          let objectToReturn = { available_agents: _available_agents, agents: project_users, operators: selectedoperator, department: department, id_project: projectid, project: project, context: context };

          // var objectToReturnRoundRobin = objectToReturn;

          that.roundRobin(objectToReturn).then(function(objectToReturnRoundRobin) {
            winston.debug("context2",context);
            departmentEvent.emit('operator.select.base1', {result:objectToReturnRoundRobin,  disableWebHookCall: disableWebHookCall, resolve: resolve, reject: reject, context: context});

            // attento qui            
            // if (objectToReturnRoundRobin.department._id == "5e5d40b2bd0a9b00179ff3cf" ) {
            //   objectToReturnRoundRobin.operators = [];
            // }
          

            //is resolved by departmentEvent or SubscriptionNotifier
            // return resolve(objectToReturnRoundRobin);
          });
          
        }).catch(function (error) {

          // winston.error("Write failed: ", error);
          winston.error('D-3 -> [ findProjectUsersAllAndAvailableWithOperatingHours_nogroup ] - AVAILABLE AGENT - ERROR ', error);
          return reject(error);

        });

       
      } else {
        // here subscription notifier??
        let objectToReturn = { available_agents: [], agents: [], operators: [], context: context };
        return resolve(objectToReturn);
      }

    });
  });
}



 getAvailableOperatorsWithOperatingHours(project_users, projectid) {

  var that = this;


  return new Promise(function (resolve, reject) {

    if (project_users && project_users.length > 0) {

      return operatingHoursService.projectIsOpenNow(projectid, function (isOpen, err) {
        // console.log('D -> [ OHS ] -> [ GET AVAILABLE PROJECT-USER WITH OPERATING H ] -> PROJECT ID: ', projectid);
        // console.log('D -> [ OHS ] -> [ GET AVAILABLE PROJECT-USER WITH OPERATING H ] -> IS OPEN THE PROJECT: ', isOpen);
        // console.log('D -> [ OHS ] -> [ GET AVAILABLE PROJECT-USER WITH OPERATING H ] -> IS OPEN THE PROJECT - ERROR: ', err)

        if (err) {
          winston.error(err); 
          return reject(err);
          // sendError(err, res);

        } 
        
        if (isOpen) {

          var _available_agents = that.getAvailableOperator(project_users);

          return resolve(_available_agents);
        } else {
          // console.logO ---> [ OHS ] -> PROJECT NOT FOUND("HERERERERERERE");
          return resolve([]);
        }
      });
    } else {
      return resolve([]);
    }

  });
}

// FILTER ALL THE PROJECT USERS FOR AVAILABLE = TRUE
 getAvailableOperator(project_users) {
  var project_users_available = project_users.filter(function (projectUser) {
    if (projectUser.user_available == true) {
      return true;
    }
  });
  // console.log('D -> [GET AVAILABLE PROJECT-USER ] - AVAILABLE PROJECT USERS (getAvailableOperator): ', project_users_available)
  return project_users_available
}



 
getDefaultDepartment(projectid) {
  return new Promise(function (resolve, reject) {
    let query = { default: true, id_project: projectid };
    winston.debug('query ', query)
    // console.log('query', query);
    return Department.findOne(query).exec(function (err, department) {
      // return Department.findOne(query).exec().then(function (department) {

      if (err) {
        winston.error('-- > 1 DEPT FIND BY ID ERR ', err)
        return reject(err);
      }
      // console.log("department", department);
      if (!department) {
        // TODO: error log removed due to attempt to reduces logs when no department is found
        winston.verbose("Department not found for projectid: "+ projectid +" for query: ", query, context);
        return reject({ success: false, msg: 'Department not found for projectid: '+ projectid +' for query: ' + JSON.stringify(query) });
      }
      winston.debug('department ', department);

      return resolve(department);
    });
  });
}

 getRandomAvailableOperator(project_users_available) {

  // console.log('-- > OPERATORS [ getRandomAvailableOperator ] - PROJECT USER AVAILABLE LENGHT ', project_users_available.length);
  if (project_users_available.length > 0) {


    // new
                                  // num between 0 and 1 * es 3 -> 
    // let randomIndex =  Math.round(Math.random() * project_users_available.length);
    // // let randomIndex =  Math.floor(Math.random() * project_users_available.length);
    
    // console.log("randomIndex",randomIndex);
    // var operator = project_users_available[randomIndex];
    // // console.log('OPERATORS - SELECTED MEMBER ID', operator.id_user);

    var operator = project_users_available[Math.floor(Math.random() * project_users_available.length)];


    return [{ id_user: operator.id_user }];
    // return [operator];

  }
  else {

    return []

  }
}

  /**
   * Checks if the group belongs to a department of the project
   * @param {String} projectId
   * @param {String} groupId
   * @returns {Promise<Boolean>} true if the group belongs to a department of the project, otherwise false
   */
  async isGroupInProjectDepartment(projectId, groupId) {
    try {
      const department = await Department.findOne({ id_project: projectId, id_group: groupId });
      return !!department;
    } catch (err) {
      winston.error('Error in isGroupInProjectDepartment', err);
      return false;
    }
  }


}


var departmentService = new DepartmentService();


module.exports = departmentService;
