'use strict';
define(function () {
    let CommonFactory = function (
      $http,
      $location,
      ConfigFactory,
      $q,
      gaJsUtils,
      $sce,
      $filter,
      FeatureTypeFactory
    ) {
      const replaceControlName = (control, preconisation, controlCfg) => {
        let controlLabel = findControlTypeLabel(control, controlCfg);
        let value = controlLabel
          ?  '<span>' + controlLabel + '</span>'
          : '';

        if (preconisation && value) {
          value =
            '<span class="muted" title="Type de contrôle préconisé"><i class="fa fa-clock-o"></i> ' +
            value +
            '</span>';
        }

        return value;
      };

      const findControlTypeLabel = (controlType, controlCfg) => {
        const control = controlCfg.find((item)=> controlType === item.type);
        return (control ? control.label_court : '');
      };

      const updateConfigWithCreateCommune = (data, appname, isancapp) => {
        // on adding : will save, every day, a temporary version
        const sauveGardes = [
          ConfigFactory.updateConfigWithCreateCommune(data, 'main', 'mainConfig', appname, isancapp),
          ConfigFactory.add(
            data,
            'main',
            'mainConfig_' + moment(new Date()).format('DD_MM_YYYY'),
            appname
          ),
        ];
        return $q.all(sauveGardes);
      };

      const getAlerteColorClass = (dateEcheance, alertFileConfig) => {
        let alerteColorClass;
        const daysBeforeAlerte = gaJsUtils.dayDiff(Date.now(), dateEcheance);
        if (daysBeforeAlerte <= alertFileConfig.red) {
          alerteColorClass = 'has_alerte_echeance redAlert';
        } else {
          if (
            daysBeforeAlerte > alertFileConfig.red &&
            daysBeforeAlerte < alertFileConfig.green
          ) {
            alerteColorClass = 'has_alerte_echeance yellowAlert';
          } else {
            alerteColorClass = 'has_alerte_echeance greenAlert';
          }
        }
        return {
          alerteColorClass:alerteColorClass,
          daysBeforeAlerte:daysBeforeAlerte
        };
      };

      const tableAlert = (crudValue, dossier, notHtml, alertFileConfig) => {
        const echeance = dossier.properties.alerte_echeance;
        let value = '';
        let alerte = {
          alerteColorClass: '',
          daysBeforeAlerte: 0,
        };

        if (alertFileConfig && echeance) {
          alerte = getAlerteColorClass(echeance, alertFileConfig);
        }
        if (crudValue) {
          if (echeance) {
            value = notHtml
              ? crudValue
              : $sce.trustAsHtml(
                  '<div class="btn btn-xs btn-default cursorHelp" title="' +
                    crudValue +
                    "\" ng-click=\"actionFromDatatable({fn:'edit_alerte_dossier',data:{report: '" +
                    dossier.id +
                    '\'}})">' +
                    '<i class="fa fa-warning ' +
                    alerte.alerteColorClass +
                    '"> ' +
                    alerte.daysBeforeAlerte +
                    ' </i>' +
                    '</div>'
                );
          } else {
            value = notHtml
              ? crudValue
              : $sce.trustAsHtml(
                  '<div class="btn btn-xs btn-default cursorHelp" title="' +
                    crudValue +
                    "\" ng-click=\"actionFromDatatable({fn:'edit_alerte_dossier',data:{report: '" +
                    dossier.id +
                    '\'}})">' +
                    '<i class="fa fa-commenting has_alerte cursorHelp" title="' +
                    crudValue +
                    '"></i>' +
                    '</div>'
                );
          }
        } else {
          if (echeance) {
            value = notHtml
              ? ''
              : $sce.trustAsHtml(
                  '<div class="btn btn-xs btn-default" title="Ajouter une alerte" ng-click="actionFromDatatable({fn:\'edit_alerte_dossier\',data:{report: \'' +
                    dossier.id +
                    '\'}})">' +
                    '<i class="fa fa-warning ' +
                    alerte.alerteColorClass +
                    '"> ' +
                    alerte.daysBeforeAlerte +
                    ' </i>' +
                    '</div>'
                );
          } else {
            value = notHtml
              ? crudValue ? crudValue.toString() : ''
              : $sce.trustAsHtml(
                  '<div class="btn btn-xs btn-default" title="Ajouter une alerte" ng-click="actionFromDatatable({fn:\'edit_alerte_dossier\',data:{report: \'' +
                    dossier.id +
                    '\'}})">' +
                    '<i class="fa fa-plus"></i>' +
                    '</div>'
                );
          }
        }
        return value || '';
      };

      const  tableStatus = (fileStatus, notHtml) => {
        let value;

        switch (fileStatus) {
          case 'ouvert': {
            value = notHtml
              ? 'Ouvert'
              : $sce.trustAsHtml(
                '<span class="bg-info spanEtatDossier">Ouvert</span>'
              );
            break;
          }
          case 'en_cours': {
            value = notHtml
              ? 'En' + '  ' + 'cours'
              : $sce.trustAsHtml(
                '<span class="bg-primary spanEtatDossier">En cours</span>'
              );
            break;
          }
          case 'sans_suite': {
            value = notHtml
              ? 'Sans' + '  ' +'suite'
              : $sce.trustAsHtml(
                '<span class="bg-warning spanEtatDossier">Sans suite</span>'
              );
            break;
          }
          case 'raccorde': {
            value = notHtml
              ? 'Raccordé'
              : $sce.trustAsHtml(
                '<span class="bg-warning spanEtatDossier">Raccordé</span>'
              );
            break;
          }
          case 'archive': {
            value = notHtml
              ? 'Archivé'
              : $sce.trustAsHtml(
                '<span class="bg-danger spanEtatDossier">Archivé</span>'
              );
            break;
          }
          default: {
            value = fileStatus;
            break;
          }
        }
        return (value || '');
      };

      const tableAddressNumber = (num, dossier, notHtml) => {
        if (num && dossier.properties.adresse_num_rue_extra) {
          return (notHtml
            ? num + ' ' + dossier.properties.adresse_num_rue_extra
            : $sce.trustAsHtml(
              num
              + ' <span class="label label-default dimmed">'
              + dossier.properties.adresse_num_rue_extra
              + '</span>'
            ));
        } else {
          return (num || '');
        }
      };

      const affectationConstruction = (
        affectationConstruction,
        dossier,
        notHtml
      ) => {
        if (dossier.properties.affectation_construction) {
          return notHtml
            ? dossier.properties.affectation_construction
            : $sce.trustAsHtml(
                ' <span class="">' +
                  dossier.properties.affectation_construction +
                  '</span>'
              );
        } else {
          return affectationConstruction || '';
        }
      };
      const lastControlAvis = (crudValue, notHtml) => {
        let value = crudValue;
        if (crudValue) {
          value = notHtml
            ? crudValue ? crudValue.toString() : ''
            : $sce.trustAsHtml(
              '<span  style="background-color: #fafafa; font-size:1em;" class="spanEtatDossierAvis">'
              + crudValue
              + '</span>'
            );
        }
        return (value || '');
      };

      const controlServiceName = (serviceControle, dossier, notHtml) => {
        let serviceControleNom;
        if (
          !serviceControle &&
          angular.isDefined(dossier.id) &&
          gaJsUtils.checkNestedProperty(
            'properties.dernierControle.serviceControle',
            dossier
          )
        ) {
          serviceControleNom = angular.copy(
            dossier.properties.dernierControle.serviceControle
          );
          serviceControleNom = serviceControleNom || '';
          return (notHtml
            ? serviceControleNom
            : $sce.trustAsHtml(
              ' <span class="">' + serviceControleNom + '</span>'
            ));
        } else {
          return notHtml
            ? (serviceControle
              ? serviceControle.toString()
              :'')
            : (serviceControle || '');
        }
      };

      const getTableValueProprietaire = (crudValue, dossier, notHtml, propertyName) =>{
        if (dossier.id && gaJsUtils.checkNestedProperty(
          'properties.proprietaires',
          dossier)
        ) {
          const first = angular.copy(dossier.properties.proprietaires);
          let displayValue = '';
          if (first) {
            for (let i = 0; i < first.length; i++) {
              if (first[i].cp) {
                displayValue += (first[i][propertyName] || '')
                  + ((i < first.length - 1) ? (notHtml ? '---' : '<br>') : '');
              }
            }
          }
          return (notHtml
            ? displayValue
            : $sce.trustAsHtml(
              ' <span class="">' + displayValue + '</span>'
            ));
        }
      }

      const numRueProprietaire = (crudValue, dossier, notHtml) => {
        if (
          angular.isDefined(dossier.id) &&
          gaJsUtils.checkNestedProperty('properties.proprietaires',
            dossier)) {
          const first = angular.copy(dossier.properties.proprietaires);
          let numRueProprietairedd = '';
          if (angular.isDefined(first)) {
            for (let i = 0; i < first.length; i++) {
              if (first[i].numRue) {
                numRueProprietairedd += first[i].numRue;
                if (first[i].numRueExtra) {
                  numRueProprietairedd += ' '
                    + first[i].numRueExtra
                    + (notHtml ? ' ' : '<br>');
                }
                numRueProprietairedd += ((i < first.length - 1)
                  ? (notHtml ? ' ' : '<br>')
                  :'');
              }
            }
          }
          return (notHtml
            ? numRueProprietairedd
            : $sce.trustAsHtml(
              ' <span class="">' + numRueProprietairedd + '</span>'
            ));
        }
      };

      const villeProprietaire = (crudValue, dossier, notHtml)=> {
        return getTableValueProprietaire(crudValue, dossier, notHtml, "ville");
      };

      const paysProprietaire = (crudValue, dossier, notHtml) => {
        return getTableValueProprietaire(crudValue, dossier, notHtml, "pays");
      };

      const rueProprietaire = (crudValue, dossier, notHtml)=> {
       return getTableValueProprietaire(crudValue, dossier, notHtml, "rue");
      };

      const cpProprietaire = (crudValue, dossier, notHtml) => {
        return getTableValueProprietaire(crudValue, dossier, notHtml, "cp");
      };

      const typeProprietaire = (crudValue, dossier, notHtml) => {
        if (
          angular.isDefined(dossier.id) &&
          gaJsUtils.checkNestedProperty('properties.proprietaires', dossier)
        ) {
          const first = angular.copy(dossier.properties.proprietaires);
          let displayValue = '';
          if (angular.isDefined(first)) {
            for (let i = 0; i < first.length; i++) {
              if (first[i].typeProprietaire) {
                const valueSeparator = ((i < first.length - 1)
                  ? (notHtml ? '---' : '<br>')
                  : '');
                const listeId = dossier.id.indexOf('anc') > -1
                  ? 'kis_anc_dossier_proprietaire'
                  : 'kis_bac_dossier_proprietaire';

                const appListeDeroulante = FeatureTypeFactory.getFeatureByUid(listeId);
                const typeProprietaireListeDeroulante =
                  getListeDeroulanteValues(appListeDeroulante,'type_proprietaire');
                displayValue += gaJsUtils.getTypeDeProprietaireValue(
                  first[i].typeProprietaire,
                  valueSeparator,
                  typeProprietaireListeDeroulante);
              }
            }
          }
          return (notHtml
            ? displayValue :
            $sce.trustAsHtml(
              ' <span class="">' + displayValue + '</span>'));
        }
      };

      const volumeFiliere = (crudValue, dossier, notHtml) => {
        if (
          angular.isDefined(dossier.id) &&
          gaJsUtils.checkNestedProperty(
            'properties.infosFilieres.volume',
            dossier
          )
        ) {
          const rowVolume = angular.copy(
            dossier.properties.infosFilieres.volume
          );
          let displayValue = '';
          switch (rowVolume) {
            case '0':
              displayValue = 'Volume inférieur à 20 EH';
              break;
            case '1':
              displayValue = 'Volume compris entre 21 et 200 EH';
              break;
            case '2':
              displayValue = 'Volume supérieur à 200 EH';
              break;
          }
          displayValue = (displayValue || '');
          return (notHtml
            ? displayValue
            : $sce.trustAsHtml(
              ' <span class="">' + displayValue + '</span>'
            ));
        }
      };

      const date_prochain_controle = (crudValue, dossier, notHtml) => {
        let value = crudValue;
        if (crudValue) {
          value = new Date(value);

          let hour = $filter('date')(value, 'HH:mm');

          // test rb bouton ouvrir calendrier
          let extraBtn = '';
          let controleId = '';
          if (
            angular.isDefined(dossier.id) &&
            gaJsUtils.checkNestedProperty(
              'properties.infosProchainControle.id',
              dossier
            )
          ) {
            controleId = angular.copy(
              dossier.properties.infosProchainControle.id
            );

            extraBtn =
              '<div class="btn btn-xs btn-default openRDVFromListeDossiers" title="Afficher le RDV dans le calendrier" ng-click="actionFromDatatable({fn:\'openCalendarFromControleAnc\',data:{controleId: \'' +
              controleId +
              "', dossierId: '" +
              dossier.id +
              '\'}})">' +
              '<i class="fa fa-calendar"></i>' +
              '</div>';
          }
          let toPrint = '';
          if (
            angular.isDefined(
              dossier.properties.date_prochain_controle_preconise
            ) &&
            dossier.properties.date_prochain_controle_preconise !== null
          ) {
            let toCompare = new Date(
              dossier.properties.date_prochain_controle_preconise
            );

            let ndays = Math.round(
              (toCompare.valueOf() - value.valueOf()) / 1000 / 86400 - 0.5
            );
            if (angular.isDefined(ndays)) {
              value = $filter('date')(value, 'dd/MM/yyyy');
              if (ndays < 0) {
                toPrint = notHtml
                  ? value + ' ' + hour
                  :'<div class="tableTdWrapper"><span'
                  + ' class="spanEtatDossier spanEtatDossierAlert"> <b>'
                  + value
                  + '</b> '
                  + hour
                  + '  </span> '
                  + extraBtn
                  + ' </div>';
              } else {
                if (ndays < 30 && ndays >= 0) {
                  toPrint = notHtml
                    ? value + ' ' + hour
                    :'<div class="tableTdWrapper"><span class="bg-info spanEtatDossier spanEtatDossierWarning"> <b>'
                    + value
                    + '</b> '
                    + hour
                    + '</span>'
                    + extraBtn
                    + '</div>';
                } else {
                  toPrint = notHtml
                    ? value + ' ' + hour
                    : '<div class="tableTdWrapper"><span class="bg-info'
                    + ' spanEtatDossier spanEtatDossierValid"><b>'
                    + value
                    + '</b> '
                    + hour
                    +'</span> '
                    + extraBtn
                    +'</div>';
                }
              }
            }
          } else {
            const dateFiltered =$filter('date')(value, 'dd/MM/yyyy');
            toPrint = notHtml
              ? dateFiltered + ' ' + hour
              : '<div class="tableTdWrapper"><span> <b>'
              + dateFiltered
              + '</b> '
              + hour
              + ' </span> '
              + extraBtn
              + ' </div>';
          }

          value = $sce.trustAsHtml(toPrint);
        }

        return date_prochain_controle != 0 ? value : null;
      };

      const date_dernier_controle = (crudValue, doosier, notHtml) => {
        let value = crudValue;
        if (crudValue) {
          value = $filter('date')(new Date(value), 'dd/MM/yyyy');
          value = notHtml
            ? value
            :$sce.trustAsHtml(
              '<span style="font-size:1em;"><b>' + value + '</b> </span>'
            );
        }
        return (crudValue ? value : '');
      };

      const getListeDeroulanteValues = (appListeDeroulante, attributeName) => {
        const attribute = appListeDeroulante.attributes
          .find((att) => att.name === attributeName);
        if (attribute){
          return (attribute.restrictions[0].listofValues || null);
        }
        return null;
      };

      /**
       * Construit un objet Personne à partir du 1er élément d'un tableau de features
       * @param features tableau de features geojson
       * @return {{nomComplet: string, id, nom, prenom: *, civilite: *}}
       */
      const createPersonFromFirstFeature = (features) => {
        if (Array.isArray(features) && features.length > 0) {
          return {
            nomComplet: features[0].properties.nom + ' ' + features[0].properties.prenom,
            id: features[0].id,
            nom: features[0].properties.nom,
            prenom: features[0].properties.prenom,
            civilite: features[0].properties.civilite,
          };
        } else {
          console.error('createPersonFromFirstFeature - Le tableau de features est null ou vide: '
              + ' features = ', features);
          return {
            nomComplet: '',
            id: '',
            nom: '',
            prenom: '',
            civilite: '',
          };
        }
      };

      return {
        CommonFactory: CommonFactory,
        updateConfigWithCreateCommune: updateConfigWithCreateCommune,
        getAlerteColorClass: getAlerteColorClass,
        tableAlert: tableAlert,
        tableStatus: tableStatus,
        tableAddressNumber: tableAddressNumber,
        affectationConstruction:affectationConstruction,
        lastControlAvis: lastControlAvis,
        controlServiceName: controlServiceName,
        numRueProprietaire: numRueProprietaire,
        villeProprietaire: villeProprietaire,
        paysProprietaire: paysProprietaire,
        rueProprietaire: rueProprietaire,
        cpProprietaire: cpProprietaire,
        typeProprietaire: typeProprietaire,
        volumeFiliere: volumeFiliere,
        date_prochain_controle: date_prochain_controle,
        date_dernier_controle: date_dernier_controle,
        replaceControlName: replaceControlName,
        findControlTypeLabel: findControlTypeLabel,
        getListeDeroulanteValues:getListeDeroulanteValues,
        createPersonFromFirstFeature: createPersonFromFirstFeature
      };
    };

    CommonFactory.$inject = [
    	'$http',
      '$location',
      'ConfigFactory',
      '$q',
      'gaJsUtils',
      '$sce',
      '$filter',
      'FeatureTypeFactory'
    ];
    return CommonFactory;
  }
);
