'use strict';
define(function() {
  /**
   * Class : PortalsFactory
   * Factory WebServices
   */
  var portalsFactory = function(
    $http,
    $q,
    gaUrlUtils,
    gaJsUtils,
    $rootScope,
    licenceFactory,
    $translatePartialLoader,
    $filter,
    $location,
    $window
  ) {
    var resources = { portals: [] };

    /**
     * Renvoie le portalId actuel,
     * Celui contenu en variable JS ou celui dans l'URL ou celui dans le datastorage
     */
    /**
     * Renvoie le portalId actuel,
     * Celui contenu en variable JS ou celui dans l'URL ou celui dans le datastorage
     *
     * @returns {string|*} valeur du du portal id
     */
    const getPortalId = () => {
      if (angular.module('gcMain')
          && angular.module('gcMain').portalid
          && angular.module('gcMain').portalid !== '') {
        return angular.module('gcMain').portalid;
      }
      if ($location.search().portal && $location.search().portal !== '') {
        return $location.search().portal;
      }
      if (localStorage.getItem('portal') && localStorage.getItem('portal') !== '') {
        return localStorage.getItem('portal');
      }
      return '-';
    };

    /**
     * Function: get
     */
    function get() {
      if (typeof ancAppAndroid !== 'undefined') {
        return $q.when(['detail', 'simple']);
      } else {
        // user isn't connected anyway
        if (!localStorage.getItem('auth_token')) {
          var def = $q.defer();
          def.reject();
          return def.promise;
        }

        var promise = $http.get('/services/portal/get?f=json');
        promise.then(function(res) {
          if (res.data !== '') {
            if (res.data.CLASSTYPE && res.data.CLASSTYPE == 'UNAUTHORIZED') {
              // nope
            } else {
              resources.portals = sortPortalByNames(res.data);
            }
          }
        });
        return promise;
      }
    }

    /**
     * Function: get
     */
    function getByUid(portailId,token) {
      return $http.get('/services/portal/getByUid?f=json&uid='+portailId+(token?'&token='+token:''));
    }

    function sortPortalByNames(portals) {
      return portals.sort(function (a, b) {
        if (a.name < b.name) { return -1; }
        if (a.name > b.name) { return 1; }
        return 0;
      });
    }

    /**
     * Function: getPortalAndApps
     */
    function getPortalAndApps() {
      var promise = $http.get('/services/portal/getPortalAndApps?f=json');
      promise.then(function(res) {
        if (res.data !== '') {
          resources.portals = res.data;
        }
      });
      return promise;
    }
    /**
     * Function: add
     */
    function add(name) {
      var promise = $http.get(
        '/services/portal/add?f=json' +
          '&name=' +
          gaUrlUtils.encodeUriQuery(name)
      );
      promise.then(function(res) {
        resources.portals.push(res.data);
      });
      return promise;
    }

    /**
     * Met à jour un portail. <br>
     * Modifie le portail dans la liste des resources.<br>
     * Créé la table qui stocke les données du fil d'actualité de la page d'accueil.<br>
     * Si la création de table a échouée, l'erreur est affichée en taustr
     * @param senddata portail en String
     * @return {Promise} contenant une map: {portal -> portal, homepage_news_errors -> [string]}
     */
    function update(senddata) {
      var promise = $http.post('/services/portal/update?f=json', senddata);
      promise.then(function(res) {
        var replaceIndex = resources.portals
          .map(function(x) {
            return x.uid;
          })
          .indexOf(senddata.uid);
        resources.portals[replaceIndex] = res.data.portal;

        // affiche un message pour chaque erreur rencontrée lors de la création de la table 'kis_homepage_actualite'
        if (res.data.hasOwnProperty('homepage_news_errors') && Array.isArray(res.data.homepage_news_errors)) {
          for (const error of res.data.homepage_news_errors) {
            require('toastr').error(error);
          }
        }
      });
      return promise;
    }

    /**
     * Function: remove
     */
    /**
     * Suppression d'un portail
     * @param portalUid uid identifiant d'un portal (portal.uid)
     * @return {Promise} si la suppression a réussi la promesse contient l'uid du portail supprimé.
     * Si la suppression a échouée une erreur serveur est renvoyée
     */
    const remove = (portalUid) => {
      const promise = $http.get('/services/portal/remove?f=json' + '&id=' + portalUid);
      promise.then(
          (res) => {
            const deleteIndex = resources.portals.findIndex(portal => portal.uid === id);
            if (deleteIndex > -1) {
              resources.portals.splice(deleteIndex, 1);
            }
            console.log('Suppression du portail réussie. uid = ', res.data);
          },
          () => {
            require('toastr').error($filter('translate')('portals.portals.deleteError'));
          });
      return promise;
    };

    /**
     * Function: checkportaldata
     */
    function checkportaldata(portalid) {
      var promise = $http.get(
        '/services/portal/checkPortalData?f=json' + '&portalid=' + portalid
      );
      promise.then(function(res) {
        $rootScope.xgos.kis_public_url = res.data.KIS_PUBLIC_URL;
      });
      return promise;
    }

    /**
     * Function: checkportaldata
     */
    function applyTraduction(portalid, langs, lang) {
      var promise = $http.get(
        '/services/portal/applyTraduction?f=json' +
          '&portalid=' +
          portalid +
          '&langs=' +
          langs +
          '&lang=' +
          lang
      );
      promise.then(function(res) {});
      return promise;
    }

    /**
     * Set portal
     * @param portalId
     */
    function setPortal(portalId) {
      var def = $q.defer();
      portalId = portalId || false;

      if (!portalId) {
        var tmpPortal = localStorage.getItem('portal');
        if (tmpPortal) {
          portalId = tmpPortal;
        }
      }

      if (portalId) {
        $rootScope.portalChosen = portalId;
        localStorage.setItem('portal', portalId);
        for (const portal of resources.portals) {
          if (portal.uid === portalId) {
            $rootScope.xgos.portal = portal;
            // applique le thème du portail s'il existe
            if (portal.parameters && portal.parameters.theme && !portal.parameters.allowUserTheme) {
              $rootScope.xgos.currentTheme = portal.parameters.theme;
            }
            if (gaJsUtils.notNullAndDefined($rootScope.xgos.portal, 'parameters.homepage.active')) {
              $rootScope.xgos.hasHomepage = $rootScope.xgos.portal.parameters.homepage.active;
              if (typeof $rootScope.goToHomepage !== "function") {
                $rootScope.goToHomepage = () => {
                  $window.open('#/home', '_blank');
                };
              }
            }
            break;
          }
        }
        getClientCss(portalId);
        $translatePartialLoader.addPart(`/services/${portalId}/translation/model`);
        def.resolve();
      } else {
        def.reject();
      }
      return def.promise;
    }

    /**
     * setCurrPortalCfg
     * moved from app.js, get/setCurrPortal and check licence once user is authentified
     */
    function setCurrPortalCfg() {
      var def = $q.defer();

      get().then(
        function() {
          setPortal().then(function() {
            licenceFactory.getAllLicences().then(function() {
              var licence = licenceFactory.getLicence($rootScope.portalChosen);
              $rootScope.xgos.licence.full = licence;
              if (licence && licence.type !== 'free')
                licenceFactory.checkLicence(licence);
              def.resolve();
            });
          });
        },
        function() {
          def.reject();
        }
      );

      return def.promise;
    }

    var checkedPortal = '-';
    /**
     * executeCheckPortalData
     */
    var executeCheckPortalData = function() {
      if (
        checkedPortal != $rootScope.portalChosen &&
        $rootScope.portalChosen != '-'
      ) {
        // check that portal only once per portal instance
        checkedPortal = $rootScope.portalChosen;
        checkportaldata($rootScope.portalChosen);
      }
    };

    /**
     * No Portal
     */
    function setNoPortal() {
      delete $rootScope.portalChosen;
      delete $rootScope.xgos.portal;
    }

    /**
     * Function: reload JSON all repos config
     */
    function reloadAll() {
      return $http.get('/services/tools/reload?f=json');
    }

    /**
     * Function: reload JSON one repo config
     */
    function reloadPortal(portalid) {
      return $http.get(
        '/services/tools/reload/portal?f=json&portalid=' + portalid
      );
    }

    /**
     * get shared commonInfo
     */
    function getCommonInfo() {
      return $http.get('/services/portal/getCommonInfo?f=json')
    }

    /**
     * Ajoute le nouveau lien de navigation (bouton "Help" de l'application Map)
     * dans le paramètre "helpTools" du portail
     * @param portalid uid identifiant du portail contenant l'application map où les nouveaux liens seront ajoutés
     * @param processId uid du processus d'upload correspondant au nom du dossier dans lequel ont été
     *                  copiées les images après drag/drop
     * @param helptool objet contenant le titre, le lien de l'image, la position du titre et l'emplacement de l'image
     * @return {[]} liste des liens de navigation ("helpTools") du portail.
     * @see portalhelplinks.appendHelpTool
     */
    const addOrEditPortalHelpTool = (portalid, processId, helptool) => {
      if (portalid && helptool) {
        return $http.post('/services/portal/addOrEditPortalHelpTool?f=json'
            +'&portalid=' + portalid
            +'&processid=' + processId
        , helptool);
      }
    };
    /**
     * Supprime le lien de navigation des paramètres du portail
     * @param portalid uid identifiant du portail
     * @param uid uid du lien de navigation à supprimer
     * @return {[]} liste des liens de navigation ("helpTools") du portail.
     * @see portalhelplinks.deleteHelpTool
     */
    const deletePortalHelpTool = (portalid, uid) => {
      if (portalid && uid) {
        return $http.get('/services/portal/deletePortalHelpTool?f=json'
        + '&portalid=' + portalid
        + '&uid=' + uid
        );
      }
    };

    /**
     * Remplace le paramètre "helpTools" du portail
     * @param portalid uid identifiant du portail à modifier
     * @param helpTools tableau des liens de navigation du portail
     * @return {boolean} true si le portail a été mis à jour
     * @see portalhelplinks.moveField
     */
    const savePortalHelpToolsParameter = (portalid, helpTools) => {
      if (portalid && Array.isArray(helpTools)) {
        return $http.post('/services/portal/savePortalHelpToolsParameter?f=json'
            + '&portalid=' + portalid
        , helpTools);
      }
    };

    /** Ajoute dans le dom le contenu HTML de la popup info présentée sur la page de login et stockée
     * dans le dossier "CSS-HTML" du repo sous le nom fixe de "login_notif.html".
     * Ajoute dans le dom le css de la popup infoet stocké dans le dossier "CSS-HTML" du repo
     * sous le nom fixe de "login_notif.css"
     * @param portalid uid identifiant du portail dont on souhaite afficher la popup d'informations
     * sur la page de login
     * @return {boolean} true si le portail contient un fichier html
     */
    const getPortalNotifInfo = (portalid) => {
      let defer = $q.defer();
      $http.get(
        '/services/portal/getPortalNotifInfo?f=json&portalid=' + portalid
      ).then(
        res => {
          const popupInfo = res.data;
          if (!popupInfo || Object.keys(popupInfo).length === 0) {
            defer.resolve(false);
          }
          else {
            if (popupInfo.code && popupInfo.code === 403) {
              require('toastr').error(
                $filter('translate')('portals.css.noUserConnectedError'));
              defer.resolve(false);
            } else {
              if (popupInfo.css){
                const popup = document.createElement('div');
                popup.innerHTML = '<br><style>'+ popupInfo.css +'</style>';
                const notifContainerElement = document.querySelector('.notif-info-container');
                if (notifContainerElement) {
                  notifContainerElement.appendChild(popup);
                }
              }
              if (popupInfo.view){
                const notifElement = document.querySelector('.notif-info-body');
                if (notifElement) {
                  notifElement.innerHTML = popupInfo.view;
                  defer.resolve(true);
                } else {
                  defer.resolve(false);
                }
              } else {
                defer.resolve(false);
              }
            }
          }
        },
        (err) => {
          console.log('erreur serveur PortalHandler#getPortalNotifInfo lors de la notification ' +
                'd\'information du portail');
          defer.reject(err.data);
        }
      );
      return defer.promise;
    };

    /**
     * Injecte le contenu du fichier custom.css présent dans le dossier 'CSS-HTML' du repo
     * dans la div portant la class css 'client-css-container' de la page index.html.<br>
     * Copie les images dans le dossier 'FILES' du repo.<br>
     * Les images référencées dans le fichier custom.css doivent avoir un chemin défini ainsi:
     * "<code>/services/{portalid}/files/downloadfile?fileName=monimage.jpg</code>"
     * @param portalid uid identifiant du portail
     */
    const getClientCss = (portalid) => {
      if (portalid) {
        $http.get('/services/portal/getClientCss?f=json&portalid=' + portalid).then(
            res => {
              if (res.data && res.data.length > 0){
                const cssContainerElt = document.getElementById('alt-css-injector');
                if (cssContainerElt) {
                  const css = '<br><style>'+ res.data +'</style>';
                  const cssDiv = document.getElementById('custom-css-file');
                  if (cssDiv) {
                    cssDiv.innerHTML = css;
                  } else {
                    const div = document.createElement('div');
                    div.id = 'custom-css-file';
                    div.innerHTML = css;
                    cssContainerElt.appendChild(div);
                  }
                }
              }
            }
        );
      }
    };

    /**
     * Ouvre un nouvel onglet du navigateur web sur la page de l'application.<br>
     * Reformate fonction entre apps.js, homeAppSwitcher, homeAppCarousel, homepageNews et mapLeftMenu
     * @param portalid uid identifiant du portail
     * @param app application kis
     * @param distinctAppName (optionnel) false ds mapleftMenu qd scope.currentAppName === app.name
     */
    const gotoApp = (portalid, app, distinctAppName = true) => {
      if (app.uid === 'admin') {
        $window.open('#/users');
      } else if (~app.uid.indexOf('external_app')) {
        $window.open(app.url);
      } else {
        if (distinctAppName) {
          const appTpl = app.type.replace('App', '').toLowerCase();
          $window.open(
              '#/' + appTpl + '?portal=' + portalid + '&app=' + app.name
          );
        }
      }
    };

    /**
     * Ajoute un paramètre 'homepage' au portail
     * @param portal objet portal
     */
    const initHomepagePortalParameter = (portal) => {
      if (!portal.parameters.homepage
          || (portal.parameters.homepage
              && (portal.parameters.homepage.active === null
                  || portal.parameters.homepage.active === undefined))) {
        portal.parameters.homepage = {
          active: false,
          activename: null
        };
      }
    };

    /**
     * Récupère la liste des pages d'accueils en objets simplifiés {name,id}
     * @param portalid uid identifiant du portail
     * @returns {*} liste des noms et id des pages d'accueil du portail
     */
    const getHomepagesLight = (portalid) => {
      return $http.get('/services/portal/getHomepagesLight?f=json&portalid=' + portalid)
    };

    /**
     * Supprime une page d'accueil dans le fichier homepages.json du dossier CSS-HTML du repo
     * @param portalid uid identifiant du portail
     * @param id entier identifiant unique de la page d'accueil déjà sauvegardée (homepage.id)
     */
    const deleteHomepageById = (portalid, id) => {
      const promise = $http.get('/services/' + portalid + '/homepage/deleteById?f=json'
          + '&homepageid=' + id
      );
      promise.catch((err) => {
        if (err && Array.isArray(err.data)) {
          for (const error of err.data) {
            require('toastr').error(error);
          }
        }
      });
      return promise;
    };
    return {
      getPortalId: getPortalId,
      portalsFactory: portalsFactory,
      resources: resources,
      get: get,
      sortPortalByNames: sortPortalByNames,
      add: add,
      update: update,
      remove: remove,
      setPortal: setPortal,
      setNoPortal: setNoPortal,
      checkportaldata: checkportaldata,
      executeCheckPortalData: executeCheckPortalData,
      applyTraduction: applyTraduction,
      reloadAll: reloadAll,
      reloadPortal: reloadPortal,
      getPortalAndApps: getPortalAndApps,
      setCurrPortalCfg: setCurrPortalCfg,
      addOrEditPortalHelpTool: addOrEditPortalHelpTool,
      deletePortalHelpTool: deletePortalHelpTool,
      savePortalHelpToolsParameter: savePortalHelpToolsParameter,
      getByUid:getByUid,
      getPortalNotifInfo: getPortalNotifInfo,
      getClientCss: getClientCss,
      gotoApp: gotoApp,
      initHomepagePortalParameter: initHomepagePortalParameter,
      getHomepagesLight: getHomepagesLight,
      deleteHomepageById: deleteHomepageById,
      getCommonInfo:getCommonInfo
    };
  };
  portalsFactory.$inject = [
    '$http',
    '$q',
    'gaUrlUtils',
    'gaJsUtils',
    '$rootScope',
    'licenceFactory',
    '$translatePartialLoader',
    '$filter',
    '$location',
    '$window'
  ];
  return portalsFactory;
});
