import { Draw } from 'ol/interaction';
import GeometryType from 'ol/geom/GeometryType';
import Modify from 'ol/interaction/Modify';
import Select from 'ol/interaction/Select';
import MultiPoint from 'ol/geom/MultiPoint';
import Point from 'ol/geom/Point';
import {
  Fill, Stroke, Style, Circle, Text //RegularShape, Circle as CircleStyle, Text,Icon
} from 'ol/style';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';
import mapService from '@/services/map-service';
import { buffer } from 'ol/extent';

const editionService = {
  editing_feature: {},
  geom_type: 'linestring',
  drawStyle: new Style({
    fill: new Fill({
      color: 'rgba(255, 255, 255, 0.2)'
    }),
    stroke: new Stroke({
      color: 'rgba(0, 0, 255, 0.5)',
      lineDash: [],
      width: 2
    }),
    image: new Circle({
      radius: 7,
      stroke: new Stroke({
        color: 'rgba(255, 0, 0, 0.5)',
        lineDash: [],
        width: 2
      }),
      fill: new Fill({
        color: 'rgba(255, 255, 255, 0.5)'
      })
    }),
    text: new Text({
      font: '12px Calibri,sans-serif',
      fill: new Fill({ color: '#000' }),
      stroke: new Stroke({
        color: '#fff',
        width: 1
      }),
      text: ''
    }),
    zIndex: 50
  }),

  setEditingFeature(feature) {
    this.editing_feature = feature;
  },

  startEditFeature(feature){
    this.editing_feature=feature;
    this.draw.setActive(false);
    this.drawSource.addFeature(feature);
    this.drawnItems.setZIndex(50);
    mapService.fitExtent(buffer(this.drawSource.getExtent(),200));
  },

  addEditionControls(geomType) {
    this.geom_type=geomType;
    this.drawSource = new VectorSource();
    this.drawnItems = new VectorLayer({
      source: this.drawSource,
      style: this.drawStyle,
      zIndex: 4000
    });
    window.olMap = mapService.getMap();
    mapService.getMap().addLayer(this.drawnItems);
    if (this.draw) {
      mapService.getMap().removeInteraction(this.draw);
    }
    let gType = GeometryType.POINT;
    if (geomType.toUpperCase().indexOf('POLYGON') >= 0) {
      gType = GeometryType.POLYGON;
    }
    else if (geomType.toUpperCase().indexOf('LINE') >= 0) {
      gType = GeometryType.LINE_STRING;
    }
    this.draw = new Draw({
      source: this.drawSource,
      type: gType,
      style: this.drawStyle,
      //geometryName: layer.getGeomAttributeName()
    });
    mapService.getMap().addInteraction(this.draw);
    this.setEditingFeature(undefined);

    this.draw.on('drawend', (evt) => {
      var feature = evt.feature;
      console.log(feature);
      this.setEditingFeature(feature);
      this.draw.setActive(false);
    });

    this.selectForUpdate = new Select({
      style: [
        this.drawStyle,
        new Style({
          image: new Circle({
            radius: 5,
            fill: new Fill({
              color: 'orange',
            }),
          }),
          geometry: function (feature) {
            // return the coordinates of the first ring of the polygon
            const coordinates = feature.getGeometry().getCoordinates()[0];
            if (feature.getGeometry() instanceof Point){
              return feature.getGeometry();
            }
            return new MultiPoint(coordinates);
          },
        })
      ]
    });
    this.modify = new Modify({
      style: this.drawStyle,
      features: this.selectForUpdate.getFeatures()
    });

    // je garde ce bout de code pour l'implementation a venir du snapping
    //snapping
    // var snap = new Snap({
    //  source: this.drawSource
    //});

    // This workaround allows to avoid the ol freeze
    // referenced bug : https://github.com/openlayers/openlayers/issues/6310
    // May be corrected in a future version
    this.modify.handleUpEvent_old = this.modify.handleUpEvent;
    this.modify.handleUpEvent = function (evt) {
      try { 
        this.handleUpEvent_old(evt);
      } catch (ex) { 
        console.log(ex); 
      }
    };

    mapService.getMap().addInteraction(this.selectForUpdate);
    mapService.getMap().addInteraction(this.modify);
    // je garde ce bout de code pour l'implementation a venir du snapping
    //map.addInteraction(snap);


  },
  resetAllTools() {
    if (this.draw) {
      this.draw.setActive(false);
    }

    if (this.selectForDeletion) {
      this.removeSelectInteraction(this.selectForDeletion);

    }
    if (this.selectForUpdate) {
      this.removeSelectInteraction(this.selectForUpdate);
    }
    if (this.modify) {
      this.modify.setActive(false);
    }
  },
  removeSelectInteraction(interaction) {
    interaction.getFeatures().clear();
    interaction.setActive(false);
  },
  activeUpdateFeature() {
    this.resetAllTools();
    this.modify.setActive(true);
    this.selectForUpdate.setActive(true);
    this.selectForUpdate.getFeatures().push(this.editing_feature);

  },
  activeDeleteFeature() {
    this.resetAllTools();
    if (!this.selectForDeletion) {
      var style = new Style({
        fill: new Fill({
          color: 'rgba(255, 0, 0, 0.2)'
        }),
        stroke: new Stroke({
          color: 'rgba(255, 0, 0, 0.5)',
          width: 2
        }),
        image: new Circle({
          radius: 7,
          fill: new Fill({
            color: 'rgba(255, 0, 0, 0.5)'
          })
        }),
        text: new Text({
          font: '12px Calibri,sans-serif',
          fill: new Fill({ color: 'rgba(255, 0, 0, 0.5)' }),
        }),
        zIndex: 50
      });
      this.selectForDeletion = new Select({ style: style });
      mapService.getMap().addInteraction(this.selectForDeletion);
      // Lorsque de nouvelles features sont sélectionnées
      let selected_features = this.selectForDeletion.getFeatures();
      this.listenerKey = selected_features.on('add', (evt) => {
        var feature = evt.element;
        if (feature) {
          setTimeout(() => {
            if (confirm('Etes-vous sur de vouloir supprimer cet objet ?')) {
              // supprimer l'edition de la sélection
              this.selectForDeletion.getFeatures().clear();
              // supprimer l'edition de la carte
              this.drawSource.removeFeature(feature);
              this.editing_feature = undefined;
              this.draw.setActive(true);
              this.selectForDeletion.setActive(false);
            }
          }, 300);
        }
      });
    } else {
      this.selectForDeletion.setActive(true);
    }
  },

};


export default editionService;