'use strict';

/**
 * @ngdoc service
 * @name modules.authentication.service:AuthFactory
 * @description
 * The authentication factory
 */
define(function() {
  var authFactory = function(
    $http,
    $q,
    $location,
    $rootScope,
    PortalsFactory,
    $timeout,
    licenceFactory,
    ThemesFactory,
    gaJsUtils,
    AncAppFactory,
    homeFactory) {
    var resources = { currentUser: null };

    /**
     * getrgpdmessage
     * @returns {HttpPromise}
     */
    function getrgpdmessage() {
      return $http.get('/services/{portalid}/connect/getrgpdmessage?f=json');
    }


    /**
     * User logout
     */
    function logout(s) {
      if (s) {
        clearStorageAndSetPortal();

        // reset global object
        $rootScope.xgos = {};

        goToCleanLogout();
      } else {
        logoutUserFromServer().then(
          function(res) {
            if (res.data === true) {
              clearStorageAndSetPortal();

              // reset global object
              $rootScope.xgos = {};

              goToCleanLogout();
            }
          },
          function() {
            clearStorageAndSetPortal();

            // reset global object
            $rootScope.xgos = {};

            goToCleanLogout();
          }
        );
        //goToLogin();
      }
    }

    /**
     * Function: getMe
     */
    function getMe() {
      if (resources.currentUser != null && resources.currentUser != '') {
        var def = $q.defer();
        def.resolve(resources.currentUser);
        return def.promise;
      } else {
        return getcurrentuser();
      }
    }

    /**
     * getToken
     * @param user
     * @param app
     * @param gotohome
     * @returns {HttpPromise}
     */
    function getToken(user, app, gotohome) {
      gotohome = gotohome ? '1' : '0';

      var usr = angular.copy(user);

      usr.login = encodeURIComponent(user.login);
      usr.password = encodeURIComponent(user.password);

      var promise = $http.get(
        '/services/{portalid}/connect/gettoken?' +
          'u=' +
          usr.login +
          '&' +
          'p=' +
          usr.password +
          '&app=' +
          app +
          '&gotohome=' +
          gotohome +
          '&lang=' +
          localStorage.getItem('current_language')
      );
      promise.then(function(res) {
        resources.currentUser = usr;
      });
      return promise;
    }

    /**
     * oidclogin
     * @param user
     * @param app
     * @param oidctoken
     * @param portalid
     * @param gotohome
     * @returns {HttpPromise}
     */
    function oidclogin(user, app, oidctoken, portalid, gotohome) {
      gotohome = gotohome ? '1' : '0';

      var usr = angular.copy(user);
      usr.login = encodeURIComponent(user.login);

      var promise = $http.get(
        '/services/'+portalid+'/connect/oidclogin?' +
          'username=' +
          usr.login +
          '&app=' +
          app +
        //          'galilee_carte'+
          '&oidctoken=' +
          oidctoken +
          '&portalid=' +
          portalid +
          '&gotohome=' +
          gotohome +
        //          '1' +
          '&lang=' +
          localStorage.getItem('current_language')
      );
      promise.then(function(res) {
        resources.currentUser = usr;
      });
      return promise;
    }

    /**
     * needToChangePwd
     * @param token
     * @returns {HttpPromise}
     */
    function needToChangePwd(token) {

      return $http.get('/services/{portalid}/connect/needToChangePwd?token=' +token);
    }

    /**
     * updateUserPW
     * @param token
     * @param password
     * @returns {HttpPromise}
     */
    function updateUserPW(token,password) {

      return $http.post('/services/{portalid}/connect/updateUserPW?token=' +
          token,{'password': password});
    }

    /**
     * getToken
     * @param user
     * @param app
     * @param gotohome
     * @returns {HttpPromise}
     */
    function logoutUserFromServer() {
      var promise = $http.get('/services/{portalid}/connect/logout?f=json&');
      promise.then(function(res) {});
      return promise;
    }

    /**
     * getToken
     * @param user
     * @param app
     * @param gotohome
     * @returns {HttpPromise}
     */
    function logoutUserFromServerByUid(uid) {
      var promise = $http.get(
        '/services/{portalid}/connect/logoutAdmin?f=json&uid=' + uid
      );
      promise.then(function(res) {});
      return promise;
    }

    /**
     * getToken
     * @param user
     * @param app
     * @param gotohome
     * @returns {HttpPromise}
     */
    function logoutUserFromServerSync() {
      var xhr = new XMLHttpRequest();
      xhr.open(
        'GET',
        '/services/' +
          $rootScope.portalChosen +
          '/connect/logout?f=json&token=' +
          encodeURIComponent(localStorage.getItem('auth_token')),
        false
      );
      xhr.onload = function(e) {
        if (xhr.readyState === 4) {
          if (xhr.status === 200) {
            console.log('user disconnected');
          } else {
            console.error(xhr.statusText);
          }
        }
      };
      xhr.onerror = function(e) {
        console.error(xhr.statusText);
      };
      xhr.send(null);
    }

    /**
     * Function: getcurrentuser
     */
    function getcurrentuser() {
      var promise = $http.get(
        '/services/{portalid}/connect/getcurrentuser?f=json'
      );
      promise.then(function(res) {
        //-- Pour une raison inconnue le token obtenu est vidé.
        //-- Dans ce cas on récupére sa sauvegarde pour pouvoir continuer
        //-- le lancement initial de l'application.
        if (
          localStorage.auth_token == undefined &&
          localStorage.auth_token1 != undefined
        )
          localStorage.auth_token = localStorage.auth_token1;

        if (res.data.code === 403) {
          // user cant access the resource
          let portalid = $location.search()['portal'];
          if (!portalid) {
            portalid = PortalsFactory.getPortalId();
          }
          if (portalid !== null) {
            PortalsFactory.getClientCss(portalid);
          }
        } else {
          $rootScope.xgos.isroot = res.data.login == 'root';
          $rootScope.xgos.isadmin = res.data.login == 'root';
          $rootScope.xgos.isSuperAdmin = res.data.login == 'root';

          $rootScope.xgos.user = res.data;

          // Vérification des rôles
          if (angular.isArray(res.data.roles)) {
            for (var i in res.data.roles) {
              if (res.data.roles[i].name == 'rootUser')
                $rootScope.xgos.isadmin = true;
              if (res.data.roles[i].name == 'sRootUser') {
                $rootScope.xgos.isadmin = true;
                $rootScope.xgos.isSuperAdmin = true;
              }
            }
          }

          // Vérification des groupes
          if (angular.isArray(res.data.groups)) {
            for (const group of res.data.groups) {
              if (angular.isArray(group.roles)) {
                for (const role of group.roles) {
                  if (role.name == 'rootUser')
                    $rootScope.xgos.isadmin = true;
                  if (role.name == 'sRootUser') {
                    $rootScope.xgos.isadmin = true;
                    $rootScope.xgos.isSuperAdmin = true;
                  }
                }
              }
            }
          }

          resources.currentUser = res.data;
          // ré-initialise le thème courant et supprime la variable locale
          // applique le thème de l'utilisateur si le portail le permet
          ThemesFactory.applyUserTheme(resources.currentUser.theme);
        }
        /**
         * Vérification pour lancer ou non le service de check,selon la configuration
         */
        if (
          AncAppFactory.getAppCfgServicesChecksExecuteOrNot('checkPortalData')
        ) {
          PortalsFactory.executeCheckPortalData();
          /**
           * Maj de la configuration des services Checks
           */
          AncAppFactory.majAppCfgServicesChecks('checkPortalData');
        }
      });

      return PortalsFactory.setPortal().then(function() {
        return promise;
      });
    }

    /**
     * Return whether the user is logged
     * @returns {*}
     */
    function userLogged() {
      var def = $q.defer();
      if (!localStorage.auth_token) {
        def.reject();
      } else {
        // clean secureSingleSession when logout occurs
        /*if(secureSession=='logout') {
                    console.log('da');
                    delete sessionStorage.secureSingleSession;
                }*/

        // there is a token and the user is known
        //if($rootScope.xgos.user){
        if (0) {
          def.resolve();
          // the user isn't known, retrieve it
        } else {
          getcurrentuser().then(
            function(res) {
              if (res.data.code == 403) {
                def.reject();
              } else {
                def.resolve();
              }
            },
            function() {
              def.reject();
            }
          );
        }
      }

      return def.promise;
    }

    var setGoToParameters = function() {
      if ($location.path() && $location.path() != '') {
        var goto = $location.path().replace(/\//, '');
        //      console.log(goto);
        //-- Ne pas changer le goto quand on se déconnecte
        //-- "goto=='logout'", sinon en se déconnectant de la carte
        //-- puis en voulant se reconnecter, on n'accéde plus à la carte
        //-- mais au module d'administration !!!!!
        if (goto != '503/' && goto != '404/' && goto != 'logout/') {
          $location.search('goto', goto);
        }
      }
    };
    /**
     * Redirect to the login page
     */
    function goToLogin(force) {

      const promise = $http.get('/services/{portalid}/connect/logintype');

      promise.then(response =>
      {

        let loginType = -1;
        loginType = response.data;

        const redirect = () => {
          const shortPath = $location.path().replace(/\//g, '');

          if (shortPath !== 'login' && shortPath !== 'loginoidc' && shortPath !== 'oidclogged') {
            // -- kis-3764: "setGoToParameters" ne doit pas être exécuté quand le path est
            // -- un path de login, sinon, le goto=type_d_application devient goto=login, et
            // -- on est renvoyé vers l'administration à condition d'y être autorisé, et
            // -- non vers l'application.
            setGoToParameters();
            $rootScope.xgos.sector = loginType === 0 ? 'login' : 'loginoidc';
            $location.path(loginType === 0 ? '/login' : '/loginoidc');
          }
          else if(shortPath === 'login'){
            if(loginType ===1){
              $rootScope.xgos.sector = 'loginoidc';
              $location.path('/loginoidc');
            }
            else{
              $rootScope.xgos.sector = 'login';
              $location.path('/login');
            }
          }
          else if(shortPath === 'loginoidc' || shortPath === 'oidclogged'){
            if(loginType ===0){
              $rootScope.xgos.sector = 'login';
              $location.path('/login');
            }
            else{
              $rootScope.xgos.sector = 'loginoidc';
              $location.path('/loginoidc');
            }
          }
        };

        if (force) redirect();
        // if the portal in the url doesnt seem to exist, remove it from the url
        else if (typeof $location.search()['portal'] != 'undefined') {
          var found = false;
          PortalsFactory.get().then(() => {
            for (var i in PortalsFactory.resources.portals) {
              if (
                PortalsFactory.resources.portals[i].uid ==
              $location.search()['portal']
              ) {
                found = true;
              }
            }
            if (!found) {
              $location.search('portal', null);
            }
            if ($rootScope.xgos.specificApp != 'mobile_photo') redirect();
          },
          () => {
            goToLogin(true);
          });
        }
        else {
          redirect();
        }
      })
        .catch(function(error) {
          console.error('Error fetching OIDC Angular Address :', error);
        });
    }

    function goToCleanLogout() {
      setGoToParameters();
      $location.search('reload', 'true');
      $location.path('/logout');
    }

    /**
     * Return whether the user is allowed to access the page
     * @returns {boolean}
     */
    function userIsAllowed() {
      var allowed = true;

      if (!$rootScope.xgos.isroot) {
        // admin can now access supervision but handle their portal only
        if (
          $rootScope.xgos.sector == 'supervision' &&
          !$rootScope.xgos.isadmin
        ) {
          allowed = false;
        }

        // sub supervision (anc for ex) only for root atm
        if ($rootScope.xgos.sectorParts[1] == 'supervision') {
          allowed = false;
        }

        if ($rootScope.xgos.sector == 'admin' && !$rootScope.xgos.isadmin) {
          allowed = false;
        }
      }
      return allowed;
    }

    /**
     * Redirect to the login page
     */
    function goToAccessDenied() {
      $rootScope.xgos.sector = 'denied';
      $location.path('/503/');
    }

    /**
     * Après la 1ère connexion:<ul><li>
     * redirige vers la page d'accueil si le portail choisi a une page d'accueil active</li><li>
     * sinon redirige vers le chemin du paramètre goto de l'url.</li></ul>
     * Patiente 750 ms avant redirection si l'application est 'mobile_photo' et si KisAncCfg.
     * @param KisAncCfg boolean pour anc ?
     */
    function redirectAfterLogin(KisAncCfg) {
      var goto = 'users';
      if (
        $rootScope.xgos.isroot &&
        $rootScope.xgos.specificApp != 'mobile_photo'
      ) {
        goto = 'supervision';
      }
      if ($location.search()['goto']) {
        goto = $location.search()['goto'];
        $location.search('goto', null);
      }
      let promises = [];
      // root bypass la page d'accueil
      if (!$rootScope.xgos.isroot && gaJsUtils.notNullAndDefined($rootScope.xgos, 'portal.parameters.homepage')
          && $rootScope.xgos.portal.parameters.homepage.active && $rootScope.portalChosen) {
        // we goto 'home' only if at least one homepage is published
        let promise = homeFactory.get($rootScope.portalChosen).then((homepages) => {
          if (homepages && Array.isArray(homepages)) {
            const homepage = homepages.find(homepage => homepage.published);
            if (homepage) {
              // si il y a une page d'accueil publié -> on y va
              goto = "home"
            }
          }
        });
        promises.push(promise);
      }
      $q.all(promises).then(()=> {
        if (KisAncCfg && $rootScope.xgos.specificApp == 'mobile_photo') {
          $timeout(function() {}, 750);
        } else {
          $location.path('/' + goto);
        }
      });
    }

    function clearStorageAndSetPortal() {
      const keepStorageItems = ['current_language', 'portal', 'gcDataTableCount', 'kisusertheme'];
      const storage = keepStorageItems.reduce((obj, item) => {
        obj[item] = localStorage.getItem(item);
        return obj;
      }, {});
      // clear localstorage sauf token
      localStorage.clear();
      Object.keys(storage).filter(item => storage[item]).forEach(item => localStorage.setItem(item, storage[item]));

      var portal = PortalsFactory.getPortalId();
      PortalsFactory.setPortal(portal);
    }

    return {
      authFactory: authFactory,
      resources: resources,
      getToken: getToken,
      oidclogin: oidclogin,
      logout: logout,
      getMe: getMe,
      userLogged: userLogged,
      goToLogin: goToLogin,
      userIsAllowed: userIsAllowed,
      goToAccessDenied: goToAccessDenied,
      redirectAfterLogin: redirectAfterLogin,
      logoutUserFromServer: logoutUserFromServer,
      logoutUserFromServerSync: logoutUserFromServerSync,
      logoutUserFromServerByUid: logoutUserFromServerByUid,
      getcurrentuser: getcurrentuser,
      needToChangePwd: needToChangePwd,
      updateUserPW:updateUserPW,
      getrgpdmessage:getrgpdmessage,
    };
  };

  authFactory.$inject = [
    '$http',
    '$q',
    '$location',
    '$rootScope',
    'PortalsFactory',
    '$timeout',
    'licenceFactory',
    'ThemesFactory',
    'gaJsUtils',
    'AncAppFactory',
    'homeFactory'
  ];
  return authFactory;
});
