'use strict';
define(function() {
  var UsersCtrl = function(
    $scope,
    UsersFactory,
    GroupsFactory,
    RolesFactory,
    $filter,
    $translate,
    ngDialog,
    RestrictionFactory,
    $rootScope,
    ExtraAuthenticationFactory,
    gaJsUtils,
    ngTableParams,
    $timeout,
    gaDomUtils,
    authFactory,
    ThumbnailFactory,
    ParametersFactory,
    PortalsFactory,
    MajicFactory
  ) {

    $scope.isSuperAdmin = $rootScope.xgos.isSuperAdmin;
    // Edit User Tabs
    $scope.tabs = [
      {
        title: 'common.general',
        content: 'js/XG/modules/rights/views/modals/modal.users_general.html',
      },
      {
        title: 'rights.groups.title',
        content: 'js/XG/modules/rights/views/modals/modal.users_groups.html',
      },
      {
        title: 'rights.roles.title',
        content: 'js/XG/modules/rights/views/modals/modal.users_roles.html',
      },
      {
        title: 'rights.restriction.title',
        content:
          'js/XG/modules/rights/views/modals/modal.users_restriction.html',
      }
    ];

    if($rootScope.xgos.isroot){
      $scope.tabs.push({
        title: 'rights.portails.title',
        content: 'js/XG/modules/rights/views/modals/modal.users_portails.html',
      });
    }
    $scope.tabs.activeTab = 0;
    $scope.confirmpass = { pass: '' };

    /**
     * setUserModal
     */
    var setUserModal = function() {
      $scope.tabs.activeTab = 0;

      $scope.civilities = [
        {
          key: 'Mme',
          label: $filter('translate')('rights.users.civility.ms'),
        },
        {
          key: 'M',
          label: $filter('translate')('rights.users.civility.mrs'),
        },
      ];

      if (
        $rootScope.xgos.user.roles
          .map(function(x) {
            return x.name;
          })
          .indexOf('rootUser') !== -1 ||
          $rootScope.xgos.user.roles
            .map((x) => {
              return x.name;
            })
            .indexOf('ANCadmin') !== -1 ||
        $rootScope.xgos.user.roles
          .map((x) => {
            return x.name;
          })
          .indexOf('adminportal') !== -1
      ) {
        RestrictionFactory.getAllRestrictions().then(
          function(res) {
            if (res.data) {
              $scope.restrictions = [
                {
                  name: $filter('translate')(
                    'rights.restriction.norestriction'
                  ),
                },
              ];
              $scope.restrictions = $scope.restrictions.concat(res.data);
              RestrictionFactory.setRestriction(res.data);
            }
            else {
              console.info('no config');
            }
          },
          function() {
            console.info('no config');
          }
        );

        $scope.showRestriction = true;
        if (!$scope.edit_resource.restriction)
          $scope.edit_resource.restriction = {
            uid: '',
          };
        if (angular.isUndefined($scope.edit_resource.restriction.modes))
          $scope.edit_resource.restriction.modes = {};
      }
      else {
        $scope.showRestriction = false;
      }

      // Groups DualListBox
      $scope.dLBGroupData = {
        leftData: angular.copy($scope.edit_resource.groups),
        leftDisplayAttribute: 'name',
        rightData: angular.copy(GroupsFactory.resources.groupsLight),
        rightDisplayAttribute: 'name',
        leftTitle: 'rights.users.groups',
        rightTitle: 'rights.groups.title',
        source: 'right',
      };

      var roles = angular.copy(RolesFactory.resources.rolesLight);

      // seul root peut affecter le droit sRootUser
      if (!$rootScope.xgos.isroot) {
        roles = roles.filter(function(x) {
          return x.name != 'sRootUser';
        });
      }

      // Roles DualListBox
      $scope.dLBRolesData = {
        leftData: angular.copy($scope.edit_resource.roles),
        leftDisplayAttribute: 'name',
        rightData: roles,
        rightDisplayAttribute: 'name',
        leftTitle: 'rights.users.roles',
        rightTitle: 'rights.roles.title',
        source: 'right',
      };

      $scope.modalIsLoading = false;

      if($rootScope.xgos.isroot){
        if(!$scope.edit_resource.portails){
          $scope.edit_resource.portails = [];
        }
        //on teste si le portail existe déjà dans le leftData sinon on l'ajoute
        if(!$scope.edit_resource.portails.find(portail => portail.uid ==$scope.xgos.portal.uid)){
          $scope.edit_resource.portails.push({'name':$scope.xgos.portal.name,'uid':$scope.xgos.portal.uid});
        }
        $scope.dLBPortailsData = {
          leftData: angular.copy($scope.edit_resource.portails),
          leftDisplayAttribute: 'name',
          rightData: PortalsFactory.resources.portals.map((portail)=> Object.assign({'name':portail.name,'uid':portail.uid})),
          rightDisplayAttribute: 'name',
          leftTitle: 'rights.portails.user',
          rightTitle: 'rights.portails.title',
          source: 'portails',
          disableDragFromRight: $scope.xgos.portal.name,
          keytocheck: 'name',
        };
      }

      // Majic DualListBox
      $scope.dLBMajicData = {
        leftData: [],
        leftDisplayAttribute: 'name',
        rightData: [],
        rightDisplayAttribute: 'name',
        leftTitle: 'tools.majicedigeo.majic.filtrerSurCommunes',
        rightTitle: 'tools.majicedigeo.majic.communesDisponibles',
        source: 'right',
      };

      /**
       * Rempli la liste des noms communes de l'utilisateur (partie gauche)
       * en fonction des codes insee de l'utilisateur
       * @param communes liste de toutes les communes ayant des données Majic
       */
      const updateMajicLeftData = (communes) => {
        if ($scope.edit_resource && $scope.edit_resource.communes && Array.isArray(
          $scope.edit_resource.communes)) {
          for (const insee of $scope.edit_resource.communes) {
            const optionalCommune = Object.entries(communes).find(x => x[0] === insee);
            if (optionalCommune) {
              $scope.dLBMajicData.leftData.push({
                name: optionalCommune[1],
                insee: insee
              });
            }
          }
        }
      };

      /**
       * Rempli la liste des noms communes disponibles
       * en soustrayant les communes de l'utilisateur
       * à la liste de toutes les communes ayant des données Majic
       * @param communes liste de toutes les communes ayant des données Majic
       */
      const updateMajicRightData = (communes) => {
        if(communes){
          const libcommunes = [];
          for (const [key,value] of Object.entries(communes)) {
            if ($scope.dLBMajicData.leftData.findIndex(commune => commune.insee === key) === -1) {
              libcommunes.push({
                name: value,
                insee: key
              });
            }
          }
          $scope.dLBMajicData.rightData = libcommunes;
        }
      };

      // vérifie si le portail contient une datasource majic
      // On ne vérifie pas la présence des tables "b_10" et "nb_10" (cf. KIS-2474 @TB)
      MajicFactory.hasMajicDataStore().then(
        res => {
          // Il existe un datastore "majic"
          if (res.data && typeof res.data == 'boolean') {
            const isMajicTabPresent = $scope.tabs.find(tab => tab.title === 'tools.majicedigeo.majic.restrictedAcces');
            if (!isMajicTabPresent) {
              $scope.tabs.push({
                title: 'tools.majicedigeo.majic.restrictedAcces',
                content: 'js/XG/modules/rights/views/modals/modal.users_majic.html',
              });
            }
            if (!$scope.communes) {
              MajicFactory.hasTableCommuneInMajicDataStore().then(
                res => {
                  if (typeof res.data === 'boolean' && res.data) {
                    // la source de données "majic" possède une table f_commune
                    MajicFactory.getVilleInsee().then(
                      res => {
                        if (typeof res.data === 'object' && res.data !== null) {
                          $scope.communes = res.data;
                          updateMajicLeftData(res.data);
                          updateMajicRightData(res.data);
                        }
                      },
                      (error) => {
                        if (error && error.data && error.data.message){
                          console.error(error.data.message);
                        }
                        require('toastr').error(
                          $filter('translate')('tools.majicedigeo.majic.communeserror'));
                      }
                    );
                  }
                  else {
                    console.log(
                      'MajicFactory.hasTableCommuneInMajicDataStore - '
                            + 'Pas de table f_commune dans la source de données "majic"');
                  }
                },
                err => {
                  if (err && err.data && err.data.message){
                    console.error(err.data.message);
                  }
                  require('toastr').error(
                    $filter('translate')('tools.majicedigeo.majic.fcommuneTableError'));
                }
              );
            }
            else {
              updateMajicLeftData($scope.communes);
              updateMajicRightData($scope.communes);
            }
          }
        },
        (err) => {
          if (err && err.data && err.data.message){
            console.error(err.data.message);
          }
          require('toastr').error($filter('translate')('tools.majicedigeo.majic.majicDatastoreError'));
        }
      );
    };

    /**
            Edit modal is loaded
         */
    $scope.$on('data_modal', function(event, args) {
      $scope.modalIsLoading = true;
      $scope.usersDialog = args.dialog;

      // if user is the light version
      if (
        (angular.isUndefined($scope.edit_resource.roles) ||
          $scope.edit_resource.roles.length === 0) &&
        $scope.edit_resource.uid !== undefined
      ) {
        UsersFactory.getbyid($scope.edit_resource.uid, true).then(function(res) {
          $scope.edit_resource = res.data;
          $scope.confirmpass.pass = $scope.edit_resource.pass;
          setUserModal();
        });
      }
      else {
        $scope.confirmpass.pass = $scope.edit_resource.pass;
        setUserModal();
      }
      initPattern();
      $scope.checkPassword();
    });



    $scope.requiredData = false;
    $scope.getRequiredData = function() {
      if (!$scope.requiredData) {
        $scope.requiredData = [
          { key: $scope.edit_resource.login, tab: 0 },
          { key: $scope.edit_resource.name, tab: 0 },
          { key: $scope.edit_resource.vorname, tab: 0 },
          { key: $scope.edit_resource.pass, tab: 0 },
          { key: $scope.confirmpass.pass, tab: 0 },
          { key: $scope.edit_resource.email, tab: 0 },
        ];
      }
    };

    $scope.fileNameChanged = function(a) {
      var firstFile = a.files[0];

      var fd = new FormData();
      fd.append('file', firstFile);

      ThumbnailFactory.uploadprocess(fd).then(function(data) {
        $scope.edit_resource.thumbnail = firstFile.name;

        try {
          $scope.$apply();
        }
        catch (err) {}

        console.log($scope.edit_resource.thumbnail);
      });
    };

    /**
     * Créé ou met à jour un utilisateur
     * La variable $scope.isNewResource permet de savoir si l'utilisateur existait déjà
     * @see UsersFactory.add
     * @see UsersFactory.update
     */

    $scope.edituser = () => {
      if (
        $scope.showRestriction &&
        $scope.edit_resource.restriction &&
        $scope.edit_resource.restriction.name !==
          $filter('translate')('rights.restriction.norestriction') &&
        $scope.edit_resource.restriction.name &&
        !$scope.edit_resource.restriction.modes.viewer &&
        !$scope.edit_resource.restriction.modes.query &&
        !$scope.edit_resource.restriction.modes.edition
      ) {
        alert($filter('translate')('rights.users.norestrictionmodechoosen'));
        $scope.tabs.activeTab = 3;
        return;
      }

      if (!$scope.edit_resource.ldap && ($scope.isNewResource || $scope.edit_resource.change_password) && !$scope.edit_resource.pass.match($scope.pattern)) {
        alert($filter('translate')('rights.users.passwordDontMatchPattern'));
        return;
      }

      if ($scope.confirmpass.pass !== $scope.edit_resource.pass) {
        alert($filter('translate')('rights.users.different_passwords'));
        return;
      }
      gaDomUtils.showGlobalLoader();
      ngDialog.close($scope.usersDialog.attr('id'));

      // supprime la propriété $selected qui n'existe pas dans la classe java Group
      // précaution supplémentaire, en plus de la configuration de l'objectMapper dans UserHandler#update
      if($scope.dLBGroupData.leftData){
        const cleanedUserGroups = [];
        for (const group of $scope.dLBGroupData.leftData){
          if (group.$selected){
            delete group.$selected;
          }
          cleanedUserGroups.push(group);
        }
        $scope.edit_resource.groups = cleanedUserGroups;
      }
      else{
        $scope.edit_resource.groups = undefined;
      }
      $scope.edit_resource.roles = $scope.dLBRolesData.leftData;
      if($rootScope.xgos.isroot && $scope.dLBPortailsData) {
        $scope.edit_resource.portails = $scope.dLBPortailsData.leftData;
      }
      if ($scope.dLBMajicData && $scope.dLBMajicData.leftData) {
        // assigne un tableau des codes insee des communes majic sélectionnées
        // à la propriété user.communes
        $scope.edit_resource.communes = $scope.dLBMajicData.leftData.map(commune => commune.insee);
      }

      // Si la case de couleur a été cochée mais que la couleur n'a pas été modifiée,
      // le client a voulu laisser la couleur noir à l'utilisateur
      if($scope.edit_resource.userHasColor && !$scope.edit_resource.userColor) {
        $scope.edit_resource.userColor = '#000000';
      }

      // fullname creation before saving user configuration
      $scope.edit_resource.fullname = $scope.edit_resource.vorname + ' ' + $scope.edit_resource.name;
      if ($scope.isNewResource) {
        UsersFactory.add($scope.edit_resource, $scope.edit_resource.pass, true)
          .finally(gaDomUtils.hideGlobalLoaderAfterTimeout);
      }
      else {
        UsersFactory.update($scope.edit_resource, $scope.edit_resource.pass, true)
          .finally(gaDomUtils.hideGlobalLoaderAfterTimeout);
      }
    };

    /**
     * Remove an user
     */
    $scope.removeUser = () => {
      UsersFactory.remove($scope.edit_resource.uid).then(function() {
        $scope.tableParams.total($scope.currentResources.length).reload();
      });
    };

    /**
     * User loading
     * Also loads Groups and/or Roles if not previously loaded
     */
    $scope.currentResources = UsersFactory.resources.users;

    if ($rootScope.xgos.isroot || $rootScope.xgos.isadmin) {
      if (RolesFactory.resources.rolesLight.length === 0) RolesFactory.get(true);
      if (GroupsFactory.resources.groupsLight.length === 0) GroupsFactory.get(true);

      UsersFactory.getlight().then(function() {
        $scope.currentResources = UsersFactory.resources.users;
      });
    }
    else {
      if (UsersFactory.resources.users.length === 0) {
        if (RolesFactory.resources.rolesLight.length === 0) RolesFactory.get(true);
        if (GroupsFactory.resources.groupsLight.length === 0) GroupsFactory.get(true);

        UsersFactory.getlight().then(function() {
          $scope.currentResources = UsersFactory.resources.users;
        });
      }
    }

    // -------------------------
    // IMPORT USERS
    // -------------------------
    var _importUserDialog;
    $scope.extraAuthProviders = [];
    ExtraAuthenticationFactory.get().then(
      function(res) {
        $scope.extraAuthProviders = res.data;
      },
      function(err) {
        require('toastr').error($filter('translate')('common.error'));
      }
    );
    /**
     * importUsers
     */
    $scope.importUsersDialog = function() {
      $scope.pickedProvider = {};
      _importUserDialog = ngDialog.open({
        template:
          'js/XG/modules/authentication/views/modals/modal.user.import.html',
        className: 'ngdialog-theme-plain width800',
        closeByDocument: false,
        scope: $scope,
      });
    };


    /**
     * checkLdapUsers
     */
    let checkLdapUsers;
    $scope.checkLdapUsers = () => {
      gaDomUtils.showGlobalLoader();
      UsersFactory.checkLdapUsersAndGetFailed().then((res)=>{
        gaDomUtils.hideGlobalLoader();
        if(res && res.data && res.data.length>0){
          $scope.ldapFailedUsers = res.data;
          $scope.failedLdapTable = new ngTableParams(
            {
              page: 1, // show first page
              count: 100, // count per page
            },
            {
              total: 0,
              counts: []
            }
          );
          $scope.disableRemoveFailedUserBouton = true;
          $scope.toggleAllFailedUsers = {value:false};
          checkLdapUsers = ngDialog.open({
            template:
              'js/XG/modules/authentication/views/modals/modal.user.ldap.check.html',
            className: 'ngdialog-theme-plain width1000',
            closeByDocument: false,
            scope: $scope,
          });
        }
        else{
          require('toastr').success($filter('translate')('rights.users.ldap.checkOk'));
        }
      });
    };

    $scope.columnDelimiter = ',';
    $scope.showConfigSparator = () =>{
      let exportcsvdialog = ngDialog.openConfirm({
        template:
          'js/XG/widgets/hpoapp/analye_multicritere/views/dialog/csvFormatPrompt.html',
        className: 'ngdialog-theme-plain nopadding miniclose',
        scope: $scope,
        showClose: true,
      });
      exportcsvdialog.then((data) => {
        $scope.columnDelimiter = data;
      });
    };

    $scope.exportCsvFile = () => {
      let toExport = [];
      toExport.push([$filter('translate')('rights.extra_authentication.ldap.ldapConnectionString'),
        $filter('translate')('rights.extra_authentication.ldap.login'),
        $filter('translate')('rights.extra_authentication.ldap.lastname'),
        $filter('translate')('rights.extra_authentication.ldap.firstname'),
        $filter('translate')('rights.extra_authentication.ldap.email')]);
      $scope.ldapFailedUsers.forEach((user)=>{
        toExport.push([user.ldap_connection_string,user.login,user.vorname,user.name,user.email]);
      });
      return toExport;
    };

    $scope.removeFailedUsers = () => {
      swal(
        {
          title: $filter('translate')('rights.users.ldap.deleteFailedUsers'),
          type: 'warning',
          showCancelButton: true,
          confirmButtonColor: '#DD6B55',
          confirmButtonText: $filter('translate')('common.yes'),
          cancelButtonText: $filter('translate')('common.no'),
          closeOnConfirm: true,
          closeOnClickOutside: false,
        },(isConfirm) => {
          if (isConfirm) {
            let ldapFailedUsersToDelete = $scope.ldapFailedUsers.filter((user) => user.toDelete);
            ldapFailedUsersToDelete.forEach((user) => {
              UsersFactory.remove(user.uid).then(function() {
                $scope.ldapFailedUsers.splice($scope.ldapFailedUsers.findIndex(u => user.uid === u.uid),1);
                if($scope.ldapFailedUsers.length ===0){
                  checkLdapUsers.close();
                }
              });
            });
          }
        });
    };

    $scope.updateConnectionStrings = () => {
      swal(
        {
          title: $filter('translate')('rights.users.ldap.updateFailedUsers'),
          text: $filter('translate')('rights.users.ldap.slowOperation'),
          type: 'warning',
          showCancelButton: true,
          confirmButtonColor: '#DD6B55',
          confirmButtonText: $filter('translate')('common.yes'),
          cancelButtonText: $filter('translate')('common.no'),
          closeOnConfirm: true,
          closeOnClickOutside: false,
        },(isConfirm) => {
          if (isConfirm) {
            gaDomUtils.showGlobalLoader();
            UsersFactory.updateConnectionStrings($scope.ldapFailedUsers).then((res) =>{
              gaDomUtils.hideGlobalLoader();
              if(res && res.data && res.data.length>0){
                require('toastr').info($filter('translate')('rights.users.ldap.checkUsersNotFound'));
                $scope.ldapFailedUsers = res.data;
              }
              else{
                $scope.ldapFailedUsers = [];
                checkLdapUsers.close();
                require('toastr').success($filter('translate')('rights.users.ldap.checkOk'));
              }
            });
          }
        });
    };

    $scope.checkAllUserToDelete = () => {
      let ldapFailedUsersToDelete = $scope.ldapFailedUsers.filter((user) => user.toDelete);
      $scope.disableRemoveFailedUserBouton = ldapFailedUsersToDelete.length === 0;
      $scope.toggleAllFailedUsers.value = ldapFailedUsersToDelete.length === $scope.ldapFailedUsers.length;
    };

    $scope.toggleAllFUsers = () => {
      $scope.ldapFailedUsers.forEach((user) => {
        user.toDelete = $scope.toggleAllFailedUsers.value;
      });
      $scope.disableRemoveFailedUserBouton = !$scope.toggleAllFailedUsers.value;
    };

    $scope.disbaleUser = function() {
      var b = false;
      if (
        !$scope.selected_resource ||
        ($scope.selected_resource && !$scope.selected_resource.connected)
      )
        b = true;
      return b;
    };

    $scope.refreshList = function() {
      if (RolesFactory.resources.rolesLight.length === 0) GroupsFactory.get(true);
      if (GroupsFactory.resources.groupsLight.length === 0) RolesFactory.get(true);
      try {
        gaDomUtils.showGlobalLoader();
        UsersFactory.getlight().then(
          function() {
            $scope.currentResources = UsersFactory.resources.users;

            gaDomUtils.hideGlobalLoader();
          },
          function() {
            gaDomUtils.hideGlobalLoader();
          }
        );
      }
      catch (e) {
        gaDomUtils.hideGlobalLoader();
      }
    };

    $scope.disconnectUser = () => {
      try {
        gaDomUtils.showGlobalLoader();
        authFactory.logoutUserFromServerByUid($scope.edit_resource.uid).then(
          res => {
            if (res.data === true) {
              $scope.edit_resource.connected = false;
              $scope.currentResources.map(x => {
                if (x.uid === $scope.edit_resource.uid) {
                  x.connected = false;
                  $scope.tableParams
                    .total($scope.currentResources.length)
                    .reload();
                }
              });
              require('toastr').info(
                $scope.edit_resource.login +
                  $filter('translate')('rights.users.disconnected')
              );
            }
            else {
              require('toastr').info(
                $filter('translate')('rights.users.unabledisconnected') +
                  $scope.edit_resource.login
              );
            }
            gaDomUtils.hideGlobalLoader();
          },
          function(res) {
            require('toastr').info(
              $filter('translate')('rights.users.unabledisconnected') +
                $scope.edit_resource.login
            );
            gaDomUtils.hideGlobalLoader();
          }
        );
      }
      catch (e) {
        gaDomUtils.hideGlobalLoader();
      }
    };

    $scope.importableUsers = [];
    $scope.importUserTable = new ngTableParams(
      {
        page: 1, // show first page
        count: 10, // count per page
      },
      {
        total: $scope.importableUsers.length, // length of data
        $scope: $scope,
        getData: function($defer, params) {
          // use build-in angular filter
          params.total($scope.importableUsers.length); // set total for recalc pagination
          //$defer.resolve(scope.users = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
          //$defer.resolve(scope.data);
          $defer.resolve(
            ($scope.currentPageData = $scope.importableUsers.slice(
              (params.page() - 1) * params.count(),
              params.page() * params.count()
            ))
          );
        },
      }
    );

    var importProvider = false;

    /**
     * Retourne la valeur de l'attribut si elle existe depuis la cle issue de la config du provider
     * par ex : si le nom est stocke dans un attribut "name", return att[name] si existe, false sinon
     * @param {*} data
     * @param {*} key
     */
    var linkImportUserData = function(data, key) {
      var correspondanceKey =
        importProvider &&
        angular.isDefined(importProvider.parameters.mapping) &&
        angular.isDefined(importProvider.parameters.mapping[key])
          ? importProvider.parameters.mapping[key]
          : false;

      // console.log(importProvider.parameters.mapping);
      // console.log(correspondanceKey);

      if (correspondanceKey) {
        return angular.isDefined(data[correspondanceKey])
          ? data[correspondanceKey]
          : false;
      }
      else {
        return false;
      }
    };

    function saveQueryList() {
      ParametersFactory.updatebyname(
        $scope.dataOfQueries,
        'ldapAuthQueries'
      ).then(
        function(res) {
          swal({
            title: $filter('translate')('rights.users.import_users.query_list'),
            text: $filter('translate')(
              'rights.users.import_users.queries_saved'
            ),
            timer: 1800,
          });
        },
        function(reason) {
          require('toastr').error(reason);
        }
      );
    }

    function openQueryList() {
      var listScope = $scope.$new(true, $scope);

      listScope.deleteQuery = function(queryIndex) {
        $scope.dataOfQueries.data.queries.splice(queryIndex, 1);
        saveQueryList();
      };

      //      $scope.$on('ngDialog.closed', function(e, $dialog) {
      listScope.loadQuery = function() {
        swal(
          {
            title: $filter('translate')('rights.users.import_users.query_list'),
            text: '',
            type: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#6BDD55',
            confirmButtonText: $filter('translate')(
              'rights.users.import_users.executeAndClose'
            ),
            cancelButtonText: $filter('translate')(
              'rights.users.import_users.cancelAndStay'
            ),
            closeOnConfirm: true,
            closeOnCancel: true,
          },
          function(confirmOk) {
            if (confirmOk) {
              $timeout(function() {
                for (
                  var iQuery = 0;
                  iQuery < listScope.currentResources.length;
                  iQuery++
                ) {
                  if (listScope.currentResources[iQuery].$selected) {
                    $scope.pickedProvider.filter =
                      listScope.currentResources[iQuery].filter;
                    $scope.pickedProvider.query_filter =
                      listScope.currentResources[iQuery].query_filter;
                    $scope.pickedProvider.groupForQuery =
                      listScope.currentResources[iQuery].group;
                    $scope.selectedQuery.showGroups =
                      $scope.pickedProvider.groupForQuery !== undefined;
                    require('toastr').success('import effectué');
                    break;
                  }
                }
                queryListDlg.close();
                $scope.preImportUser();
              }, 250);
            }
          }
        );
      };
      //      });

      listScope.currentResources = $scope.dataOfQueries.data.queries;
      listScope.editListCfg = {
        dataModule: 'rights',
        resource_type: 'import_users',
        cols: ['name', 'filter', 'query_filter', 'group'],
        hideDetails: true,
        removeFunction: listScope.deleteQuery,
        addResourceButton: false,
        extraGlobalActions: [
          {
            label:
              '<label>' +
              $filter('translate')('rights.users.import_users.select_query') +
              '</label>',
            fn: listScope.loadQuery,
          },
        ],
      };
      var queryListDlg = ngDialog.open({
        template:
          'js/XG/modules/rights/views/modals/modal.users.query_list.html',
        className: 'ngdialog-theme-plain width800',
        closeByDocument: false,
        scope: listScope,
      });
    }
    $scope.openQueryList = function() {
      openQueryList();
    };

    $scope.queries = [];
    ParametersFactory.getbyname('ldapAuthQueries').then(function(res) {
      if (res.data && res.data.data && res.data.data.queries)
        $scope.dataOfQueries = res.data;
      else
        ParametersFactory.add(
          { queries: $scope.queries },
          'LDAP_CONFIG',
          'ldapAuthQueries'
        ).then(function(res) {
          if (res.data && res.data.data && res.data.data.queries)
            $scope.dataOfQueries = res.data;
        });
    });

    $scope.$watch('pickedProvider.provider', function(a1, a2) {
      if ($scope.pickedProvider) {
        ExtraAuthenticationFactory.getGroups(
          $scope.pickedProvider.provider.uid
        ).then(function(res) {
          if (res.data) {
            if (res.data.etat === 'fini') {
              $scope.dataOfQueries.data.groups = res.data.objValeur.sort();
            }
            else if (
              res.data.etat === 'erreur' &&
              res.data.hasOwnProperty('errorList') &&
              res.data.errorList &&
              res.data.errorList.length !== 0
            ) {
              var mess =
                res.data.errorList[0].composant +
                ':' +
                res.data.errorList[0].exception +
                ' -> ' +
                res.data.errorList[0].message_kis;
              require('toastr').error(mess);
            }
          }
        });
      }
    });

    $scope.selectedQuery = {};
    $scope.$watch('selectedQuery.query', function(a1, a2) {
      if ($scope.pickedProvider === undefined) $scope.pickedProvider = {};
      if ($scope.selectedQuery.query) {
        $scope.pickedProvider.filter = $scope.selectedQuery.query.filter;
        $scope.pickedProvider.query_filter =
          $scope.selectedQuery.query.query_filter;
      }
    });

    $scope.saveQuery = function() {
      swal(
        {
          title: $filter('translate')('rights.users.import_users.save_query'),
          text: $filter('translate')('rights.users.import_users.query_name'),
          type: 'input',
          showCancelButton: true,
          confirmButtonColor: '#6BDD55',
          confirmButtonText: $filter('translate')('common.yes'),
          cancelButtonText: $filter('translate')('common.no'),
          closeOnConfirm: false,
          closeOnCancel: true,
        },
        function(inputValue) {
          var query;
          if (inputValue === '') {
            swal.showInputError(
              $filter('translate')(
                'rights.users.import_users.query_name_mandatory'
              )
            );
            return false;
          }
          else if (inputValue) {
            //-- inputValue vaut FALSE quand on clique sur "Cancel" (Non").
            query = {
              name: inputValue,
              filter: $scope.pickedProvider.filter,
              query_filter: $scope.pickedProvider.query_filter,
            };
            if ($scope.selectedQuery.showGroups)
              query.group = $scope.pickedProvider.groupForQuery;
            $scope.dataOfQueries.data.queries.push(query);
            saveQueryList();
          }
        }
      );
    };

    function loadUsers(res) {
      $scope.pickedProvider.searched = true;

      const { users, error } = res.data;

      $scope.tooManyUsersErrror = false;
      if (error) {
        $scope.tooManyUsersErrror = error.indexOf('Sizelimit') !== -1;
        require('toastr').error(error);
      }

      users.forEach(function(u) {
        var login = linkImportUserData(u, 'login'),
          name = linkImportUserData(u, 'name'),
          vorname = linkImportUserData(u, 'vorname'),
          email = linkImportUserData(u, 'email');

        if (login) {
          var loginExists = false;

          loginExists =
            $scope.currentResources
              .map(r => r.login)
              .indexOf(login) !== -1;

          $scope.importableUsers.push({
            providerData: u,
            // data: getimportUserDataFromCfg()
            data: {
              login: login,
              name: name,
              vorname: vorname,
              fullname: name + ' ' + vorname,
              email: email,
              pickable: login && !loginExists,
              loginExists: loginExists,
            },
          });
        }
      });

      $scope.importUserTable.reload();
      gaDomUtils.hideGlobalLoader();
    }

    function getUsersOfGroup() {
      ExtraAuthenticationFactory.getGroupMembers(
        $scope.pickedProvider.provider.uid,
        $scope.pickedProvider.groupForQuery,
        $scope.pickedProvider.filter
      ).then(
        function(res) {
          loadUsers(res);
        },
        function(err) {
          require('toastr').error($filter('translate')('common.error'));
          gaDomUtils.hideGlobalLoader();
        }
      );
    }

    function getUsersFromFilters() {
      // retrieve users
      ExtraAuthenticationFactory.getusers({
        uid: $scope.pickedProvider.provider.uid,
        filter: $scope.pickedProvider.filter,
        query_filter: $scope.pickedProvider.query_filter,
      }).then(
        function(res) {
          loadUsers(res);
        },
        function(err) {
          require('toastr').error($filter('translate')('common.error'));
          gaDomUtils.hideGlobalLoader();
        }
      );
    }
    /**
     * preImportUser
     */
    $scope.preImportUser = function() {
      $scope.importableUsers = [];
      $scope.usersToImport = {};
      $scope.toggleAllImportUser = { v: false };

      gaDomUtils.showGlobalLoader();

      // retrieve provider
      ExtraAuthenticationFactory.getbyid(
        $scope.pickedProvider.provider.uid
      ).then(
        function(res) {
          importProvider = res.data;

          if ($scope.selectedQuery.showGroups) {
            getUsersOfGroup();
          }
          else {
            getUsersFromFilters();
          }
        },
        function(err) {
          require('toastr').error($filter('translate')('common.error'));
          gaDomUtils.hideGlobalLoader();
        }
      );
    };

    // toggleAllImportUser on click, toggle toutes les checkboxes
    $scope.$watch(
      'toggleAllImportUser',
      function(tga) {
        $scope.importableUsers.forEach(function(u) {
          if (u.data.pickable) $scope.usersToImport[u.data.login] = tga.v;
        });
      },
      1
    );

    // verifie si presence d'user à importer ou aucun
    $scope.noUserToImport = function() {
      var nbUser = 0;
      for (var i in $scope.usersToImport) {
        if ($scope.usersToImport[i] == true) {
          nbUser++;
        }
      }
      return nbUser == 0;
    };

    /**
     * importUsers depuis provider externe
     */
    $scope.importUsers = function() {
      const users = [];
      for (let i in $scope.usersToImport) {
        if ($scope.usersToImport[i] === true) {
          const userData = $scope.importableUsers.filter(x => x.data.login === i)[0];

          users.push({
            login: i,
            name: userData.data.name ? userData.data.name : '',
            vorname: userData.data.vorname ? userData.data.vorname : '',
            email: userData.data.email ? userData.data.email : '',
            ldap_provider_uid: $scope.pickedProvider.provider.uid,
            ldap_connection_string:
              userData.providerData.ldap_connection_string,
          });
        }
      }

      gaDomUtils.showGlobalLoader();
      ExtraAuthenticationFactory.importusers(users).then(
        function(res) {
          require('toastr').success('import effectué');
          UsersFactory.getlight().then(function() {
            $scope.currentResources = UsersFactory.resources.users;

            _importUserDialog.close();
            gaDomUtils.hideGlobalLoader();
            $scope.tableParams.reload();
          });
        },
        () => {
          require('toastr').error($filter('translate')('common.error'));
          gaDomUtils.hideGlobalLoader();
        }
      );
    };

    if ($rootScope.xgos.isroot || $rootScope.xgos.isadmin) {
      /*
             EditList Directive configuration
             */
      var editListCfg = {
        dataModule: 'rights',
        resource_type: 'users',
        cols: [
          'login',
          'name',
          'vorname',
          'email',
          'leaving_date',
          'connected',
        ],
        colsCss: [{ leaving_date: 'leaving_date' }],
        colsFunction: { connected: 'booleanToCheck' },
        removeFunction: $scope.removeUser,
        extraGlobalActions: [
          {
            label: 'rights.users.disconnect',
            fn: $scope.disconnectUser,
            disablefn: $scope.disbaleUser,
          },
          {
            label: 'rights.users.refresh',
            fn: $scope.refreshList,
          },
        ],
      };
    }
    else {
      /*
             EditList Directive configuration
             */
      editListCfg = {
        dataModule: 'rights',
        resource_type: 'users',
        cols: ['login', 'name', 'vorname', 'email', 'leaving_date'],
        colsCss: [{ leaving_date: 'leaving_date' }],
        removeFunction: $scope.removeUser,
      };
    }

    // si active et length>0
    if (
      gaJsUtils.checkNestedProperty(
        'portal.parameters.extra_authentication.active',
        $scope.xgos
      ) !== false
    ) {

      $translate('rights.users.ldap.check').then(translated => {
        editListCfg.extraGlobalActions.push({
          icon: `<i class='glyphicon glyphicon-check' title="${translated}"></i>`,
          fn: $scope.checkLdapUsers,
        });
      });
      // Make sure the translation is available at page loading
      $translate('rights.users.import_users.title').then(translated => {
        editListCfg.extraGlobalActions.push({
          icon: `<i class='fa fa-upload' title="${translated}"></i>`,
          fn: $scope.importUsersDialog,
        });
      });
    }

    $scope.editListCfg = editListCfg;

    $scope.validForm = {};
    $scope.validateLogin = function() {
      var actualLogin = $scope.edit_resource.login;
      $scope.$watch(
        'edit_resource.login',
        function(login) {
          $scope.loginExists =
            $scope.currentResources
              .map(r => r.login)
              .indexOf(login) !== -1;
          if (
            !$scope.isNewResource &&
            $scope.edit_resource !== null &&
            $scope.edit_resource.login === actualLogin
          )
            $scope.loginExists = false;
          $scope.validForm.login = !$scope.loginExists;
        },
        1
      );
      var actualEmail = $scope.edit_resource.email;
      $scope.$watch(
        'edit_resource.email',
        function(email) {
          $scope.emailExists =
            $scope.currentResources
              .map(res => res.email)
              .indexOf(email) !== -1;
          if (
            !$scope.isNewResource &&
            $scope.edit_resource !== null &&
            $scope.edit_resource.email === actualEmail
          )
            $scope.emailExists = false;
          $scope.validForm.email = !$scope.emailExists;
        },
        1
      );
    };

    let initPattern = () => {
      if(!$rootScope.xgos.portal.parameters || !$rootScope.xgos.portal.parameters.settingPwd){
        $scope.pattern = '(?=(.*[A-Z]){1,})(?=(.*[a-z]){1,})(?=(.*\\d){1,})(?=(.*\\W){1,}).{10,50}';
        $scope.minimumNumberUppercase = 1;
        $scope.minimumNumberLowercase = 1;
        $scope.minimumNumberDigits = 1;
        $scope.minimumNumberSpecialCharacters = 1;
        $scope.minimumNumberTotalCharacters = 10;
      }
      else{
        $scope.pattern = '(?=(.*[A-Z]){$1,})(?=(.*[a-z]){$2,})(?=(.*\\d){$3,})(?=(.*\\W){$4,}).{$5,50}';
        if($rootScope.xgos.portal.parameters.settingPwd.minimumNumberUppercase){
          $scope.pattern = $scope.pattern.replace('$1',$rootScope.xgos.portal.parameters.settingPwd.minimumNumberUppercase);
          $scope.minimumNumberUppercase = $rootScope.xgos.portal.parameters.settingPwd.minimumNumberUppercase;
        }
        else{
          $scope.pattern = $scope.pattern.replace('$1',0);
        }
        if($rootScope.xgos.portal.parameters.settingPwd.minimumNumberLowercase){
          $scope.pattern = $scope.pattern.replace('$2',$rootScope.xgos.portal.parameters.settingPwd.minimumNumberLowercase);
          $scope.minimumNumberLowercase = $rootScope.xgos.portal.parameters.settingPwd.minimumNumberLowercase;
        }
        else{
          $scope.pattern = $scope.pattern.replace('$2',0);
        }
        if($rootScope.xgos.portal.parameters.settingPwd.minimumNumberDigits){
          $scope.pattern = $scope.pattern.replace('$3',$rootScope.xgos.portal.parameters.settingPwd.minimumNumberDigits);
          $scope.minimumNumberDigits = $rootScope.xgos.portal.parameters.settingPwd.minimumNumberDigits;
        }
        else{
          $scope.pattern = $scope.pattern.replace('$3',0);
        }
        if($rootScope.xgos.portal.parameters.settingPwd.minimumNumberSpecialCharacters){
          $scope.pattern = $scope.pattern.replace('$4',$rootScope.xgos.portal.parameters.settingPwd.minimumNumberSpecialCharacters);
          $scope.minimumNumberSpecialCharacters = $rootScope.xgos.portal.parameters.settingPwd.minimumNumberSpecialCharacters;
        }
        else{
          $scope.pattern = $scope.pattern.replace('$4',0);
        }
        if($rootScope.xgos.portal.parameters.settingPwd.minimumNumberTotalCharacters){
          $scope.pattern = $scope.pattern.replace('$5',$rootScope.xgos.portal.parameters.settingPwd.minimumNumberTotalCharacters);
          $scope.minimumNumberTotalCharacters = $rootScope.xgos.portal.parameters.settingPwd.minimumNumberTotalCharacters;
        }
        else{
          $scope.pattern = $scope.pattern.replace('$5',0);
        }
      }
    };

    $scope.checkPassword = () => {
      if($scope.minimumNumberUppercase && $scope.edit_resource.pass && $scope.edit_resource.pass.match(
        '(?=(.*[A-Z]){'+$scope.minimumNumberUppercase+',}).{'+$scope.minimumNumberUppercase+',50}')){
        $scope.minimumNumberUppercaseValid = true;
      }
      else{
        $scope.minimumNumberUppercaseValid = false;
      }
      if($scope.minimumNumberLowercase && $scope.edit_resource.pass &&  $scope.edit_resource.pass.match(
        '(?=(.*[a-z]){'+$scope.minimumNumberLowercase+',}).{'+$scope.minimumNumberLowercase+',50}')){
        $scope.minimumNumberLowercaseValid = true;
      }
      else{
        $scope.minimumNumberLowercaseValid = false;
      }
      if($scope.minimumNumberDigits && $scope.edit_resource.pass && $scope.edit_resource.pass.match(
        '(?=(.*\\d){'+$scope.minimumNumberDigits+',}).{'+$scope.minimumNumberDigits+',50}')){
        $scope.minimumNumberDigitsValid = true;
      }
      else{
        $scope.minimumNumberDigitsValid = false;
      }
      if($scope.minimumNumberSpecialCharacters && $scope.edit_resource.pass && $scope.edit_resource.pass.match(
        '(?=(.*\\W){'+$scope.minimumNumberSpecialCharacters+',}).{'+$scope.minimumNumberSpecialCharacters+',50}')){
        $scope.minimumNumberSpecialCharactersValid = true;
      }
      else{
        $scope.minimumNumberSpecialCharactersValid = false;
      }
      if($scope.minimumNumberTotalCharacters && $scope.edit_resource.pass && $scope.edit_resource.pass.match(
        '.{'+$scope.minimumNumberTotalCharacters+',50}')){
        $scope.minimumNumberTotalCharactersValid = true;
      }
      else{
        $scope.minimumNumberTotalCharactersValid = false;
      }
    };


    $scope.changedViewer = function(modes) {
      modes.query = true;
      modes.edition = true;
    };

    /**
     * Edition de la restriction d'un utilisateur.
     * L'option "Aucune restriction", équivalent à une option vide, désactive les modes
     */
    $scope.onUserRestrictionChange = () => {
      const noRestriction = $filter('translate')('rights.restriction.norestriction');
      if ((!$scope.edit_resource.restriction || $scope.edit_resource.restriction.name === noRestriction
          || $scope.edit_resource.restriction.modes.userchoice) && $scope.edit_resource.restriction.modes) {
        $scope.edit_resource.restriction.modes.edition = false;
        $scope.edit_resource.restriction.modes.query = false;
        $scope.edit_resource.restriction.modes.viewer = false;
      }
      if ($scope.edit_resource.restriction.name === noRestriction) {
        $scope.edit_resource.restriction.modes = {
          userchoice: false,
          edition: false,
          query: false,
          viewer: false
        };
      }
    };

    /**
     * Edition de la restriction d'un utilisateur
     * Lorsque le mode "Requête" est sélectionné alors le mode "Edition" est sélectionné également
     */
    $scope.onQueryRestrictionModeChange = () => {
      if ($scope.edit_resource.restriction.modes.query) {
        $scope.edit_resource.restriction.modes.edition = true;
      }
    };
  };

  UsersCtrl.$inject = [
    '$scope',
    'UsersFactory',
    'GroupsFactory',
    'RolesFactory',
    '$filter',
    '$translate',
    'ngDialog',
    'RestrictionFactory',
    '$rootScope',
    'ExtraAuthenticationFactory',
    'gaJsUtils',
    'ngTableParams',
    '$timeout',
    'gaDomUtils',
    'authFactory',
    'ThumbnailFactory',
    'ParametersFactory',
    'PortalsFactory',
    'MajicFactory'
  ];
  return UsersCtrl;
});
