'use strict';
define(function() {
  var ancBacMainReport = function(
    AncAppFactory,
    BacAppFactory,
    gaJsUtils,
    gaDomUtils,
    $rootScope,
    FeatureTypeFactory,
    GoogleMapsFactory,
    ogcFactory,
    $timeout
  ) {
    return {
      templateUrl:
        'js/XG/widgets/ancapp/main/views/anc_bac/anc_bac_main_report.html',
      restrict: 'EA',
      scope: {
        existCciControle: '=?',
        apptype: '=?',
        currentReport: '=',
        saveReport: '&', // save function located in
        saveReportOmega: '&', // listeDossiers.js,
        refreshReports: '&?', // refresh whole reports list
        changeStatutDossier: '&?',
        subventionDossier: '&?',
      },
      link: function(scope, elt, attrs, ctrl) {
        var CurrentAppFactory =
          scope.apptype == 'bac' ? BacAppFactory : AncAppFactory;
        var dossierName =
          scope.apptype == 'bac' ? 'kis_bac_dossier' : 'kis_anc_dossier';
        scope.dossierFti = angular.copy(
          FeatureTypeFactory.getFeatureByNameAndDatastore(
            CurrentAppFactory.appCfg.main.datastore,
            dossierName
          )
        );
        scope.parcellesFti = FeatureTypeFactory.getFeatureByNameAndDatastore(
          CurrentAppFactory.appCfg.main.datastore,
          CurrentAppFactory.appCfg.main.parcellesCfg.emplacement
        );

        scope.featuresConfig =
          CurrentAppFactory.appCfg.main.mapConfiguration.featuresConfig;
        scope.bbox = CurrentAppFactory.appCfg.main.mapConfiguration.bbox;

        scope.geocoderCtrl = CurrentAppFactory.appCfg.main.properties.geocoder;
        scope.subventionnableDossier =
          CurrentAppFactory.appCfg.main.properties.subventionnableDossier;
        scope.classColSizeTitle = scope.subventionnableDossier
          ? 'col-xs-3'
          : 'col-xs-6';
        scope.classColSizeInput = scope.subventionnableDossier
          ? 'col-sm-3 col-xs-6'
          : 'col-sm-6 col-xs-12';
        if (angular.isDefined(scope.geocoderCtrl)) {
          scope.geocoderCtrl.forEach(function(geocoder) {
            if (geocoder.active === true) scope.geocoder = geocoder.id;
          });
        }

        if (angular.isUndefined(scope.geocoder)) {
          scope.geocoder = 'google';
        }

        if (typeof AppAndroid !== 'undefined') scope.AppAndroid = AppAndroid;

        if (scope.currentReport.properties.alerte_echeance) {
          let alerte = CurrentAppFactory.getAlerteColorClass(
            Date.parse(scope.currentReport.properties.alerte_echeance)
          );
          scope.alerteColorClass = alerte.alerteColorClass;
        } else {
          scope.alerteColorClass = '';
        }

        scope.$on('alerteColor', function(event, data) {
          scope.alerteColorClass = data.alerteColorClass;
        });

        $timeout(function() {
          scope.$on('checkDirtyReport', function(v, data, newData) {
            if (angular.isDefined(newData) && angular.isDefined(data)) {
              var tmpData = angular.copy(data);
              var tmpNewData = angular.copy(newData);
              // need to clean up copy of current report to avoid
              // hazardous trigger
              [
                'prochain_controle',
                'type_dernier_controle',
                'type_prochain_controle_preconise',
                'dernierControle',
                'date_dernier_controle',
                'date_prochain_controle_preconise',
                'date_prochain_controle',
                'avis_dernier_controle',
                'locataires',
                'proprietaires',
                'etablissement',
                'activite_principale',
                'activite_secondaire',
              ].forEach(function(rm) {
                if (angular.isDefined(tmpData[rm])) delete tmpData[rm];
                if (angular.isDefined(tmpNewData[rm])) delete tmpNewData[rm];
              });

              var cleanData = gaJsUtils.removeEmpty(tmpData, true);
              var cleanNewData = gaJsUtils.removeEmpty(tmpNewData, true);

              if (JSON.stringify(cleanData) != JSON.stringify(cleanNewData)) {
                scope.$emit('reportIsDirty', {});
              }
            }
          });
        });

        /***************************************************************
         * STATUT
         **************************************************************/

        scope.openChangeDossierStatutDialog = function() {
          scope.changeStatutDossier({
            dossier: scope.currentReport,
          });
        };

        /***************************************************************
         * POSITION
         **************************************************************/

        scope.appliqueFromMapPicker = { coord: false, adresse: false };
        scope.appliqueFromMapAutocomplete = {
          coord: false,
          adresse: false,
        };

        /*---------------------

                 Address helpers
                 */
        scope.tmpPositionFromMapPicker = {};
        scope.tmpPositionFromAutocomplete = {};
        var watcher1 = scope.$watch('tmpPositionFromMapPicker', function() {
          scope.appliqueFromMapPicker = {
            coord: false,
            adresse: false,
          };
        });
        var watcher2 = scope.$watch(
          'tmpPositionFromAutocomplete.v',
          function() {
            if (angular.isDefined(scope.tmpPositionFromAutocomplete))
              getAdresseFromGeocoder(
                scope.tmpPositionFromAutocomplete,
                'auto_complete'
              );

            scope.appliqueFromMapAutocomplete = {
              coord: false,
              adresse: false,
            };
          },
          1
        );

        var positionChange = $rootScope.$on(
          'PositionFromMapPositionPickerChange',
          function() {
            if (angular.isDefined(scope.tmpPositionFromMapPicker))
              getAdresseFromGeocoder(
                scope.tmpPositionFromMapPicker,
                'map_picker'
              );

            scope.appliqueFromMapAutocomplete = {
              coord: false,
              adresse: false,
            };
            scope.appliqueFromMapPicker = {
              coord: false,
              adresse: false,
            };
          }
        );

        var appliquer_coordonnees_dossier = function(feature, coord, type) {
          scope.currentReport.geometry = feature.geometry;

          if (type == 'map_picker') {
            scope.appliqueFromMapPicker.coord = true;
            scope.appliqueFromMapAutocomplete.coord = false;
          } else {
            scope.appliqueFromMapPicker.coord = false;
            scope.appliqueFromMapAutocomplete.coord = true;
          }

          gaDomUtils.hideGlobalLoader();
          scope.saveReport();
        };
        /**
         * apply coordinates to current geometry
         *
         * @TODO Deplace dans la partie ancBacPositionDossier
         *       normalement, a supprimer si deja le cas
         * @param coord
         */
        scope.appliquerCoordonneesDossier = function(coord, type) {
          type = type || 'map_picker';

          // convert lat lon
          if (type == 'autocomplete') {
            if (
              angular.isDefined(scope.geocoder) &&
              scope.geocoder != 'google'
            ) {
              coord = {
                lat:
                  scope.tmpPositionFromAutocomplete.v.geometry.coordinates[1],
                lng:
                  scope.tmpPositionFromAutocomplete.v.geometry.coordinates[0],
              };
            }

            var coord = GoogleMapsFactory.latLngTocoordinates(
              coord,
              'EPSG:3857'
            );
            console.log(coord);
          } else {
            var coord = GoogleMapsFactory.latLngTocoordinates(
              {
                lat: coord[1],
                lng: coord[0],
              },
              'EPSG:3857'
            );
            console.log(coord);
          }

          var format = new ol.format.GeoJSON();
          var feature = format.writeFeatureObject(
            new ol.Feature({
              geometry: new ol.geom.Point(coord),
            })
          );

          if (scope.parcellesFti.geographic == true) {
            var x = feature.geometry.coordinates[0];
            var y = feature.geometry.coordinates[1];
            var leftX = x - 3;
            var rightX = x + 3;
            var bottomY = y - 3;
            var topY = y + 3;

            gaDomUtils.showGlobalLoader();
            ogcFactory
              .getfeatures(
                'GetFeature',
                'WFS',
                '1.0.0',
                scope.parcellesFti.uid,
                'json',
                'EPSG:3857',
                'INTERSECTS(geom, POLYGON((' +
                  leftX +
                  ' ' +
                  bottomY +
                  ',' +
                  rightX +
                  ' ' +
                  bottomY +
                  ',' +
                  rightX +
                  ' ' +
                  topY +
                  ',' +
                  leftX +
                  ' ' +
                  topY +
                  ',' +
                  leftX +
                  ' ' +
                  bottomY +
                  ')))'
              )
              .then(
                function(res) {
                  if (res.data.features.length) {
                    var typeGeometrieParcelles =
                      res.data.features[0].geometry.type;
                    if (
                      typeGeometrieParcelles != 'MultiPolygon' &&
                      typeGeometrieParcelles != 'Polygon'
                    ) {
                      console.log(
                        "ERREUR : le type de géométrie des parcelles n'est pas supporté ()"
                      );
                    } else {
                      res.data.features.forEach(function(parcelle) {
                        var cql_filter = '';
                        if (parcelle.geometry.type == 'MultiPolygon') {
                          var coords_parcelle =
                            parcelle.geometry.coordinates[0][0];
                        } else if (parcelle.geometry.type == 'Polygon') {
                          var coords_parcelle =
                            parcelle.geometry.coordinates[0];
                        }

                        for (var i = 0; i < coords_parcelle.length; i++) {
                          if (i == coords_parcelle.length - 1) {
                            cql_filter =
                              cql_filter +
                              coords_parcelle[i][0] +
                              ' ' +
                              coords_parcelle[i][1];
                          } else {
                            cql_filter =
                              cql_filter +
                              coords_parcelle[i][0] +
                              ' ' +
                              coords_parcelle[i][1] +
                              ',';
                          }
                        }

                        ogcFactory
                          .getfeaturespost(
                            'INTERSECTS(geom, POLYGON((' + cql_filter + ')))',
                            scope.dossierFti.uid,
                            'EPSG:3857'
                          )
                          .then(
                            function(res) {
                              if (res.data.features.length) {
                                // verif si deja pas deja
                                // associe à un dossier sauf
                                // si dossier en cours....
                                var ans = 1;
                                if (
                                  res.data.features[0].id !==
                                  scope.currentReport.id
                                ) {
                                  var ans = confirm(
                                    'Le dossier ' +
                                      res.data.features[0].properties
                                        .ref_dossier +
                                      " est déjà sur cette parcelle!\nVoulez-vous l'associer à ce dossier également ?"
                                  );
                                }
                                if (ans) {
                                  appliquer_coordonnees_dossier(
                                    feature,
                                    coord,
                                    type
                                  );
                                } else {
                                  gaDomUtils.hideGlobalLoader();
                                }
                              } else {
                                appliquer_coordonnees_dossier(
                                  feature,
                                  coord,
                                  type
                                );
                              }
                            },
                            function() {
                              require('toastr').error(
                                'Erreur lors de la récupération des parcelles à cette adresse (2).'
                              );
                              gaDomUtils.hideGlobalLoader();
                            }
                          );
                      });
                    }
                  } else {
                    appliquer_coordonnees_dossier(feature, coord, type);
                  }
                },
                function() {
                  require('toastr').error(
                    'Erreur lors de la récupération des parcelles à cette adresse.'
                  );
                  gaDomUtils.hideGlobalLoader();
                }
              );
          } else {
            appliquer_coordonnees_dossier(feature, coord, type);
          }
        };

        if (scope.apptype == 'anc') {
          var listeDesVillesActives = CurrentAppFactory.appCfg.main.infosSpancListeVillesCfg.filter(
            function(x) {
              return x.gere_spanc;
            }
          );
        } else {
          var listeDesVillesActives = CurrentAppFactory.appCfg.main.extra.infosSassListeVillesCfg.filter(
            function(x) {
              return x.gere_sass;
            }
          );
        }

        // TODO EST DEJA DEPLACE DANS LE ANCBACPSOTIONDOSSIER
        /**
         * apply address to dossier
         *
         * @param adresse
         *
         */
        scope.appliquerAdresseDossier = function(adresse, type) {
          [
            'adresse_num_rue',
            'adresse_rue',
            'adresse_ville',
            'adresse_pays',
            'adresse_cp',
            'adresse_complement',
            'adresse_batiment',
            'adresse_appt',
            'adresse_etage',
            'adresse_escalier',
            'adresse_bp',
            'adresse_num_rue_extra',
          ].forEach(function(x) {
            delete scope.currentReport.properties[x];
          });

          if (angular.isDefined(scope.geocoder) && scope.geocoder != 'google') {
            var getAdressComponent;

            if (type != 'autocomplete')
              adresse.properties = adresse.infos.properties;

            if (angular.isDefined(adresse)) {
              adresse.address_components = [];

              Object.keys(adresse.properties).forEach(function(key) {
                if (adresse.properties[key].length) {
                  switch (key) {
                    case 'housenumber':
                      adresse.address_components.push({
                        types: 'street_number',
                        long_name: adresse.properties[key],
                      });
                      break;
                    case 'city':
                      adresse.address_components.push({
                        types: 'locality',
                        long_name: adresse.properties[key],
                      });
                      break;
                    case 'citycode':
                      adresse.address_components.push({
                        types: 'postal_code',
                        long_name: adresse.properties[key],
                      });
                      break;
                    case 'street':
                      adresse.address_components.push({
                        types: 'route',
                        long_name: adresse.properties[key],
                      });
                      break;
                    case 'country':
                      adresse.address_components.push({
                        types: 'country',
                        long_name: 'France',
                      });
                  }
                }
              });
            }
          } else {
            if (type === 'map_picker' && scope.geocoder == 'google')
              adresse = adresse.infos.place;
          }

          type = type || 'map_picker';
          if (
            angular.isDefined(adresse.address_components) &&
            adresse.address_components.length
          ) {
            adresse.address_components.forEach(function(c) {
              // reset
              [
                'street_number',
                'route',
                'locality',
                'country',
                'postal_code',
              ].forEach(function(x) {
                delete scope.currentReport.properties[x];
              });

              if (~c.types.indexOf('street_number')) {
                console.log(c.long_name);
                scope.currentReport.properties.adresse_num_rue = parseInt(
                  c.long_name,
                  10
                );
              }
              if (~c.types.indexOf('route')) {
                scope.currentReport.properties.adresse_rue = c.long_name;
              }
              if (~c.types.indexOf('locality')) {
                // alerte si ville pas connue
                var villeCorrespondance = c.long_name;
                if (listeDesVillesActives.length) {
                  var hits = listeDesVillesActives.filter(function(x) {
                    return x.value.toLowerCase() == c.long_name.toLowerCase();
                  });
                  // aucune correspondance directe (lowercase)
                  if (!hits.length) {
                    // tentative avec levenshtein
                    var hitsLev = listeDesVillesActives
                      .filter(function(x) {
                        x.lev = gaJsUtils.levenshtein(x.value, c.long_name);
                        return x.lev > 0.6;
                      })
                      .sort(function(a, b) {
                        return a.lev > b.lev ? -1 : b.lev > a.lev ? 1 : 0;
                      });

                    // rien > 0.6 avec levenshtein
                    if (!hitsLev.length) {
                      require('toastr').error(
                        "Aucune correspondance avec une commune gérée par le SPANC n'a pu être établie avec la commune <b> " +
                          c.long_name +
                          '</b>.',
                        'Attention',
                        {
                          closeButton: true,
                          timeOut: '0',
                          extendedTimeOut: '0',
                        }
                      );
                      villeCorrespondance = null;
                    } else {
                      require('toastr').warning(
                        "Aucune correspondance directe avec une commune gérée par le SPANC n'a pu être établie avec la commune <b> " +
                          c.long_name +
                          '.</b><br/><br/>' +
                          'Cependant la commune <b>' +
                          hitsLev[0].value +
                          '</b> semble correspondre et a été sélectionnée.',
                        'Information',
                        {
                          closeButton: true,
                          timeOut: '0',
                          extendedTimeOut: '0',
                        }
                      );
                      villeCorrespondance = hitsLev[0].value;
                    }
                  } else {
                    villeCorrespondance = hits[0].value;
                  }
                }
                scope.currentReport.properties.adresse_ville = villeCorrespondance;
              }
              if (~c.types.indexOf('country')) {
                scope.currentReport.properties.adresse_pays = c.long_name;
              }
              if (~c.types.indexOf('postal_code')) {
                scope.currentReport.properties.adresse_cp = c.long_name;
              }
            });
          }
          if (type == 'map_picker') {
            scope.appliqueFromMapPicker.adresse = true;
            scope.appliqueFromMapAutocomplete.adresse = false;
          } else {
            scope.appliqueFromMapPicker.adresse = false;
            scope.appliqueFromMapAutocomplete.adresse = true;
          }

          scope.saveReport();
        };

        var getAdresseFromGeocoder = function(adresse, type) {
          scope.adresseToShow = '';
          if (angular.isDefined(adresse) && Object.keys(adresse).length > 0) {
            if (scope.geocoder == 'google') {
              if (type === 'map_picker')
                scope.adresseToShow = adresse.infos.place.formatted_address;

              if (type === 'auto_complete')
                scope.adresseToShowAutoComplete = adresse.v.formatted_address;
            } else {
              if (type === 'map_picker')
                scope.adresseToShow = adresse.infos.properties.label;

              if (type === 'auto_complete')
                scope.adresseToShowAutoComplete = adresse.v.value;
            }
          }
        };

        /***************************************************************
         * Liste des villes (ANC only atm)
         **************************************************************/
        /** Tooltip affichage position du dossier * */
        scope.tooltipTitle = {};
        scope.tooltipTitle.title = 'Afficher la position du dossier';
        scope.tooltipTitle.class = 'cursorHelp';

        /**
         * unsetAlerteDossier Supression commentaire et échéance de
         * l'alerte
         */
        scope.unsetAlerteDossier = function() {
          delete scope.currentReport.properties.alerte_echeance;
          delete scope.currentReport.properties.alerte;
        };
        scope.checkSubvention = function() {
          scope.subventionDossier({
            check: scope.currentReport.properties.subventionnable_dossier,
          });
        };

        // cleanup
        scope.$on('$destroy', function() {
          watcher1();
          watcher2();
          positionChange();
        });
        scope.currentRelationProprio = {};
      },
    };
  };

  ancBacMainReport.$inject = [
    'AncAppFactory',
    'BacAppFactory',
    'gaJsUtils',
    'gaDomUtils',
    '$rootScope',
    'FeatureTypeFactory',
    'GoogleMapsFactory',
    'ogcFactory',
    '$timeout',
  ];
  return ancBacMainReport;
});
