<template>
  <section class="AiTMap">
    <div ref="tmap" class="map"/>
  </section>
</template>

<script>
  export default {
    name: 'AiQMap',
    props: {
      areaId: String,
      ops: {
        default: () => {
          return {}
        }
      },
      libraries: {
        default: () => ['service']
      },
      markerIcon: {
        type: String
      },
      is3dAround: {
        type: Boolean,
        default: false
      },
      is3d: {
        type: Boolean,
        default: false
      },
      limitArea: {
        type: Boolean,
        default: false
      },
      map: Object,
      lib: Object,
      markers: {
        type: Array,
        default: () => []
      }
    },

    watch: {
      markers: {
        handler (v) {
          if (window.TMap && v.length) {
            this.addMarkers(v)
          }
        },
        deep: true,
        immediate: true
      }
    },

    data () {
      return {
        tmap: null,
        mapLib: null,
        marker: null,
        keyframe: [
          {
            percentage: 0,
            rotation: 0
          },
          {
            percentage: 0.2,
            rotation: 72
          },
          {
            percentage: 0.4,
            rotation: 144
          },
          {
            percentage: 0.6,
            rotation: 216
          },
          {
            percentage: 0.8,
            rotation: 288
          },
          {
            percentage: 1,
            rotation: 360
          }
        ]
      }
    },

    computed: {
      key () {
        return process.env.NODE_ENV == 'production' ? 'RWWBZ-64BEJ-MVLFJ-FTHLQ-JTR6J-SAB2S' : '3RZBZ-LZUCF-CT6J5-NWKZH-FCWOQ-UUFKY'
      }
    },

    mounted () {
      if (!window.TMap) {
        window.initTMap = this.initTMap
        this.injectLib(`https://map.qq.com/api/gljs?v=1.exp&key=${this.key}&libraries=${this.libraries.toString()}&callback=initTMap`)
      } else {
        this.initTMap()
      }
    },

    methods: {
      injectLib (url, cb) {
        const script = document.createElement('script')
        script.type = 'text/javascript'
        script.id = 'aiqmap'
        script.src = url
        script.addEventListener('load', () => {
          cb && cb()
        })
        document.body.appendChild(script)
      },

      setMarkersCenter () {
        var bounds = new TMap.LatLngBounds()
        this.markers.forEach(item => {
          if (bounds.isEmpty() || !bounds.contains(new TMap.LatLng(item.lat, item.lng))) {
            bounds.extend(new TMap.LatLng(item.lat, item.lng))
          }
        })

        this.tmap.fitBounds(bounds, {
          padding: 100
        })
      },

      addMarkers (v) {
        if (this.marker) {
          this.marker.setMap(null)
        }

        this.marker = new TMap.MultiMarker({
          id: 'markers',
          map: this.tmap,
          styles: {
            marker: new TMap.MarkerStyle({
              width: 25,
              height: 35,
              color: '#333',
              size: 16,
              offset: { x: 0, y: 8 },
              anchor: { x: 17, y: 23 },
              direction: 'bottom',
              strokeWidth: 2,
              src: this.markerIcon
            })
          },
          geometries: v.map(v => {
            return {
              ...v,
              styleId: 'marker',
              position: new TMap.LatLng(v.lat, v.lng)
            }
          })
        })

        this.setMarkersCenter()
        this.marker.on('click', e => {
          this.$emit('markerClick', e.geometry)
        })
      },

      initTMap () {
        this.mapLib = TMap
        this.tmap = new TMap.Map(this.$refs.tmap, {
          zoom: 11,
          ...this.ops,
          viewMode: this.is3d ? '3d' : '2d',
          pitch: this.is3d ? 40 : 0,
          // mapStyleId: 'style1',
          baseMap: this.limitArea ? [
            { type: 'vector', features: ['base'] },
            {
              type: 'traffic',
              opacity: 1,
            }
          ] : [
            { type: 'vector' },
          ],
          renderOptions: {
            enableBloom: true, // 是否启用泛光效果 注：为true才会有效果
          }
        })

        this.tmap.on('click', e => {
          this.$emit('click', e)
        })

        if (this.markers.length) {
          this.addMarkers(this.markers)
        }
        this.$emit('loaded')
        this.$emit('update:lib', TMap)
        this.$emit('update:map', this.tmap)
        this.areaId && this.getMapArea()
      },

      getMapArea () {
        let {mapLib, areaId, tmap: map} = this, keyword = areaId.substring(0, 6)
        const fitBounds = latLngList => {
          if (latLngList.length === 0) {
            return null
          }
          let boundsN = latLngList[0].getLat()
          let boundsS = boundsN
          let boundsW = latLngList[0].getLng()
          let boundsE = boundsW
          latLngList.forEach((point) => {
            point.getLat() > boundsN && (boundsN = point.getLat())
            point.getLat() < boundsS && (boundsS = point.getLat())
            point.getLng() > boundsE && (boundsE = point.getLng())
            point.getLng() < boundsW && (boundsW = point.getLng())
          })
          return new TMap.LatLngBounds(
            new TMap.LatLng(boundsS, boundsW),
            new TMap.LatLng(boundsN, boundsE)
          )
        }

        if (!this.limitArea) return
        let polygons = new TMap.MultiPolygon({map, geometries: []})
        new mapLib.service.District({
          polygon: 2,
          maxOffset: 100
        }).search({keyword}).then(res => {
          if (res?.result) {
            console.log(res.result[0][0].polygon)
            let center = res.result[0][0].location
            this.tmap.enableAreaHighlight({
              paths: res.result[0][0].polygon,
              highlightColor: 'rgba(0,0,0,0)',
              shadeColor: 'rgba(0,0,0,1)'
            })
            this.tmap.setCenter(center)
            new TMap.MultiPolyline({
              map: this.tmap,
              styles: {
                polyline: new TMap.PolylineStyle({
                  color: '#017cf7', // 线条填充色，
                  width: 8,
                  lineCap: 'round',
                  enableBloom: true, // 是否启用泛光  注：为true才会有效果
                }),
              },
              geometries: [
                {
                  styleId: 'polyline', // 样式id
                  paths: res.result[0][0].polygon
                }
              ]
            })

            res.result.forEach((level) => {
              level.forEach((place) => {
                let bounds = []
                let newGeometries = place.polygon.map((polygon, index) => {
                  bounds.push(fitBounds(polygon))
                  return {
                    id: `${place.id}_${index}`,
                    paths: polygon
                  }
                })
                bounds = bounds.reduce((a, b) => {
                  return fitBounds([
                    a.getNorthEast(),
                    a.getSouthWest(),
                    b.getNorthEast(),
                    b.getSouthWest()
                  ])
                })
                // polygons.updateGeometries(newGeometries)
                this.tmap.fitBounds(bounds)
              })
            })

            setTimeout(() => {
              this.is3dAround && this.tmap.startAnimation(this.keyframe, {
                duration: 16000,
                loop: Infinity
              })
            }, 600)
          }
        })
      }
    },

    destroyed () {
      this.tmap.destroy()
    }
  }
</script>

<style lang="scss" scoped>
  .AiTMap {
    width: 100%;
    height: 100%;
    flex: 1;
    min-width: 0;
    min-height: 0;

    ::v-deep.map {
      height: 100%;

      & > div > div {
        &:nth-of-type(2), &:nth-of-type(3) {
          display: none;
        }
      }
    }
  }
</style>
