<template>
  <LayoutContainer>
    <v-responsive :aspect-ratio="1" width="100%">
      <!-- /!\ We do not use the nuxt-leaflet library here,
      because in its current version it's way too slow to deal with hundreds of markers     -->
      <div id="map" />
    </v-responsive>

    <div class="advice">
      {{ $t("click_on_land_to_go_there") }}
    </div>

    <v-row class="map-shortcuts">
      <v-col v-for="shortcut in shortcuts" :key="shortcut.src" cols="2">
        <div @click="setMapBounds(shortcut.bounds)">
          <nuxt-img
            :src="shortcut.src"
            :alt="shortcut.alt"
          />
        </div>
      </v-col>
    </v-row>
  </LayoutContainer>
</template>

<script>
import 'leaflet/dist/leaflet.css'
let L
if (typeof window !== 'undefined') {
  // only require leaflet on client-side
  L = require('leaflet')
}

export default {
  props: {
    structures: {
      type: Array,
      required: false,
      default: () => []
    }
  },
  data () {
    return {
      map: null,
      defaultBounds: [[51.03, -5.78], [41.2, 9.70]],
      shortcuts: [
        { src: '/images/metropole.png', alt: 'Metropole', bounds: [[51.03, -5.78], [41.2, 9.70]] },
        { src: '/images/guadeloupe.png', alt: 'Guadeloupe', bounds: [[16.62, -62.03], [15.74, -60.97]] },
        { src: '/images/martinique.png', alt: 'Martinique', bounds: [[14.95, -61.43], [14.28, -60.60]] },
        { src: '/images/mayotte.png', alt: 'Mayotte', bounds: [[-12.51, 44.86], [-13.19, 45.45]] },
        { src: '/images/la_reunion.png', alt: 'La Réunion', bounds: [[-20.65, 54.92], [-21.65, 56.15]] },
        { src: '/images/guyane.png', alt: 'Guyane', bounds: [[6.24, -54.62], [1.87, -50.59]] }
      ],
      zoomRequired: false
    }
  },
  watch: {
    structures (oldval, newval) {
      if (oldval !== newval) {
        this.populateMarkers()
      }

      if (this.zoomRequired) {
        this._fitBoundsToMarkers()
        this.zoomRequired = false
      }
    }
  },
  mounted () {
    const options = { scrollWheelZoom: false, zoomSnap: 0.25 }
    const defaultCenter = [46.71, 1.94]
    const defaultZoom = 5.75
    const layerSource = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png'
    const attribution = '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'

    this.map = L.map('map', options)
    this.map.setView(defaultCenter, defaultZoom)
    L.tileLayer(layerSource, { attribution }).addTo(this.map)

    this.populateMarkers()

    this.map.on('zoomend moveend', () => {
      this.$emit('boundsUpdated', this.map.getBounds())
    })
  },
  beforeDestroy () {
    if (this.map) {
      this.map.remove()
    }
  },
  methods: {
    populateMarkers () {
      // remove any existant marker layers
      this.map.eachLayer((layer) => {
        if (layer instanceof L.MarkerClusterGroup) {
          this.map.removeLayer(layer)
        }
      })

      // populate new layer
      const clusters = L.markerClusterGroup()
      for (const s of this.structures) {
        if (!s.latitude || !s.longitude) { continue }

        const marker = L.marker([s.latitude, s.longitude])
        marker.bindPopup(`<b>${s.name}</b><br/>${s.postalCode} ${s.addressCity}<br/><a href="${s.website}" target="_blank">${s.website}</a>`)
        clusters.addLayer(marker)
      }
      this.map.addLayer(clusters)
    },
    setMapBounds (bounds) {
      this.map.fitBounds(bounds) // << without this, the new bounds may not be properly set when the current view overlaps the new bounds.
    },
    resetBounds () {
      this.setMapBounds(this.defaultBounds)
    },
    zoomOnResults () {
      this.zoomRequired = true
    },
    _fitBoundsToMarkers () {
      const coords = this.structures.filter(
        (s) => { return s.latitude && s.longitude }
      ).map(
        (s) => { return [s.latitude, s.longitude] })
      if (!coords.length > 0) {
        return
      }
      this.setMapBounds(coords)
    }
  }
}
</script>

<style scoped>
  #map {
    height: 100%;
    width: 100%;
  }
  .advice {
    margin: 1rem 0;
    color: #262626;
    font-weight: 750;
    text-align: center;
    font-size: 0.9rem;
    width: 100%;
  }
  .map-shortcuts .col {
    padding: 12px 6px;
  }
  .map-shortcuts img {
      border: solid 1px #000;
      width: 75px;
      height: 75px;
    }
</style>
