'use strict';
define(function() {
  const AtlasArcGIS108Service = function($rootScope, ArcGisJob, $q) {

    let scope;


    /**
     * Si un des paramétres appartient à la ctyégorie "__keyword__",
     * il s'agit d'un mot clef dont nous devons calculer la valeur ici.
     * @param {*} keyword
     * @returns
     */
    const getSpecialInfo = (keyword) => {
      if (keyword.toLowerCase()==='author') {
        return $rootScope.xgos.user.vorname + ' ' + $rootScope.xgos.user.name;
      }
    };

    /**
       * Gestion des paramétres spéciaux du service:
       * 1) Ceux à ne pas présenter et qui ont été
       *    préconfigurés dans la préparation du géotraitement.
       * 2) Ceux qui sont des mots clefs et que l'on doit calculer ici.
       * 3) Ceux qui sont à saisir (en plus du titre, de la description,
       *    du modéle et du format d'export)
       *
       * @param {*} postData Donnes à envoyer en POST au service HTTP
       * @param {*} atlasResponse Positionné lors de l'appel au service brut
       *                       pour rcupérer la description du géotraitement
       */
    const setArcGIS108SpecialParameters = (scope, postData, atlasResponse) => {
      let fields, field;
      if (atlasResponse) {
        if (scope.esriConfig) {
          scope.esriConfig.arcgis108Desc = atlasResponse;
        }
        else {
          scope.mainConfig.autoAtlas.arcgis108Desc = atlasResponse;
        }
      }
      else {
        if (scope.esriConfig) {
          atlasResponse = scope.esriConfig.arcgis108Desc;
        }
        else {
          atlasResponse = scope.mainConfig.autoAtlas.arcgis108Desc;
        }
      }
      for (const parameter of atlasResponse.parameters) {
        switch(parameter.category) {
          case 'DoNotAsk':
            postData[parameter.name] = parameter.defaultValue;
            break;
          case '__keyword__':
            postData[parameter.name] = getSpecialInfo(parameter.name);
            break;
          case 'ask':
            // -- Initialisation éventuelle de la liste des paramétres à saisir
            if (!scope.atlasEsri) {
              scope.atlasEsri = {};
            }
            if (!scope.atlasEsri.geoprocessFields) {
              scope.atlasEsri.geoprocessFields = [];
            }
            // -- Recherche du paramétre dans liste
            fields = scope.atlasEsri.geoprocessFields;
            field = fields.find(field => field.name===parameter.name);
            if (!field) {
              // -- Le paramétre n'existe pas, donc on l'ajoute
              parameter.value = parameter.defaultValue;
              fields.push(parameter);
              field = parameter;
            }
            // -- Affecter la valeur pour un véentuel appel d'un service de l'atlas
            postData[parameter.name] = field.value;
            break;
        }
      }
    };


    /**
     * Positionne le contenu de la propriété "atlasEsri" en fonction
     * de la description reçu du service d'atlas ArcGIS.
     * On stocke dans le workspace du scope cette propriété afin de ne pas rappeler
     * le service si sans fermer le widget on redemande l'accés à la directive d'atlas ArcGIS.
     * Donc, si on a déjà stcoké la description on la lit depuis la sauvegarde faite
     * dans la propriété "workspace" du scope.
     *
     * @param {*} scope Scope du widget depuis lequel les services d'atlas sont appelés
     * @param {*} templateList Liste des modèle d'atlas (reçu depuis le service ArcGIS)
     */
    const setEsriPrint = (scope, templateList) => {
      let configAlreadyGotten = false;
      // -- Quand un workspace est défini sur le scope du widget parent,
      // -- on l'utilise pour éviter de recharger la liste des modèles
      // -- lors d'un rappel de ce service.
      if (scope.workspace) {
        if (scope.workspace.atlasEsri) {
          // -- Récupération de la config compléte précédemment sauvée
          scope.atlasEsri = scope.workspace.atlasEsri;
          configAlreadyGotten = true;
        }
        else {
          scope.atlasEsri.area_models = scope.atlasEsri.line_models = templateList;
          // -- Mise en place de la sauvegarde de la configuration pour plus tard
          scope.workspace.atlasEsri = scope.atlasEsri;
        }
      }
      else {
        scope.atlasEsri.area_models = scope.atlasEsri.line_models = templateList;
      }
      if (!configAlreadyGotten && scope.esriConfig && scope.esriConfig.atlas_area_models) {
        for (const model of scope.atlasEsri.area_models) {
          const cfgModel
                = scope.esriConfig.atlas_area_models.find(
                  cfgModel => cfgModel.name === model.name);
          if (cfgModel) {
            model.added = cfgModel.added;
          }
        }
      }
      else {
        scope.atlasModelList = templateList;
      }

      scope.jobInfo = false;
    };


    /**
     * Récupération de la liste des modèles d'atlas disponibles.
     * @param {*} urlAtlas URL de la requête HTTP du service d'atlas
     * @param {*} atlasResponse Réponse suite à l'appel du service d'atlas
     *                          en mode récupération de sa description
     */
    const initEsri108Atlas = (scope, urlAtlas, atlasResponse) => {
      const defer = $q.defer();
      const ws = scope.workspace;
      if (ws && ws.atlasEsri && ws.atlasEsri.area_models && ws.atlasEsri.area_models.length) {
        setEsriPrint(scope, scope.workspace.atlasEsri.area_models);
        defer.resolve();
      }
      else {
        let url = urlAtlas + '/submitJob/execute?f=json';
        const postData = {};
        setArcGIS108SpecialParameters(scope, postData, atlasResponse);
        postData.geometryType = 'list_layouts';
        scope.esriInitializing = true;
        $.post(url, postData).then((info) => {
          scope.atlasEsri.atlas_models = [];
          ArcGisJob.runEsriJob(scope, urlAtlas, info, {}).then(() => {
            const result = scope.arcgisJobs[info.jobId].jobResults.find(
              result => result.name === 'layouts');
            const layouts = result ? result.value : [];
            setEsriPrint(scope, layouts);
          }).finally(() => {
            scope.esriInitializing = false;
            console.log('scope.esriInitializing = false;');
            defer.resolve();
          });
        });
      }
      return defer.promise;
    };


    return {
      scope: scope,
      setArcGIS108SpecialParameters: setArcGIS108SpecialParameters,
      initEsri108Atlas: initEsri108Atlas
    };
  };
  AtlasArcGIS108Service.$inject = ['$rootScope', 'ArcGisJob', '$q'];
  return AtlasArcGIS108Service;
});
