'use strict';
define(function() {
  var UsersFactory = function($http, gaJsUtils, $q, $rootScope, gaDomUtils, $timeout) {
    var UsersFactory = {};

    /**
     * Class : UsersFactory
     * Factory WebServices
     */
    var resources = {
      users: [],
      currentuser: {},
    };

    var users = [];

    /**
     * Ajoute un utilisateur dans la liste des utilisateurs du portail
     * @param newUser objet JS correspondant au nouvel utilisateur du portail à enregistrer
     * @param pass mot de passe de l'utilisateur non haché (argument inutile dupliquant la propriété newUser.pass)
     * @param lightRoles est true pour retourner les users sans leur tableau de rôles
     * @return {[*]} tableau des utilisateurs du portail (avec ou sans leurs rôles)
     */
    const add = (newUser, pass, lightRoles) => {
      const senddata = {user: newUser, pass: pass};
      const promise = $http.post('/services/{portalid}/rights/user/add?f=json'
          +'&lightRoles=' + !!lightRoles,
        senddata
      );
      promise.then((res) => {
            resources.users.push(res.data);
          },
          err => {
            if (err.data && err.data.message){
              let error = err.data.message;
              if (err.data.detail && err.data.detail.length > 0) {
                error += ' : ' + err.data.detail;
                require('toastr').error(error);
              }
            }
          });
      return promise;
    };
    /**
     * Function: remove
     */
    function remove(id) {
      var promise = $http.get(
        '/services/{portalid}/rights/user/remove?f=json' + '&id=' + id
      );
      promise.then(function() {
        var deleteIndex = resources.users
          .map(function(x) {
            return x.uid;
          })
          .indexOf(id);
        resources.users.splice(deleteIndex, 1);
      });
      return promise;
    }
    /**
     * Function: get
     */
    function get() {
      var promise = $http.get('/services/{portalid}/rights/user/get?f=json');
      promise.then(function(res) {
        resources.users = gaJsUtils.sortByKey(res.data, 'login');
      });
      return promise;
    }

    /**
     * Function: user_monitoring
     */
    function user_monitoring(senddata) {
      var promise = $http.post(
        '/services/{portalid}/rights/user/user_map_widget',
        senddata
      );

      return promise;
    }

    /**
     * Function: getlegitimateuser
     */
    function getactiveusers() {
      if (typeof userAndroid !== 'undefined') {
        var defer = $q.defer();
        var response = {
          data: JSON.parse(userAndroid.getactiveusers()),
        };
        defer.resolve(response);
        return defer.promise;
      } else {
        var promise = $http.get(
          '/services/{portalid}/rights/user/getactiveusers?f=json'
        );
        promise.then(function(res) {
          // service level logic if any
        });
        return promise;
      }
    }
    /**
     * Function: getlegitimateuser
     */
    function getactiveuserslight() {
      if (typeof userAndroid !== 'undefined') {
        var defer = $q.defer();
        var response = {
          data: JSON.parse(userAndroid.getactiveusers()),
        };
        defer.resolve(response);
        return defer.promise;
      } else {
        var promise = $http.get(
          '/services/{portalid}/rights/user/getactiveuserslight?f=json'
        );
        promise.then(function(res) {
          // service level logic if any
        })
        .catch(err => {
          err.stack;
        });
        return promise;
      }
    }
    /**
     * Function: getlight
     */
    function getlight() {
      var promise = $http.get('/services/{portalid}/rights/user/getls?f=json');
      promise.then(function(res) {
        resources.users = gaJsUtils.sortByKey(res.data, 'login');
      });
      return promise;
    }
    /**
     * Function: getbyid
     */
    function getbyid(uid, lightRoles) {
      var promise = $http.get(
        '/services/{portalid}/rights/user/getbyid?f=json' + '&uid=' + uid +'&lightRoles=' + !!lightRoles
      );

      return promise;
    }
    /**
     * Function: getLightUserByLogin
     * @param {string} loginToSearch identifiant de connexion de l'utilisateur recherché
     * @returns a promise containing the user you are looking for
     */
    function getLightUserByLogin(loginToSearch) {
      const getLogin = () => {
        return resources.users.find(u => u.login === loginToSearch);
      }
      if (Array.isArray(resources.users) && resources.users.length > 0) {
        return new Promise((resolve) => {
          resolve(getLogin());
        });
      } else {
        return getlight().then(getLogin);
      }
    }

    /**
     * Met à jour un utilisateur existant du portail
     * @param newUser nouveau objet JS correspondant à l'utilisateur
     * @param password mot de passe non haché (argument inutile dupliquant la propriété newUser.pass)
     * @param lightRoles est true pour retourner les users sans leur tableau de rôles
     * @return {[*]} tableau des utilisateurs du portail (avec ou sans leurs rôles)
     */
    const update = (newUser, password, lightRoles) => {
      const senddata = {user: newUser, pass: password};
      const promise = $http.post(
        '/services/{portalid}/rights/user/update?f=json'
          +'&lightRoles=' + !!lightRoles,
        senddata
      );
      promise.then(
          (res) => {
            const replaceIndex = resources.users.indexOf(user => user.uid === newUser.uid);
            resources.users[replaceIndex] = res.data;
          },
          err => {
            if (err.data && err.data.message) {
              let error = err.data.message;
              if (err.data.detail && err.data.detail.length > 0) {
                error += ' : ' + err.data.detail;
                require('toastr').error(error);
              }
            }
          });
      return promise;
    };

    function getcurrentuser() {
      if (resources.currentuser == {}) {
        token().then(function(res) {
          resources.currentuser = res.data;
        });
      }
      return resources.currentuser;
    }
    function token() {
      var promise = $http.get('/services/{portalid}/rights/user/token?f=json');
      promise.then((res) => {
        if (res.data && res.data.code === 403
            && localStorage.getItem('kisusertheme') !== null) {
          $rootScope.xgos.currentTheme = localStorage.getItem('kisusertheme');
        }
      }); 
      return promise;
    }

    function getLightUsersByRoles(roles) {
      // Create the argument rolesString
      let rolesString = '';
      if(roles) {
        for (let role of roles) {
          rolesString += role + ','
        }
        if (rolesString !== '') {
          rolesString = rolesString.slice(0, -1);
        }
      }

      // Request the users
      return $http.get(
          '/services/{portalid}/rights/user/getLightUsersByRoles?f=json'
          + '&roles=' + rolesString
      );
    }

    function changeConnectedUser(portalIdNew,login){
      return $http.get('/services/{portalid}/rights/user/changeConnectedUser?f=json'+
      '&portalIdNew='+ portalIdNew +'&login='+ login);
    }

    /**
     * Met à jour la propriété theme de l'utilisateur.
     * Si erreur serveur, renvoie une erreur de type com.g2c.core.data.common.Error
     * @param useruid uid de l'utilisateur
     * @param isroot est true si l'utilisateur est root
     * @param theme string du nouveau thème de l'utilisateur
     * @return {boolean} renvoie true si la mise à jour de l'utilisateur dans le repo a été effectuée
     */
    const updateUserThemeByUserId = (useruid, isroot, theme) => {
      const promise = $http.get('/services/{portalid}/rights/user/updateUserThemeByUserId?f=json'+
          '&useruid='+
          useruid +
          '&isroot='+
          isroot +
          '&theme='+
          theme
      );
      promise.catch((error)=>{
        if (error.data && error.data.message && error.data.detail) {
          console.error(error.data ? error.data.message + '|' + error.data.detail : '');
        }
      });
      return promise;
    };

    const checkLdapUsersAndGetFailed = () =>{
      var deferred = $q.defer();
      $http.get('/services/{portalid}/rights/user/checkLdapUsersAndGetFailed?f=json').then(
        (res) => {
          checkLoadDataThread(res.data, deferred, 0);
        },
        (res) => {
          deferred.reject(res);
        }
      );
      return deferred.promise;
    }

    const updateConnectionStrings = (users) =>{
      var deferred = $q.defer();
      $http.post('/services/{portalid}/rights/user/updateConnectionStrings?f=json',users).then(
        (res) => {
          checkLoadDataThread(res.data, deferred, 0);
        },
        (res) => {
          deferred.reject(res);
        }
      );
      return deferred.promise;
    }

    const checkLoadDataThread = (threadid, deferred, count) => {
      $http.get('/services/{portalid}/rights/user/checkDataLoading?f=json' +
        '&threadid=' + threadid).then((res0) =>{
          if (res0 && res0.data) {
            let jsRes = res0.data;
            gaDomUtils.setGlobalLoaderScaleBar(jsRes.progress,jsRes.progressMax/jsRes.progressPercentage);
            if (jsRes.alive) {
              let delay = 5000;
              if (count < 3) delay = 1000;
              $timeout(() => {
                checkLoadDataThread(threadid, deferred, ++count);
              }, delay);
            } else {
              if (jsRes.status == 400) {
                deferred.resolve({ data: jsRes.error });
              } else {
                deferred.resolve({ data: jsRes.result });
              }
            }
          } else {
            deferred.reject(res0);
          }
        },
        (res) => {
          deferred.reject(res);
        }
      );
    };

    // Test si l'utilisateur a les droits en écriture sur la feature
    const userHasWriteRight = (user, featureUid) => {
      // Check on roles
      for (const role of user.roles) {
        for (const authorization of role.authorizations) {
          if(authorization.item === featureUid) {
            if(authorization.write === true) {
              return true;
            }
            break;
          }
        }
      }
      // Check on groups
      for (const group of user.groups) {
        for (const role of group.roles) {
          for (const authorization of role.authorizations) {
            if(authorization.item === featureUid) {
              if(authorization.write === true) {
                return true;
              }
              break;
            }
          }
        }
      }
      return false;
    };



    return {
      UsersFactory: UsersFactory,
      resources: resources,
      add: add,
      remove: remove,
      get: get,
      getactiveusers: getactiveusers,
      getlight: getlight,
      getbyid: getbyid,
      update: update,
      getcurrentuser: getcurrentuser,
      changeConnectedUser: changeConnectedUser,
      token: token,
      getLightUsersByRoles: getLightUsersByRoles,
      getLightUserByLogin: getLightUserByLogin,
      user_monitoring: user_monitoring,
      getactiveuserslight: getactiveuserslight,
      updateUserThemeByUserId: updateUserThemeByUserId,
      checkLdapUsersAndGetFailed:checkLdapUsersAndGetFailed,
      userHasWriteRight: userHasWriteRight,
      updateConnectionStrings:updateConnectionStrings
    };
  };
  UsersFactory.$inject = ['$http', 'gaJsUtils', '$q', '$rootScope', 'gaDomUtils', '$timeout'];
  return UsersFactory;
});
