'use strict';
define(function() {
  var RolesFactory = function($http, $q, $filter) {
    var RolesFactory = {};
    /**
     * Class : RolesFactory
     * Factory WebServices
     */

    var resources = {
      roles: [],
      rolesLight: []
    };

    /**
     * Function: add
     */
    function add(senddata) {
      var promise = $http.post(
        '/services/{portalid}/rights/role/add?f=json',
        senddata
      );
      promise.then(function(res) {
        resources.roles.push(res.data);
        if(resources.rolesLight.length>0){
          let lightRes = angular.copy(res.data);
          lightRes.authorizations = [];
          lightRes.rightFeatures = [];
          resources.rolesLight.push(lightRes);
        }
      });
      return promise;
    }
    /**
     * Function: remove
     */
    function remove(id) {
      var promise = $http.get(
        '/services/{portalid}/rights/role/remove?f=json' + '&id=' + id
      );
      promise.then(function(res) {
        let deleteIndex = resources.roles.findIndex(role => role.uid===id);
        resources.roles.splice(deleteIndex, 1);
        if(resources.rolesLight.length>0){
          let deleteIndexLight = resources.rolesLight.findIndex(role => role.uid===id);
          resources.rolesLight.splice(deleteIndexLight, 1);
        }
      });
      return promise;
    }

    /**
     * Function: get
     */
    function get(lightRoles) {
      var promise = $http.get('/services/{portalid}/rights/role/get?f=json&lightRoles=' + !!lightRoles);
      promise.then(function(res) {
        if(lightRoles){
          resources.rolesLight = res.data;
        }else{
          resources.roles = res.data;
        }
      });
      return promise;
    }

    /**
     * Function: update
     */
    function update(senddata) {
      var promise = $http.post(
        '/services/{portalid}/rights/role/update?f=json',
        senddata
      );
      promise.then(function(res) {
        let replaceIndex = resources.roles.findIndex(role => role.uid===senddata.uid);
        resources.roles[replaceIndex] = res.data;
        if(resources.rolesLight.length>0){
          let replaceIndexLight = resources.rolesLight.findIndex(role => role.uid===senddata.uid);
          let lightRes = angular.copy(res.data);
          lightRes.authorizations = [];
          lightRes.rightFeatures = [];
          resources.rolesLight[replaceIndexLight] = lightRes;
        }
      });
      return promise;
    }

    /**
     * Récupère les rôles de l'utilisateur et les rôles des groupes de l'utilisateur
     * Les rôle sont retournés complets (lightrole = false)
     * @param login login de l'utilisateur connecté
     * @return {Promise} contenant le tableau de rôles détenus par l'utilisateur connecté
     */
    const getRolesByUser = (login) => {
      return $http.get('/services/{portalid}/rights/role/getRolesByUser?f=json&login=' + login);
    }

    /**
     * Filtre les actions du fti suivant le rôle de l'utilisateur
     * @param login login de l'utilisateur connecté
     * @param ftiActions actions du fti
     * @return {Promise} contenant uniquement les actions ayant un rôle en commun avec l'utilisateur
     */
    const filterActionsByRoles = (login, ftiActions) =>{
      const defer = $q.defer();
      if (login === 'root'){
        defer.resolve(ftiActions);
      }else{
        getRolesByUser(login).then(
            res =>{
              if (res.data && res.data.length > 0){
                const actions = [];
                const userRoles = res.data;
                for (const action of ftiActions){
                  if (action.roles && action.roles.length > 0){
                    const roles = action.roles.split(',');
                    for (const role of roles){
                      // ajoute l'action si l'utilisateur possède un role en commmun avec l'action
                      if (userRoles.findIndex(ur => ur.name === role.trim()) > -1){
                        actions.push(action);
                      }
                    }
                  }else{
                    // si l'action n'est pas restreinte à un role alors on récupère l'action
                    actions.push(action);
                  }
                }
                defer.resolve(actions);
              }else{
                // si l'utilisateur n'a pas de rôle alors on renvoie toutes les actions en entrée
                defer.resolve(ftiActions);
              }
            },
            ()=>{
              defer.reject(require('toastr').error($filter('translate')('model.featuretypes.actions.filterByRoleError')));
            }
        );
      }
      return defer.promise;
    };

    /**
     * Ajoute un rôle s'il n'existe pas déjà (suivant le nom)
     * @param role rôle à ajouter
     * @return {object | boolean} renvoie un rôle s'il a bien été ajouté ou false s'il existait déjà
     */
    const addIfNotExists = (role) => {
      $http.post(
          '/services/{portalid}/rights/role/addIfNotExists?f=json',
          role
      ).then(
          (res) => {
            if (res.data && res.data.name === role.name) {
              // ajoute le rôle retourné dans le tableau de rôles-light
              const index = resources.rolesLight.findIndex(rolelight => rolelight.name === role.name);
              if (index > -1) {
                resources.rolesLight.splice(index,1, res.data);
              } else {
                resources.rolesLight.push(res.data);
              }
            }
          },
          (err) => {
            if (err && err.data && err.data.message) {
              console.error(err.data.message);
            }
            require('toastr').error($filter('translate')('portals.homepage.addMainRoleError'));
          }
      );
    };

    /**
     * Supprime un rôle par son nom
     * @param uid uid du rôle à supprimer
     * @return {boolean} renvoie true ou false selon le résultat de la suppression ou null si aucun fichier ne porte le nom
     */
    const removeByUid = (uid) => {
      return $http.get(
          '/services/{portalid}/rights/role/removeByUid?f=json'
          + '&uid=' + uid
      ).then((res) => {
            if (res.data) {
              // si suppression réussie
              // supprime le rôle du tableau de rôles
              if (Array.isArray(resources.roles) && resources.roles.length > 0) {
                const indexRole = resources.roles.findIndex(role => role.uid === uid);
                if (indexRole > -1) {
                  resources.roles.splice(indexRole, 1);
                }
              }
              // supprime le rôle du tableau de rôles-light
              if (Array.isArray(resources.roles) && resources.roles.length > 0) {
                const indexRoleLight = resources.rolesLight.findIndex(role => role.uid === uid);
                if (indexRoleLight > -1) {
                  resources.rolesLight.splice(indexRoleLight, 1);
                }
              }
            }
          },
          (err) => {
            if (err && err.data && err.data.message) {
              console.error(err.data.message);
            }
            require('toastr').error($filter('translate')('portals.homepage.delMainRoleError'));
          });
    };

    return {
      RolesFactory: RolesFactory,
      resources: resources,
      add: add,
      remove: remove,
      get: get,
      update: update,
      getRolesByUser: getRolesByUser,
      filterActionsByRoles: filterActionsByRoles,
      addIfNotExists: addIfNotExists,
      removeByUid: removeByUid
    };
  };
  RolesFactory.$inject = ['$http','$q','$filter'];
  return RolesFactory;
});
