<template>
  <div class="AppMerchantMap">
    <div class="search">
      <image :src="$cdn + 'xincheng/search.png'" />
      <input placeholder="请输入姓名、店名、电话" v-model="businessName" @confirm="getList">
    </div>
    <div class="map-content">
      <AiTMap :map.sync="map" :lib.sync="lib" :ops="ops" :libraries="['service', 'tools']"/>
    </div>
  </div>
</template>

<script>
  import {mapState} from 'vuex'

  export default {
    name: 'AppMerchantMap',
    appName: '商户地图',
    data() {
      return {
        areaId: '',
        lib: null,
        map: null,
        polygons: [],
        labels: [],
        businessName: '',
        markers: [],
        ops: {},
        markers: [],
        MarkerCluster: null
      }
    },
    computed: {...mapState(['user', 'config'])},

    created () {
      this.areaId = this.user.areaId
      this.getList()
    },

    mounted () {
      this.initMap()
    },

    methods: {
      getList () {
        this.$http.post('/app/appcompany/list', null, {
          params: {
            size: 100000,
            current: 1,
            businessName: this.businessName
          }
        }).then((res) => {
          if (res.code == 0) {
            const markers = res.data.records.filter(item => item.lat).map(item => {
              return {
                title: item.businessName,
                lnglat: [item.lon, item.lat],
                lat: item.lat,
                lng: item.lon,
                id: item.id,
                name: item.businessName
              }
            })

            this.getMarkerCluster(markers)
          }
        })
      },

      getMarkerCluster(points, count = 0) {
        let {lib: TMap, map} = this
        if (map) {
          if (this.markers.length) {
            console.log(this.MarkerCluster)
            // this.MarkerCluster.destroy()
            // this.MarkerCluster = null
            this.markers.forEach(v => {
              v.setMap(null)
            })
          }

          class ClusterBubble extends TMap.DOMOverlay {
            constructor(options) {
              super(options);
            }

            onInit(options) {
              this.content = options.content;
              this.position = options.position;
              this.customClass = options.customClass
            };

            onDestroy() {
              this.dom.removeEventListener('click', this.onClick);
              this.removeAllListeners();
            }

            createDOM() {
              let dom = document.createElement('div');
              dom.classList.add(this.customClass || 'marker');
              dom.innerText = this.content;

              // 监听点击事件，实现zoomOnClick
              this.onClick = this.onClick.bind(this);
              // pc端注册click事件，移动端注册touchend事件
              dom.addEventListener('click', this.onClick);
              dom.addEventListener('touchend', this.onClick);
              return dom;
            };

            updateDOM() {
              if (!this.map) {
                return;
              }
              // 经纬度坐标转容器像素坐标
              let pixel = this.map.projectToContainer(this.position);

              // 使文本框中心点对齐经纬度坐标点
              let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
              let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
              this.dom.style.transform = `translate(${left}, ${top})`;
              this.emit('dom_updated');
            };

            onClick() {
              this.emit('click');
            }
          }

          this.config.latlng && map.setCenter(this.config.latlng)

          this.MarkerCluster = new TMap.MarkerCluster({
            map, gridSize: 60,
            enableDefaultStyle: false, // 关闭默认样式
            geometries: points.map(e => ({
              position: new TMap.LatLng(e.lat, e.lng),
              content: `${e.name}`,
              properties: {...e}
            })) || [],
            zoomOnClick: true
          })
          let cls = []
          this.MarkerCluster.on('cluster_changed', () => {
            if (this.markers.length) {
              this.markers.forEach(function (item) {
                item.destroy();
              })
            }
            cls.forEach(e => e.destroy())
            cls = []
            let clusters = this.MarkerCluster.getClusters()
            clusters.forEach((item) => {
              if (item.geometries?.length > 1) {
                //聚合样式
                let clusterBubble = new ClusterBubble({
                  map,
                  position: item.center,
                  content: item.geometries.length,
                  customClass: 'cluster'
                })
                clusterBubble.on('click', () => {
                  map.fitBounds(item.bounds);
                });
                cls.push(clusterBubble)
              } else {
                //点标记样式
                let {content} = item.geometries?.[0] || {},
                    overlay = new ClusterBubble({map, position: item.center, content})
                overlay.on('click', () => {
                  this.buildPopup = true
                  this.building = item.geometries?.[0]?.properties || {}
                })
                this.markers.push(overlay)
              }
            });
          })
          return Promise.resolve()
        } else {
          if (count < 5) {
            setTimeout(() => {
              return this.getMarkerCluster(points, ++count)
            }, 1000)
          } else Promise.reject("加载失败")
        }
      },

      initMap (retryTimes = 0) {
        this.$nextTick(() => {
          let { map, TMap } = this
          if (map) {
            map.setZoom(15)
          } else {
            if (retryTimes < 10) {
              setTimeout(() => {
                this.initMap(++retryTimes)
              }, 500)
            }
          }
        })
      }
    }
  }
</script>

<style lang="scss" scoped>
  .AppMerchantMap {
    height: 100%;

    ::v-deep.cluster {
      color: #fff;
      border-radius: 50%;
      height: 120px;
      width: 120px;
      background: radial-gradient(circle, #5088ff 50%, rgba(#5088ff, .4) 100%);
      display: flex;
      align-items: center;
      justify-content: center;
    }

    ::v-deep.marker {
      color: #fff;
      background: #558BFE;
      padding: 0 32px;
      width: fit-content;
      height: 56px;
      border-radius: 52px;
      transform: translate(-50%, -50%);
      display: flex;
      align-items: center;

      &:before {
        content: " ";
        display: block;
        position: absolute;
        bottom: 0;
        left: 50%;
        width: 0;
        height: 0;
        transform: translate(-50%, 100%);
        border: 12px solid transparent;
        border-top-color: #558BFE;
      }
    }

    * {
      box-sizing: border-box;
    }

    .search {
      display: flex;
      position: fixed;
      align-items: center;
      top: 24px;
      left: 50%;
      z-index: 11111;
      width: 718px;
      height: 88px;
      padding: 0 16px;
      background: #FFFFFF;
      box-shadow: 0px 4px 8px 0px rgba(192, 185, 185, 0.5);
      border-radius: 16px;
      transform: translateX(-50%);

      image {
        width: 48px;
        height: 48px;
        margin-right: 16px;
      }

      input {
        flex: 1;
        font-size: 28px;
        color: #666666;
      }
    }

    .map-content {
      width: 100%;
      height: 100vh;

      map {
        width: 100%;
        height: 100vh;
      }
    }
  }
</style>
