'use strict';
define(function() {
  var ImportExportFactory = function($http, $q, $translate, $timeout, $filter) {
    var ImportExportFactory = {};

    const  getDataTakenFromZip = (datafile, ip) => {
      return $http.get(
        '/services/{portalid}/loading_cadastre/getDataTakenFromZip?f=json'+
        '&datafile=' + datafile + '&adress=' + ip
      );
    };

    /**
     * Function: epanetexport
     */
    function epanetexport(configName) {
      var promise = $http.post(
        '/services/{portalid}/export/{appname}/epanet/export?f=json&cfgname=' +
          configName
      );

      return promise;
    }

    /**
     * Function: exportfeaturecollection
     */
    function exportfeaturecollection(
      obj,
      exportFormat,
      srid,
      mapping,
      specialcsv,
      encoding,
      separator
    ) {
      if (angular.isUndefined(mapping)) mapping = '';
      if (angular.isUndefined(specialcsv)) specialcsv = '';
      var senddata = {
        FeatureCollection: obj,
        mapping: mapping,
        specialcsv: specialcsv,
      };

      var promise = $http.post(
        '/services/{portalid}/export/exportfeaturecollection?f=json' +
          '&exportFormat=' +
          exportFormat +
          '&srid=' +
          srid
          + (encoding ? ('&encoding=' + encoding) : '')
          + (separator ? ('&separator=' + separator) : ''),
        senddata
      );

      return promise;
    }

    /**
     * Function: exportLayersFeatures
     */
    function exportLayersFeatures(
      exportFormat,
      srid,
      layers,
      attributes,
      whereClause,
      specialcsv,
      sourceSrid,
      encoding,
      separator,
      gpkgFilename
    ) {
      if (angular.isUndefined(specialcsv)) specialcsv = '';
      //bbox
      var senddata = '{"attributes":' + attributes + ',"whereClause":"'+whereClause+'"}';

      var promise = $http.post(
        '/services/{portalid}/export/exportLayersFeatures?f=json' +
          '&exportFormat=' +
          exportFormat +
          '&srid=' + srid +
          '&layers=' + layers +
          '&specialcsv=' + specialcsv +
          '&sourceSrid=' + sourceSrid +
          (encoding ? ('&encoding=' + encoding) : '') +
          (separator ? ('&separator=' + separator) : '') +
          (gpkgFilename ? ('&gpkgFilename=' + gpkgFilename) : ''),
        senddata
      );

      return promise;
    }
    /**
     * Function: checkExportStatus
     */
    function checkExportStatus(processId) {
      var promise = $http.get(
        '/services/{portalid}/export/checkExportStatus?f=json' +
          '&processId=' +
          processId
      );

      return promise;
    }

    /**
     * Function: loadSchema
     */

    function loadSchema(uploadProcessId) {
      //null
      const senddata = null;

      return $http.post(
        '/services/{portalid}/loading/loadSchema?f=json' +
          '&uploadProcessId=' +
          uploadProcessId,
        senddata
      );
    }

    function loadSchemaCsv(
      uploadProcessId,
      columnDelimiter,
      decimalDelimiter,
      columnsTypes
    ) {
      var senddata = '' + JSON.stringify(columnsTypes);

      var promise = $http.post(
        '/services/{portalid}/loading/loadSchemaCsv?f=json' +
          '&uploadProcessId=' +
          uploadProcessId +
          '&columnDelimiter=' +
          columnDelimiter +
          '&decimalDelimiter=' +
          decimalDelimiter,
        senddata
      );

      return promise;
    }

    function checkLoadDataThread(threadid, deferred, count, isUsingProgress) {
      var promise = $http.get(
        '/services/{portalid}/loading/checkDataLoading?f=json' +
          '&threadid=' +
          threadid
      );
      promise.then(function(res0) {
        var res = res0.data.replace('_ao_', '{');
        res = res.replace(/_af_/g, '}');
        res = res.replace(/_q_/g, '"');
        res = res.replace(/_p_/g, ':');
        var jsRes = JSON.parse(res);
        if (jsRes.isalive) {
          if (!isUsingProgress){
            require('toastr').info($filter('translate')('importexportwidget.importing'));
          }
          var delay = 10000;
          if (count < 3) delay = 5000;
          $timeout(function() {
            checkLoadDataThread(threadid, deferred, ++count, isUsingProgress);
          }, delay);
        } else {
          if (jsRes.result == -1) {
            if (!isUsingProgress){
              require('toastr').error($filter('translate')('importexportwidget.importFailedWithError'));
            }
            jsRes.result = 0;
          }
          // dans le cas de succès il ne faut pas gérer le status içi,
          // il faut le géré dans le .then (il y a bcp de cas spécifiques)
          deferred.resolve({ data: jsRes.result });
        }
      });
    }

    /**
     * Function: loaddata
     */

    function loaddata(
      uploadProcessId,
      sourceLayerName,
      destLayerUID,
      attribCorresp,
      srcsrid,
      cqlFilter,
      cancelReplace,
      differencial,
      applyRules,
      gps,
      srcTableId,
      dstTableId,
      gpsfieldname,
      gpsnewrow,
      gpsupdatedrow,
      defaultValues,
      copyData,
      defaultDateFormat,
      isUsingProgress,
      historicuid,
      commentaire,
      appname
    ) {
      var deferred = $q.defer();

      if (cqlFilter === undefined) cqlFilter = '';
      if (cancelReplace === undefined) cancelReplace = false;
      if (differencial === undefined) differencial = false;
      if (applyRules === undefined) applyRules = false;
      if (gps === undefined) gps = false;
      if (srcTableId === undefined) srcTableId = '';
      if (dstTableId === undefined) dstTableId = '';
      if (gpsfieldname === undefined) gpsfieldname = '';
      if (gpsnewrow === undefined) gpsnewrow = '';
      if (gpsupdatedrow === undefined) gpsupdatedrow = '';
      if (defaultValues === undefined) defaultValues = '';
      if (copyData === undefined) copyData = false;
      if (defaultDateFormat === undefined) defaultDateFormat = '';
      if (historicuid === undefined) historicuid = '';
      if (commentaire === undefined) commentaire = '';
      if (appname === undefined) appname = '';

      //null
      var senddata = {
        attribCorresp: attribCorresp,
        defaultValues: defaultValues,
        defaultDateFormat: defaultDateFormat,
        cqlFilter: cqlFilter,
        historicuid: historicuid,
        commentaire: commentaire,
        appname: appname,
      };
      var promise = $http.post(
        '/services/{portalid}/loading/loadData?f=json' +
          '&uploadProcessId=' +
          uploadProcessId +
          '&sourceLayerName=' +
          sourceLayerName +
          '&destLayerUID=' +
          destLayerUID +
          '&srcsrid=' +
          srcsrid +
          '&cqlFilter=' +
          cqlFilter +
          '&cancelReplace=' +
          cancelReplace +
          '&differencial=' +
          differencial +
          '&applyRules=' +
          applyRules +
          '&gps=' +
          gps +
          '&srcTableId=' +
          srcTableId +
          '&dstTableId=' +
          dstTableId +
          '&gpsfieldname=' +
          gpsfieldname +
          '&gpsnewrow=' +
          gpsnewrow +
          '&gpsupdatedrow=' +
          gpsupdatedrow +
          '&copyData=' +
          copyData,
        senddata
      );
      promise.then(function(res) {
        checkLoadDataThread(res.data, deferred, 0, isUsingProgress);
      });
      return deferred.promise;
    }

    /**
     * Function: loaddata
     */

    function loadandprojectdata(params) {
      var deferred = $q.defer();

      if (params.cqlFilter === undefined) params.cqlFilter = '';
      if (params.cancelReplace === undefined) params.cancelReplace = false;
      if (params.differencial === undefined) params.differencial = false;
      if (params.gps === undefined) params.gps = false;
      if (params.srcTableId === undefined) params.srcTableId = '';
      if (params.dstTableId === undefined) params.dstTableId = '';
      if (params.gpsfieldname === undefined) params.gpsfieldname = '';
      if (params.gpsnewrow === undefined) params.gpsnewrow = '';
      if (params.gpsupdatedrow === undefined) params.gpsupdatedrow = '';
      if (params.fileEncoding === undefined) params.fileEncoding = '';

      //null
      var senddata = params.attribCorresp;
      var promise = $http.post(
        '/services/{portalid}/loading/loadAndProjectData?f=json' +
          '&uploadProcessId=' + params.uploadProcessId +
          '&sourceLayerName=' + params.sourceLayerName +
          '&destLayerUID=' + params.destLayerUID +
          '&srcsrid=' + params.srcsrid +
          '&destsrid=' + params.destsrid +
          '&cqlFilter=' + params.cqlFilter +
          '&cancelReplace=' + params.cancelReplace +
          '&differencial=' + params.differencial +
          '&gps=' + params.gps +
          '&srcTableId=' + params.srcTableId +
          '&dstTableId=' + params.dstTableId +
          '&gpsfieldname=' + params.gpsfieldname +
          '&gpsnewrow=' + params.gpsnewrow +
          '&gpsupdatedrow=' + params.gpsupdatedrow +
          '&fileencoding=' + params.fileEncoding,
        senddata
      );
      promise.then(function(res) {
        checkLoadDataThread(res.data, deferred, 0);
      });
      return deferred.promise;
    }

    function loaddataCsv(
      uploadProcessId,
      sourceLayerName,
      destLayerUID,
      attribCorresp,
      defaultValues,
      differencial,
      srcTableId,
      dstTableId,
      defaultDateFormat
    ) {
      var deferred = $q.defer();

      if (defaultValues === undefined) defaultValues = '';
      if (differencial === undefined) differencial = false;
      if (srcTableId === undefined) srcTableId = '';
      if (dstTableId === undefined) dstTableId = '';
      if (defaultDateFormat === undefined) defaultDateFormat = '';

      //null
      var senddata = {
        attribCorresp: attribCorresp,
        defaultValues: defaultValues,
        differencial: differencial,
        srcTableId: srcTableId,
        dstTableId: dstTableId,
        defaultDateFormat: defaultDateFormat,
      };

      var promise = $http.post(
        '/services/{portalid}/loading/loadDataCsv?f=json' +
          '&uploadProcessId=' +
          uploadProcessId +
          '&sourceLayerName=' +
          sourceLayerName +
          '&destLayerUID=' +
          destLayerUID,
        senddata
      );
      promise.then(function(res) {
        checkLoadDataThread(res.data, deferred, 0);
      });

      return deferred.promise;
    }

    /**
     *
     * @param {String} uploadProcessId uid identifiant du processDropZone (nom du sous-dossier dans le dossier UPLOAD du repo)
     * @param {String} incrs système de coordonnées des objets géographiques du fichier importé
     * @param {String} filetype format du fichier importé
     * @param {String} separator caractère séparateur de champ d'un fichier CSV (défini dans le widget)
     * @param {boolean} geographic est true si le fichier importé contient des objets avec coordonnées
     * @param {String} geomcolonneType nom du type de géométrie présente dans le fichier importé (WKT, XY...)
     * @param {String} geomcolonneName nom du champ contenant la géométrie dans le fichier importé
     * @param {String} geomcolonneNameX nom du champ contenant la coordonnée X dans le fichier importé
     * @param {String} geomcolonneNameY nom du champ contenant la coordonnée Y dans le fichier importé
     * @param {String} currentsridName code de la projection utilisée dans l'application carte
     * @param {number|null} encoding identifiant de l'encodage de texte à utiliser pour le fichier CSV importé
     * @return {Promise}
     */
    function getGeoJson(uploadProcessId, incrs, filetype, separator, geographic,
      geomcolonneType, geomcolonneName, geomcolonneNameX, geomcolonneNameY,
      currentsridName, encoding
    ) {
      if (incrs === undefined) incrs = '';
      if (angular.isUndefined(incrs)) geographic = false;
      if (angular.isUndefined(geomcolonneType)) geomcolonneType = '';
      if (angular.isUndefined(geomcolonneName)) geomcolonneName = '';
      if (angular.isUndefined(geomcolonneNameX)) geomcolonneNameX = '';
      if (angular.isUndefined(geomcolonneNameY)) geomcolonneNameY = '';
      if (angular.isUndefined(currentsridName)) currentsridName = '';

      //null
      var senddata = null;
      //null
      if (angular.isDefined(separator)) senddata = separator;
      let ft = '';
      if (filetype) {
        ft = '&filetype=' + filetype;
      }
      return $http.post(
        '/services/{portalid}/loading/getgeojson?f=json' +
            '&uploadProcessId=' + uploadProcessId +
            '&incrs=' + incrs +
             ft +
            '&geographic=' + geographic +
            '&currentsridName=' + currentsridName +
            '&geomcolonneType=' + geomcolonneType +
            '&geomcolonneName=' + geomcolonneName +
            '&geomcolonneNameX=' + geomcolonneNameX +
            '&geomcolonneNameY=' + geomcolonneNameY +
            (encoding ? ('&encoding=' + encoding) : ''),
        senddata
      );

    }

    function loadEdigeo(
      typedonneesentree,
      datasource,
      departement,
      communes,
      transferid,
      suffix,
      componentList,
      typeoperation,
      srid
    ) {
      var promise = $http.post(
        '/services/{portalid}/loading_cadastre/loadEdigeo?f=json' +
          '&typedonneesentree=' +
          typedonneesentree +
          '&datasource=' +
          datasource +
          '&departement=' +
          departement +
          '&communes=' +
          communes +
          '&transferid=' +
          transferid +
          '&suffix=' +
          suffix +
          '&typeoperation=' +
          typeoperation +
          '&srid=' +
          srid,
        JSON.stringify(componentList)
      );

      return promise;
    }

    const loadMajic = (datasource, datasourcehost, datasourceuser, datasourcepassword, datasourceschema,
      datasourceport,   typeoperation, prefixes, departementcode, datalot, suppresspreviousdata, dataformat, datayear, dataconnexion) => {

      var promise = $http.get(
        '/services/{portalid}/loading_cadastre/loadMajic?f=json' +
          '&datasource=' +
          datasource +
          '&datasourcehost=' +
          datasourcehost +
          '&datasourceuser=' +
          datasourceuser +
          '&datasourcepassword=' +
          encodeURIComponent(datasourcepassword) +
          '&datasourceschema=' +
          datasourceschema +
          '&datasourceport=' +
          datasourceport +
          '&typeoperation=' +
          typeoperation +
          '&prefixes=' +
          prefixes +
          '&departementcode=' +
          departementcode.toString() +
          '&datalot=' +
          datalot.toString() +
          '&suppresspreviousdata=' +
          suppresspreviousdata +
          '&dataformat=' +
          dataformat +
          '&datayear=' +
          datayear +
          '&dataconnexion=' +
          dataconnexion
      );

      return promise;
    };

    function getProgressionEdigeo(p) {
      var promise = $http.post(
        '/services/{portalid}/loading_cadastre/get/progression_edigeo?',
        p
      );

      return promise;
    }

    function getUploadedEdigeo() {
      var promise = $http.get(
        '/services/{portalid}/loading_cadastre/get/uploaded_edigeo?'
      );

      return promise;
    }

    function getUploadedMajic() {
      var promise = $http.get(
        '/services/{portalid}/loading_cadastre/get/uploaded_majic?'
      );

      return promise;
    }

    function getCreatedSchema(senddata) {
      var promise = $http.post(
        '/services/{portalid}/loading/getCreatedSchema?f=json',
        senddata
      );

      return promise;
    }

    /**
     * Envoie l'ordre au serveur d'interrompre le processus d'import EDIGEO en cours
     * @param uid uid identifiant le processus d'import EDIGEO
     * @returns {Promise} qui contient true si le processus a bien changé d'état
     */
    function stopEdigeo(uid){
      var promise = $http.get(
        '/services/{portalid}/loading_cadastre/stop_edigeo?f=json' +
          '&uid=' +
          uid
      );
      return promise;
    }

    /**
     * Récupère les fichiers du processus sous la forme d'une liste de string
     * @param processUid uid du processus d'import par dropzone (repo/UPLOAD/uid)
     * @returns {Promise} contenant les fichiers sous la forme d'une liste de string
     * @see importgpxwidget
     */
    function loadFileAsString(processUid) {
      return $http.get(
        '/services/{portalid}/loading/loadFileAsString?f=json' +
          '&uid=' +
          processUid
      );
    }

    /**
     * Récupère la liste des métadonnées des photos présentes dans un sous-dossier du processus d'import
     * @param processUid uid du processus d'import
     * @param srid code EPSG de la projection courante de la carte pour re-projeter dans le back (abandonné)
     * @returns {Promise} contenant une liste de DTO de type {@code PhotoAttachmentMetadata}
     * @see importgpxwidget
     */
    function getProcessPicturesExifMetadata(processUid, srid) {
      return $http.get(
        '/services/{portalid}/loading/getExifMetadataInFolder?f=json' +
          '&uid=' +
          processUid +
          '&srid=' +
          srid
      );
    }

    /**
     * Supprime un fichier dans le dossier du processus d'import UPLOAD/
     * @param processUid id du processus d'import en cours
     * @param fileName nom du fichier à supprimer
     * @return {boolean}
     */
    function removeProcessFile(processUid, fileName){
      return $http.get(
        '/services/{portalid}/file/removeUploaded?f=json' +
          '&processId=' +
          processUid +
          '&fileName=' +
          fileName
      );
    }

    /**
     * Efface les dossiers contenus dans upload depuis 1 jour
     * @param processUid uid du processus d'import de fichier
     * @returns {Promise} ayant le code 200
     * @see importgpxwidget
     */
    function removeProcessFiles(processUid){
      return $http.get(
        '/services/{portalid}/file/removeAllUploaded?f=json' +
          '&processId=' +
          processUid
      );
    }

    /**
     * Récupère le status du processus d'export de fichier (SHP, CSV...)
     * @param process processus d'export de fichier
     * @return {Promise} contenant le processus
     */
    function getProgressionExport(process) {
      return $http.post(
        '/services/{portalid}/export/getExportProgression?',process
      );
    }

    /**
     * Récupère le numero du departement
     * @param process processus d'export de fichier
     * @return {Promise} contenant le processus
     */
    const getDepartementMajicCode = (dep) => {
      return $http.post(
        '/services/{portalid}/export/getDepartementMajicCode?',dep
      );
    };

    /**
     * Appel API pour compter le nombre d'entités présentes dans le fichier
     * qui répondent à la clause where du cqlFilter
     * @param {string} processUid identifiant du processus d'import.
     * Nom du dossier contenant les shp dans le dossier UPLOAD du repo
     * @param {string} sourceLayerName nom du fichier shp en cours d'import
     * @param {string} cqlFilter clause where filtrant les entités à importer
     * @return {Promise} contient un nombre entier correspondant au nombre d'entités à importer.
     */
    const countFeaturesFromFile = (processUid, sourceLayerName, cqlFilter) => {
      return $http.get('/services/{portalid}/loading/countFeaturesFromFile?f=json' +
           '&uploadProcessId=' + processUid +
           '&sourceLayerName=' + sourceLayerName +
           '&cqlFilter=' + cqlFilter
      );
    };

    return {
      epanetexport: epanetexport,
      ImportExportFactory: ImportExportFactory,
      exportfeaturecollection: exportfeaturecollection,
      exportLayersFeatures: exportLayersFeatures,
      checkExportStatus: checkExportStatus,
      loadSchema: loadSchema,
      loadSchemaCsv: loadSchemaCsv,
      loaddata: loaddata,
      loadandprojectdata: loadandprojectdata,
      loaddataCsv: loaddataCsv,
      getGeoJson: getGeoJson,
      loadEdigeo: loadEdigeo,
      getProgressionEdigeo: getProgressionEdigeo,
      getUploadedEdigeo: getUploadedEdigeo,
      getUploadedMajic: getUploadedMajic,
      loadMajic: loadMajic,
      getCreatedSchema: getCreatedSchema,
      stopEdigeo:stopEdigeo,
      loadFileAsString: loadFileAsString,
      getProcessPicturesExifMetadata: getProcessPicturesExifMetadata,
      removeProcessFile: removeProcessFile,
      removeProcessFiles: removeProcessFiles,
      getProgressionExport: getProgressionExport,
      getDepartementMajicCode: getDepartementMajicCode,
      getDataTakenFromZip: getDataTakenFromZip,
      countFeaturesFromFile: countFeaturesFromFile
    };
  };
  ImportExportFactory.$inject = ['$http', '$q', '$translate', '$timeout', '$filter'];
  return ImportExportFactory;
});
