<template src="./Gmap.html"></template>

<script>
import GmapMixin from '../mixins/GmapMixin'

export default {
  mixins: [GmapMixin],
  props: {
    locationField: {type: String, default: 'location'},
    idField: {type: String, default: 'id'},
    iconField: {type: String},
    field: {type: String, default: 'location'},
    items: {type: Array},
    editable: { type: Boolean, default: false },
  },
  watch: {
    items: {
      deep: true,
      handler () {
        let created = [], changed = [], deleted = [], unchanged = []
        let newIds = [], id = ''
        this.items.forEach((item, index) => {
          id = item[this.idField].toString()
          if (!this.markers[id]) this.addMarker(item, index)
          else if (JSON.stringify(this.markers[id].data) !== JSON.stringify(item)) this.updateMarker(item[this.idField], item)
          newIds.push(id)
        })
        Object.keys(this.markers)
          .filter((prevKey) => newIds.indexOf(prevKey) === -1)
          .forEach((prevKey) => this.markers[prevKey].setMap(null))
      }
    },
    editable () {
      Object.keys(this.markers).map(k => this.markers[k].setDraggable(this.editable))
    }
  },
  created () {
    this.markers = {}
  },
  async mounted () {
    await this.$initializeMap()
    this.drawMarkers()
  },
  methods: {
    clearMarkers () {
      Object.keys(this.markers).map(k => this.markers[k].setMap(null))
      this.markers = {}
    },
    updateMarker (id, data) {
      this.markers[id.toString()].data = {...data}
      this.markers[id.toString()].setPosition(new window.google.maps.LatLng(data[this.locationField][1], data[this.locationField][0]))
      if (this.iconField) {
        this.markers[id.toString()].setIcon({
          url: data[this.iconField],
          scaledSize: new window.google.maps.Size(50, 50),
          anchor: new window.google.maps.Point(25, 60)
        })
      }
    },
    deleteMarker (id) {
      this.markers[id.toString()].setMap(null)
    },
    addMarker (data, index = Object.keys(this.markers).length) {
      let marker = new window.google.maps.Marker({
        icon: this.iconField && data[this.iconField] && {
          url: data[this.iconField],
          scaledSize: new window.google.maps.Size(50, 50),
          anchor: new window.google.maps.Point(25, 60)
        },
        position: new window.google.maps.LatLng(data[this.locationField][1], data[this.locationField][0]),
        map: this.map,
        data: {...data},
        draggable: this.editable
      })
      this.markers[data[this.idField].toString()] = marker
      marker.addListener('click', () => {
        this.$emit('marker-click', marker, data)
      })
      if (this.editable) {
        ((mk, i, cb) => {
          window.google.maps.event.addListener(mk, 'dragend', () => {
            this.positionChanged(i, [ mk.position.lng(), mk.position.lat() ], marker.data[this.idField])
          })
        })(marker, index)
      }
    },
    drawMarkers () {
      this.prevValues = [...this.items]
      if (!this.items || !this.items.length) return
      this.items.forEach((item, index) => {
        this.addMarker(item, index)
      })
    },
    positionChanged (index, position, id) {
      this.$emit('marker-update', index, position, id)
    }
  }
}

</script>

