'use strict';

/**
 * @ngdoc controller
 * @name modules.authentication.controller:AuthCtrl
 * @description
 * The AuthCtrl controller
 */
define(function() {
  var AuthCtrl = function(
    $scope,
    $rootScope,
    $q,
    $location,
    authFactory,
    PortalsFactory,
    $filter,
    ngDialog,
    UsersFactory,
    versionsFactory,
    $timeout,
    licenceFactory
  ) {
    /**
     * Application user
     * @type {{login: string, password: string}}
     */
    /* $scope.user = {
             login: 'root', password: 'g2c'
         };*/
    // Variable pour le message RGPD
    $scope.RGPD_LOGIN_MESSAGE = "";

    // fill rgpdmessage variable
    authFactory.getrgpdmessage().then((res) =>{
      $scope.RGPD_LOGIN_MESSAGE = res.data
    })
    

    $scope.userLoggedOnLoad = typeof $rootScope.xgos.user != 'undefined';
    $scope.needToChangePwd = false;
    if ($scope.userLoggedOnLoad)
      authFactory.redirectAfterLogin();

    /**
     * Récupère les éventuels fichiers html/css 'notif_info' présents dans le dosssier 'CSS-HTML'
     * du repo.
     * @param portalId uid identifiant du portail
     */
    const getPortalNotifInfo = (portalId) => {
      PortalsFactory.getPortalNotifInfo(portalId).then((res)=>{
        const notifInfoElement = document.querySelector('.notif-info-container');
        if (typeof res === 'boolean' && res && notifInfoElement) {
          notifInfoElement.style.display = 'block';
        }
      },
      err => {
        require('toastr').error(
            $filter('translate')('portals.css.getNotifError') +
            err.message ? err.message : '');
      });
    };

    if (!$rootScope.xgos.portal) {
      let currentPortal = PortalsFactory.getPortalId();
      // is there a portal parameter ?
      // if not, we try a root login
      if (typeof $location.search()['portal'] == 'undefined') {
        if (currentPortal === null) {
          PortalsFactory.setPortal('-');
        }
        // else we set the portal
      } else {
        currentPortal = $location.search()['portal'];
        PortalsFactory.setPortal($location.search()['portal']);
      }
      getPortalNotifInfo(currentPortal);
    }else {
      getPortalNotifInfo($rootScope.xgos.portal.uid);
    }

    /**
     * User login
     * @returns {*}
     */
    $scope.login = () => {
      // returns a promise so the form state
      // changes when the promise is answered
      var loginPromise = $q.defer();

      $scope.loginForm.submitted = false;

      // form is valid
      if ($scope.loginForm.$valid) {
        var app = $location.search()['app'];

        if (angular.isUndefined(app)) {
          app = 'admin';
        }

        var goto_home = false;
        if ($location.search()['goto'] == 'home') {
          goto_home = true;
        }
        // @TODO RB: tmp, fix that
        if ($location.search()['goto'] == 'calendar_invite') {
          goto_home = true;
        }

        // Successful login
        loginFn($scope.user, app, goto_home).then(() => {
            loginPromise.resolve();
          },
          // Error (invalid credentials)
          function(err) {
            if (err.status === 900) {
              switch (err.data) {
                case 'reject.user.connected':
                  $scope.loginForm.error_message = err.data;
                  $scope.loginForm.submitted = true;
                  break;
                case 'reject.user.licence.expired':
                  $scope.loginForm.error_message =
                    $filter('translate')(err.data) +
                    ' ' +
                    err.data.details[0];
                  $scope.loginForm.submitted = true;
                  break;
                case 'reject.user.licence.application':
                  $scope.loginForm.error_message =
                    $filter('translate')(err.data) +
                    ' ' +
                    err.data.details[0].split(';').join(' , ');
                  $scope.loginForm.submitted = true;
                  break;
                default :
                  $scope.loginForm.error_message = $filter('translate')(
                    err.data
                  );
                  $scope.loginForm.submitted = true;
                  break;
              }
            } else {
              $scope.loginForm.error_message = 'login.invalid_credentials';
              $scope.loginForm.submitted = true;
            }
            loginPromise.reject();
          }
        );

        // form isn't valid
      } else {
        $scope.loginForm.error_message = 'login.empty_login_or_password';
        $scope.loginForm.submitted = true;
        loginPromise.reject();
      }

      return loginPromise.promise;
    };

    let loginFn = (user, app, gotohome, KisAncCfg, ctCnt) =>{
      var def = $q.defer();
      if (ctCnt == undefined) ctCnt = 0;
      if (++ctCnt > 3) {
        alert('server injoignable !');
        return;
      }

      authFactory.getToken(user, app, gotohome).then((response) => {
          // server gave a token
          if (response.data && response.data != '') {
            // dans le cas ou un portal n'existe pas sur l'application, on reload avec "-" pour ne pas être bloquer en interface
            if(response.data.code === 403 && response.data.CLASSTYPE === 'PORTAL_NOT_FOUND'){
              PortalsFactory.setPortal('-')
              loginFn(user, app, gotohome, KisAncCfg, ctCnt).then(()=>{
                def.resolve();
              },(err)=>{
                def.reject(err);
              });
            } else {
              $scope.tempToken = response.data;
              if( PortalsFactory.getPortalId() !== '-' &&  user.login !== 'root'){
                authFactory.needToChangePwd($scope.tempToken).then((res)=>{
                  if(res.data !=='false'){
                    $scope.renewalPwdTitle = $filter('translate')(res.data);
                    PortalsFactory.getByUid(PortalsFactory.getPortalId(),$scope.tempToken).then((res2)=>{
                      def.resolve();
                      $scope.needToChangePwd = true;
                      $rootScope.xgos.portal = res2.data;
                      initPattern();
                    })
                  }else{
                    postGetToken(user, KisAncCfg, def);
                  }
                },() =>{
                  postGetToken(user, KisAncCfg, def);
                })
              }else{
                postGetToken(user, KisAncCfg, def);
              } 
            }
            // server returned nothing
          } else {
            def.reject('Invalid credentials');
          }
        },(err) => {
            def.reject(err);
        }
      );

      return def.promise;
    }

    let postGetToken = (user, KisAncCfg, def) =>{
        localStorage.setItem('auth_token', $scope.tempToken);
        localStorage.setItem('auth_token1', $scope.tempToken);
        if (
          PortalsFactory.getPortalId() == undefined &&
          KisAncCfg != undefined
        )
          localStorage.setItem('portal', KisAncCfg.portalid);

        // retrieve portals list
        PortalsFactory.get().then(() => {
              // dans le cas ou on a un seul portail, on va considérer que c'est le portail de l'utilisateur
              // dans le cas ou l'utilisateur c'est root on va considérer que c'est le premier portail
              if (
                  PortalsFactory.getPortalId() === '-' &&
                  (user.login === 'root' && (PortalsFactory.resources.portals.length > 0) ||
                  (PortalsFactory.resources.portals.length === 1))
              ) {
                // gotta retrieve the portal
                const firstPortal = PortalsFactory.resources.portals[0].uid;
                PortalsFactory.setPortal(firstPortal);
              }
              try {
                licenceFactory.getAllLicences().then(() => {
                      const licence = licenceFactory.getLicence(
                          $rootScope.portalChosen
                      );
                      if (licence && licence.type !== 'free') {
                        licenceFactory.checkLicence(licence);
                      }
                      authFactory.getcurrentuser().then(() => {
                        def.resolve();
                        authFactory.redirectAfterLogin();
                      });
                    }, () => {
                      authFactory.getcurrentuser().then(() => {
                        def.resolve();
                        authFactory.redirectAfterLogin();
                      });
                    }
                );
              } catch (e) {
                console.error(e);
                authFactory.getcurrentuser().then(() => {
                  def.resolve();
                  authFactory.redirectAfterLogin();
                });
              }
            },() => {
            def.reject('Server error ?');
          }
        );
    }

    $scope.changepw = () => {
      var def = $q.defer();
      if (!$scope.user.newPassword || !$scope.user.ConfirmPassword || $scope.user.newPassword!==$scope.user.ConfirmPassword) {
        alert($filter('translate')('rights.users.different_passwords'));
        def.reject();
        return def.promise;
      }
      if ($scope.user.newPassword && !$scope.user.newPassword.match($scope.pattern)) {
        alert($filter('translate')('rights.users.passwordDontMatchPattern'));
        def.reject();
        return def.promise;
      }
      authFactory.updateUserPW($scope.tempToken,$scope.user.newPassword).then((res)=>{
        postGetToken($scope.user, undefined , def);
      },(err)=>{
        alert($filter('translate')(err.data));
        def.reject();
      })
      return def.promise;
    }

    /**
     * User logout
     */
    $scope.logout = function() {
      authFactory.logout();
    };

    /**
     * Go back to the admin sector (only for root atm)
     */
    $scope.gotoadmin = function() {
      $location.path('/');
    };

    /**
     * User chooses an action from the droplist
     * @param action
     */
    $scope.userAction = function(action) {};

    $scope.displayVersion = function() {
      accountModale = ngDialog.open({
        template:
          'js/XG/modules/authentication/views/modals/modal.versions.html',
        className: 'ngdialog-theme-plain kisVersions miniclose nopadding',
        closeByDocument: false,
        scope: $scope,
      });
    };

    var setUserActions = function() {
      $scope.userActions = [
        {
          text:
            '<i class=\'fa fa-cog\'></i>' + $filter('translate')('common.profil'),
          click: 'change_password()',
        },
        {
          text:
            '<i class=\'fa fa-tag\'></i>' +
            $filter('translate')('common.current_version') +
            ' ' +
            (angular.isDefined($scope.versionsData.current)
              ? $scope.versionsData.current
              : '') +
              '<br>' +
              (angular.isDefined($scope.indigauVersion)
                ? '<i>. . .  </i>' + $scope.indigauVersion
                : ''),
          click: 'displayVersion()',
        },
        {
          text:
            '<i class=\'fa fa-pencil-square-o\'></i>' +
            $filter('translate')('common.logout'),
          click: 'logout()',
        },
      ];
    };


    $scope.versionsData = {};

    const thisGetVersion = () => {
      if (!$rootScope.xgos.sector || $rootScope.xgos.sector==='login') {
        $timeout(() => {
          thisGetVersion();
        }, 1500);
      }
      else {
        versionsFactory.getVersions($rootScope.xgos.sector).then((res) => {
          $scope.versionsData = res[0];
          $scope.versionTreeData = res[1];
          if (res.length == 3) {
            $scope.indigauVersion = res[2];
          }
          setUserActions();
        });
      }
    };

    thisGetVersion();


    setUserActions();
    $rootScope.$on('$translateChangeEnd', function() {
      setUserActions();
    });

    $scope.currentuserdata = {};
    var getUser = function() {
      UsersFactory.token().then(function(res) {
        if (res.data.code == 403) {
          authFactory.goToLogin(true);
        } else {
          $scope.currentuser = res.data;
          $scope.currentuserdata.login = res.data.login;
          $scope.currentuserdata.password = res.data.pass;
          $scope.currentuserdata.confirm_password = res.data.pass;
          $timeout(() => {
            initPattern();
            $scope.checkPassword($scope.currentuserdata.password);
          });
         
        }
      });
    };
    getUser();
    var accountModale;
    $scope.change_password = function() {
      if (angular.equals($scope.currentuserdata, {})) {
        UsersFactory.token().then(function(res) {
          $scope.currentuser = res.data;
          $scope.currentuserdata.login = res.data.login;
          $scope.currentuserdata.password = res.data.pass;
          $scope.currentuserdata.confirm_password = res.data.pass;

          accountModale = ngDialog.open({
            template:
              'js/XG/modules/authentication/views/modals/modal.user.edit.html',
            className: 'ngdialog-theme-plain width500 miniclose nopadding',
            closeByDocument: false,
            scope: $scope,
          });
        });
      } else {
        accountModale = ngDialog.open({
          template:
            'js/XG/modules/authentication/views/modals/modal.user.edit.html',
          className: 'ngdialog-theme-plain width500 miniclose nopadding',
          closeByDocument: false,
          scope: $scope,
        });
      }
    };

    $scope.close_dialog = function() {
      accountModale.close();
    };

    $scope.updateuser = function() {
      if (!$scope.currentuserdata.password.match($scope.pattern)) {
        alert($filter('translate')('rights.users.passwordDontMatchPattern'));
        return;
      }
      $scope.currentuser.pass = $scope.currentuserdata.password;
      UsersFactory.update($scope.currentuser, $scope.currentuserdata.password);
      getUser();
      accountModale.close();
    };

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

    /**
     * Au clic sur le bouton close de la popup "notif-info",
     * masque la div ayant la classe CSS "notif-info-container"
     */
     $scope.hideNotifInfo = () =>{
      const notifInfoElement = document.querySelector('.notif-info-container');
      if (notifInfoElement) {
        notifInfoElement.style.display = 'none';
      }
    };
    
  };

  AuthCtrl.$inject = [
    '$scope',
    '$rootScope',
    '$q',
    '$location',
    'authFactory',
    'PortalsFactory',
    '$filter',
    'ngDialog',
    'UsersFactory',
    'versionsFactory',
    '$timeout',
    'licenceFactory'
  ];
  return AuthCtrl;
});
