'use strict';
define(function() {
  var gcshapeimport = function(
    ImportExportFactory,
    FeatureTypeFactory,
    DataStoreFactory,
    $translate,
    $q,
    SridFactory,
    $filter,
    gaJsUtils
  ) {
    return {
      templateUrl: 'js/XG/widgets/utilities/model/views/gcshapeimport.html',
      restrict: 'AE',
      scope: {
        stores: '=',
      },
      link: function(scope) {
        scope.destinationSRID = null;
        scope.srids = SridFactory.sridsList;
        scope.uploadProcessID = -1;
        scope.importedFeatures = [];

        scope.selectedStore = null;

        scope.srcsrid = '';

        scope.importData = true;

        scope.waitImport = false;

        var confirmLabel = 'Import avec succès';

        $translate('model.featuretypes.import_shape.confirmMsg').then(function(
          res
        ) {
          confirmLabel = res;
        });

        var errorLabel = "Erreur d'import!";

        $translate('model.featuretypes.import_shape.error').then(function(res) {
          errorLabel = res;
        });

        /**
         * [importFile description]
         * @return {[type]} [description]
         */
        scope.importFile = function() {
          if (scope.dropzoneComponent.files.length > 0) {
            ImportExportFactory.loadSchema(scope.uploadProcessID).then((importResult)=> {
              scope.importedFeatures = [];
              importResult.data.forEach(imp => {
                if(gaJsUtils.checkCustomRegex(imp.name)){
                  const notAuthorizedAttributes
                    = imp.attributes.filter(att => !gaJsUtils.checkCustomRegex(att.name));
                  if(notAuthorizedAttributes.length>0){
                    const attributesJoined
                      = notAuthorizedAttributes.map(att => att.name).join(', ');
                    const msgId = 'model.featuretypes.attributes.forbiddenCharactersInAttributes';
                    const errorMessage = $filter('translate')(msgId);
                    require('toastr')
                      .error(`${imp.name}: ${errorMessage.replace('$1', attributesJoined)}`);
                  }else{
                    scope.importedFeatures.push(imp);
                  }
                }else{
                  require('toastr').error(imp.name+': '+
                        $filter('translate')('model.featuretypes.attributes.forbidden_characters'));
                }
              });
            });
          }
        };

        /**
         * [clearDropzone description]
         * @return {[type]} [description]
         */
        scope.clearDropzone = function() {
          if (scope.dropzoneComponent.files.length > 0) {
            scope.dropzoneComponent.removeAllFiles();

            scope.importedFeatures = [];
          }
        };


        const reloadOrResolvePromise = (i, promises, defer,toastr) =>{
          i = i + 1;
          if (
            scope.importedFeatures.length > 0 &&
            i <= scope.importedFeatures.length - 1
          ) {
            scope.importFT = scope.importedFeatures[i];
            scope.sourceFeatureType = scope.importFT.name;
            var p1 = addTableAndLoadData(i);
            promises.push(p1);
          } else {
            scope.waitImport = false;
            if(toastr==='error'){
              require('toastr').error(errorLabel);
            }else if(toastr ==='success'){
              require('toastr').success(confirmLabel);
            }
            scope.clearDropzone();
            defer.resolve('termine');
          }
        };


        /**
         * Crée un objet de paramètres pour l'import
         * @param {string} destFeatureType uid du featureType destination
         * @param {string} strAttrCorrespArray string JSON des correspondances
         *     attribut- attribut
         * @returns {{destLayerUID: string, attribCorresp: string,
         *     uploadProcessId: string, sourceLayerName: string,
         *     srcsrid: number, destsrid: number, fileEncoding: string}}
         */
        const loadParams = (destFeatureType, strAttrCorrespArray) =>{
          return {
            destLayerUID: destFeatureType,
            attribCorresp: strAttrCorrespArray,
            uploadProcessId: scope.uploadProcessID,
            sourceLayerName: scope.sourceFeatureType,
            srcsrid: scope.srcsrid,
            destsrid: scope.destinationSRID,
            fileEncoding: scope.fileEncoding
          };
        };


        /**
         * Appelé par addTableAndLoadData. Ajoute un featureType et lance
         * l'import de données.
         * @param {object} res - objet de la réponse du serveur
         *      contenant le featureType créé
         * @param {object} currentImportFTI - featureType en cours d'import
         * @param {number} i - index du featureType dans le tableau
         *      scope.importedFeatures
         * @param {array} promises - tableau des promesses à résoudre
         *      pour terminer l'import
         * @param {object} defer - objet defer pour la promesse
         *      de fin d'import
         */
        const addFtiAndLoadData = (res, currentImportFTI,i,promises,defer) => {
          if (res.data !== '') {
            var newFti = res.data;
            var p2 = FeatureTypeFactory.add(newFti).then(
              function(addRes) {
                if (scope.importData) {
                  var addFti = addRes.data;
                  var destFeatureType = addFti.uid;
                  scope.srcsrid = currentImportFTI.srid;
                  var strAttrCorrespArray = '';
                  var p3 = ImportExportFactory.loadandprojectdata(
                    loadParams(destFeatureType, strAttrCorrespArray)).then(() =>{
                    reloadOrResolvePromise(i,promises,defer,'success');
                  },() =>{
                    reloadOrResolvePromise(i,promises,defer,'error');
                  }
                  );
                  promises.push(p3);
                } else {
                  reloadOrResolvePromise(i,promises,defer,'success');
                }
              },() => {
                reloadOrResolvePromise(i,promises,defer,'error');
              }
            );
            promises.push(p2);
          } else {
            require('toastr')
              .error(currentImportFTI.name
                  + $filter('translate')('model.featuretypes.import_shape.tableExistInDB'));
            reloadOrResolvePromise(i,promises,defer,'error');
          }
        };


        /**
         * Crée un featureType et charge les données du fichier importé
         * @param {number} i - index du featureType dans le tableau
         *      scope.importedFeatures
         * @return {Promise} - promesse qui se résout lorsque l'import est terminé
         */
        const addTableAndLoadData = (i) => {
          var defer = $q.defer();
          var promises = [];
          promises.push(defer.promise);
          var currentImportFTI = scope.importFT;
          var p = DataStoreFactory.addtable(
            scope.selectedStore.name,
            currentImportFTI,
            scope.destinationSRID,
            scope.forceUpdateAttributsAndSrid
          ).then((res) => {
            addFtiAndLoadData(res, currentImportFTI,i,promises,defer);
          }
          ,(err) => {
            //message spécifique en cas d'erreur!
            if(err.data && err.data.message){
              if(err.data.message.startsWith('kis_error')){
                require('toastr').error(currentImportFTI.name+$filter('translate')(
                  ('model.featuretypes.import_shape.'+err.data.message.split(':')[1])));
              }else{
                require('toastr').error(err.data.message);
              }
            }
            reloadOrResolvePromise(i,promises,defer, 'error');
          }
          );
          promises.push(p);
          return $q.all(promises);
        };


        /**
         * [submitShapeFeaturesImport description]
         * @return {[type]} [description]
         */
        scope.submitShapeFeaturesImport = function() {
          if (scope.fileEncoding === '-----') {
            require('toastr')
              .error($filter('translate')('model.featuretypes.import_shape.invalidEncoding'));
            return;
          }
          scope.waitImport = true;
          if (scope.selectedStore !== null) {
            var i = 0;
            if (
              scope.importedFeatures.length > 0 &&
              i <= scope.importedFeatures.length - 1
            ) {
              scope.importFT = scope.importedFeatures[i];
              scope.sourceFeatureType = scope.importFT.name;
              addTableAndLoadData(i).then(() =>{
                scope.$broadcast('initializeDirective');
              });
            }
          }
        };
      },
    };
  };

  gcshapeimport.$inject = [
    'ImportExportFactory',
    'FeatureTypeFactory',
    'DataStoreFactory',
    '$translate',
    '$q',
    'SridFactory',
    '$filter',
    'gaJsUtils'
  ];
  return gcshapeimport;
});
