'use strict';
define(function() {
  /**
   * Class : DataStoreInfoFactory
   * Factory WebServices
   */

  var DataStoreInfoFactory = function($http, $timeout, gaUrlUtils, $q, $filter,FeatureTypeFactory) {
    var DataStoreInfoFactory = {};

    var resources = { datastores: [] };

    var specialHpoAppUid = { uid: undefined };

    /**
     * Function: add
     */
    function add(senddata) {
      var promise = $http.post(
        '/services/{portalid}/model/datastore/add?f=json',
        senddata
      );
      promise.then(function(res) {
        resources.datastores.push(res.data);
      });
      return promise;
    }

    /**
     * Function: remove
     */
    function remove(name, id) {
      var promise = $http.get(
        '/services/{portalid}/model/datastore/remove?f=json' + '&name=' + name
      );
      promise.then(() => {
        var deleteIndex = resources.datastores
          .map(function(x) {
            return x.uid;
          })
          .indexOf(id);
        resources.datastores.splice(deleteIndex, 1);
        FeatureTypeFactory.get(true);
        require('toastr').success(
          $filter('translate')('common.featuretypes.deleteDatastoreOK'));
      },(err) =>{
        if (err.data === 'common.featuretypes.geoserverDeleteDatasource_notOK') {
          var deleteIndex2 = resources.datastores
          .map(function(x) {
            return x.uid;
          })
          .indexOf(id);
          resources.datastores.splice(deleteIndex2, 1);
          require('toastr').warning(
            $filter('translate')('common.featuretypes.geoserverDeleteDatasource_notOK'));
        } else {
          require('toastr').error(
            $filter('translate')(err.data));
        }

      });
      return promise;
    }

    /**
     * Function: get
     */
    function get(portalid) {
      var promise = portalid
        ? $http.get('/services/' + portalid + '/model/datastore/get?f=json')
        : $http.get('/services/{portalid}/model/datastore/get?f=json');

      promise.then(function(res) {
        // only if we retrieved data for the current portal
        if (!portalid) {
          if (specialHpoAppUid.uid) {
            var uids = resources.datastores.map(function(x) {
              return x.uid;
            });
            for (var i = 0; i < res.data.length; i++) {
              if (res.data[i] && (res.data[i].uid == specialHpoAppUid.uid || res.data[i].type == "ArcGis")) {
                var idx = uids.indexOf(res.data[i].uid);
                if (~idx) resources.datastores[idx] = res.data[i];
                else resources.datastores.push(res.data[i]);
              }
            }
          } else {
            resources.datastores = res.data;
          }
        }
      });
      return promise;
    }

    /**
     * Renvoie le datastore ayant pour nom
     * @param name
     * @returns {*}
     */
    const getDataStoreByName = (name) => {
      for(const datastore of resources.datastores) {
        if(name === datastore.name) {
          return datastore;
        }
      }
    };


    /**
     * Récupération des sources de données ArcGis
     */
    const getEsriDataStores = () => {
      const promise = $http.get('/services/{portalid}/model/datastore/getEsriDataStores?f=json');
      promise.then(() => {},
          () => {
            require('toastr').error(
            $filter('translate')('datatable.errorGettingArcGisDatatable'));
          }
      );
      return promise;
    };

    /**
     * Function: update
     */
    function update(senddata, oldname) {
      // KIS-3278: supprime l'ancienne propriété "arcGIS" car elle n'existe plus dans la classe Java "DatastoreInfo" (erreur de désérialization KIS-2822)
      if (senddata.hasOwnProperty('arcGIS')) {
        delete senddata.arcGIS;
      }
      var promise = $http.post(
        '/services/{portalid}/model/datastore/update?f=json&oldname=' + oldname,
        senddata
      );
      promise.then(function(res) {
        var replaceIndex = resources.datastores
          .map(function(x) {
            return x.uid;
          })
          .indexOf(senddata.uid);
        resources.datastores[replaceIndex] = res.data;
      });
      return promise;
    }

    /**
     * Retourne toutes les tables pour un datastore
     */
    function tablesget(datastorename) {
      var promise = $http.get(
        '/services/{portalid}/model/datastore/' +
          datastorename +
          '/table/get?f=json' +
          '&datastorename=' +
          datastorename
      );
      promise.then(function(res) {});
      return promise;
    }

    /**
     * Retourne les données des couches pour un datastore
     * @param datastoreName
     * @returns {*}
     */
    const getLayersDataByDatastore = (datastoreName, orderBy) => {
      const promise = $http.get('/services/{portalid}/model/datastore'
          + '/table/getLayersDataByDatastore?f=json'
          + '&datastoreName=' + datastoreName
          + '&orderBy=' + orderBy);
      promise.then(() => {},
          () => {
            require('toastr').error(
                $filter('translate')('model.featuretypes.errorGettingLayers'));
          }
      );
      return promise;
    };


    /**
     * Function: addtable
     */
    function addtable(datastorename, senddata, destinationSRID, forceUpdateAttributsAndSrid) {
      var promise = $http.post(
        '/services/{portalid}/model/datastore/' +
          datastorename +
          '/table/addtable?f=json' +
          '&datastorename=' +
          datastorename +
          '&destsrid=' +
          destinationSRID+
          '&forceUpdateAttributsAndSrid='+
          !!forceUpdateAttributsAndSrid,
        senddata
      );
      return promise;
    }

    /**
     * Function: tablesgetfinfo
     */
    function tablesgetfinfo(datastorename, tablename) {
      var tname = gaUrlUtils.encodeUriQuery(tablename);
      var promise = $http.get(
        '/services/{portalid}/model/datastore/' +
          datastorename +
          '/table/featureinfo?f=json' +
          '&datastorename=' +
          datastorename +
          '&tablename=' +
          tname
      );

      return promise;
    }

    /**
     * Function: tablesgetreloadedFinfo
     */
    function tablesgetreloadedFinfo(datastorename, tablename, ftiUid, resetAliasFromArcGIS) {
      var tname = gaUrlUtils.encodeUriQuery(tablename);
      var promise = $http.get(
        '/services/{portalid}/model/datastore/' +
          datastorename +
          '/table/featureinfo?f=json' +
          '&datastorename=' +
          datastorename +
          '&tablename=' +
          tname +
          '&ftiUid=' +
          ftiUid +
          '&reset=' +
          resetAliasFromArcGIS
      );

      return promise;
    }

    /**
     * Connexion test
     */
    function connect_test(dataStoreName) {
      var promise = $http.get(
        '/services/{portalid}/model/datastore/' +
          dataStoreName +
          '/connect_test?f=json'
      );
      promise.then(function(res) {
        console.log(res);
      });
      return promise;
    }


    /**
     * Creation ou réparer la bdd
     */

    function createOrRepairDB(createOrRepairDBParam) {
      return $http.post(
        '/services/{portalid}/model/datastore/createOrRepairDB?f=json', createOrRepairDBParam
      );
    }
     /**
     * getEsriToken
     */
    function getEsriToken(dataStoreName) {
      var promise = $http.get(
        '/services/{portalid}/model/datastore/' +
          dataStoreName +
          '/getEsriToken?f=json'
      );
      promise.then(function(res) {
        console.log(res);
      });
      return promise;
    }

    /**
     * getEsriUrl
     */
    function getEsriUrl(dataStoreName) {
      var promise = $http.get(
        '/services/{portalid}/model/datastore/' +
          dataStoreName +
          '/getEsriUrl?f=json'
      );
      return promise;
    }

    /**
     * Récupère une map contenant la longueur de chaque champ de la table
     * @param dataStoreName nom du datastore
     * @param tablename nom de la table
     * @returns {Map} contenant: nom_champ (string) -> longueur_champ (integer)
     * @see importgpxwidget.addFeaturesToFtid
     * @see importdxfwidget.addFeaturesToFtid
     */
    function getTableColumnsLength(dataStoreName, tablename) {
      return $http.get(
          '/services/{portalid}/model/datastore/' +
          dataStoreName +
          '/featureinfo/getColumnsLength?f=json' +
          '&tablename=' +
          tablename
      );
    }

    /**
     * Recherche la présence d'une datasource de type "ArcGis" dans le portail
     * @param portalId uid du portail en cours d'édition
     * @return {Promise} contenant true si le portail contient au moins 1 datasource ArcGIS
     */
    function oneEsriDatasourceExists(portalId){
      let defer = $q.defer();
        get(portalId).then(
            (res) => {
              resources.datastores = res.data;
              const esriDatasources = resources.datastores.filter(ds=> ds.type === 'ArcGis');
              defer.resolve(esriDatasources.length > 0);
            }
        );
        return defer.promise;
    }

    /**
     * Recherche la présence d'une datasource de type "PostGIS" dans le portail
     * @param portalId uid du portail en cours d'édition
     * @return {Promise} contenant true si le portail contient au moins 1 datasource PostGIS
     */
    function onePostGisDatasourceExists(portalId){
      let defer = $q.defer();
      get(portalId).then(
          (res) => {
            resources.datastores = res.data;
            const esriDatasources = resources.datastores.filter(ds=> ds.type === 'postgis');
            defer.resolve(esriDatasources.length > 0);
          }
      );
      return defer.promise;
    }

    /**
     *  cette fonction applique le script d'anonymisation de la BD
     */
    function anonymizeDb (dataStoreName) {
      return $http.get(
        '/services/{portalid}/model/datastore/anonymizeDb?f=json&dataStoreName='
        + dataStoreName
      );
    }

    return {
      DataStoreInfoFactory: DataStoreInfoFactory,
      resources: resources,
      specialHpoAppUid: specialHpoAppUid,
      add: add,
      update: update,
      remove: remove,
      get: get,
      getDataStoreByName: getDataStoreByName,
      getEsriDataStores: getEsriDataStores,
      tablesget: tablesget,
      getLayersDataByDatastore: getLayersDataByDatastore,
      addtable: addtable,
      tablesgetfinfo: tablesgetfinfo,
      tablesgetreloadedFinfo: tablesgetreloadedFinfo,
      connect_test: connect_test,
      createOrRepairDB:createOrRepairDB,
      getEsriToken:getEsriToken,
      getEsriUrl:getEsriUrl,
      getTableColumnsLength: getTableColumnsLength,
      oneEsriDatasourceExists: oneEsriDatasourceExists,
      onePostGisDatasourceExists: onePostGisDatasourceExists,
      anonymizeDb:anonymizeDb,
    };
  };
  DataStoreInfoFactory.$inject = ['$http', '$timeout', 'gaUrlUtils', '$q', '$filter','FeatureTypeFactory'];
  return DataStoreInfoFactory;
});
