<template>
  <div id="MapContainer" />
</template>

<script lang="ts">
import { defineComponent, nextTick, onMounted, PropType } from 'vue'
declare const SMap: any
declare const Plugins: any

interface PointProp {
  data: unknown[]
  key: string
  labelKey?: string
  icon?: string
  size?: number | number[]
  color?: string
}

export default defineComponent({
  name: 'MyMap',
  displayName: 'm-map',
  props: {
    config: {
      type: Object as PropType<{ [key: string]: unknown }>,
      default: null,
    },
  },
  emits: ['complete', 'event'],
  setup(props, ctx) {
    let map: any = null
    onMounted(async () => {
      await nextTick()
      initMap()
    })
    function initMap() {
      map = new SMap.Map('MapContainer', {
        viewMode: '3D',
        center: [1141.75319496382872, -480.0854532701907],
        zooms: [5, 10],
        zoom: 7,
        pitch: 45,
        mapStyle: 'smap://styles/dark',
        showBuildingBlock: true,
        ...props.config,
      }).on(SMap.MapEvent.maploaded, () => {
        // map.enableMouseEvent(false)
        setBuildingBlock()
        ctx.emit('complete', map)
        addListener()
        // hideCommunity()
      })
    }
    function setBuildingBlock(val = false) {
      map.getLayer('model_white_zw').visible = val // 整个街道图层名
      map.getLayer('model_white_zhenxing2').visible = val // 振兴小区名
      map.getLayer('model_white_WEIHAI33').visible = val // 威海小区名
      map.getLayer('model_white_dyjd').visible = val // 第一街道名
    }
    function hideCommunity() {
      map.hideXQ_Poly()
      map.hideMPZ()
      map.hideXQ_Point()
    }
    function showCommunity() {
      map.showXQ_Poly()
      map.showMPZ()
      map.showXQ_Point()
    }
    function setFilter(arr: unknown[], key = 'sect_id') {
      if (arr.length === 0) return
      const valid = arr.map((val) => {
        return `${key} like '${val}'`
      })
      map.setFilter('wg_gis_xq_point', valid.join(' or '))
      map.setFilter('wg_gis_mpz', valid.join(' or '))
      map.setFilter('wg_gis_xq_poly', valid.join(' or '))
    }
    function addListener() {
      // 触发地图点击事件
      map.on(SMap.MapEvent.click, (view: any, eventParamter: any) => {
        const { x, y } = eventParamter.mapPoint
        console.log(map.getZoom())
        console.log([x, y])
        view.hitTest(eventParamter).then((res: any) => {
          if (res.results && res.results.length > 0) {
            ctx.emit(
              'event',
              res.results[0] && res.results[0].graphic.attributes
            )
          }
        })
      })
    }
    /**
     * ------  聚焦点位 -------
     * @param {String} x [必填 - x坐标]
     * @param {String} y [必填 - y坐标]
     * @param {Number} zoom [可选 - 放大比例（默认为6）]
     */
    function focus(x: string | number, y: string | number, zoom = 6) {
      if (!map || !x || !y) {
        console.error('传入的坐标点不能为空')
        return
      }
      map.setZoomAndCenter(zoom, [+x, +y, 0])
    }

    // 添加边界
    function addBoundary({
      name = '',
      weight = 10,
      count = 10,
      color = 'rgba(51,145,255,.6)',
      maskColor = [0, 17, 33, 0.9],
    }) {
      const boundary = {
        boundaryType: 'jd_boundary',
        boundaryDefinition: `name like '%${name}%'`,
        boundarydistance: weight,
        bounarycount: count,
        boundaryColor: color,
        maskColor: maskColor,
      }
      const Boundary = new Plugins.MaskBoundary(map.view)
      Boundary.add(boundary)
      return Boundary
    }

    function rotate(deg: number) {
      map.setRotation(deg)
    }
    // 将数据转换为符合地图的点数组
    function getMapPoints({
      data = [],
      key,
      labelKey,
      icon,
      size,
      color = '#47B3FF',
    }: PointProp) {
      return data.map((item: any) => {
        let sizeProp = Array.isArray(size)
          ? new SMap.Size(size[0], size[1])
          : new SMap.Size(size, size)
        if (item.size) {
          sizeProp = Array.isArray(item.size)
            ? new SMap.Size(item.size[0], item.size[1])
            : new SMap.Size(item.size, item.size)
        }
        const result = {
          icon: new SMap.Icon({
            size: sizeProp,
            image: item.icon || icon,
          }),
          attributes: { key, ...item },
          position: [
            item.communityMinx || item.X || item.x || item.gpsx,
            item.communityMiny || item.Y || item.y || item.gpsy,
            item.communityMinz || item.Z || item.z || item.gpsz || 0,
          ],
          label: null,
        }
        if (labelKey) {
          result.label = new SMap.Label({
            text: (item[labelKey] || item[key]) + '',
            size,
            color,
          })
        }
        return new SMap.Marker(result)
      })
    }
    // 添加点
    function addPoint({
      key,
      data = [],
      labelKey = '',
      icon = 'test.png',
      size = 14,
      color = '#47B3FF',
    }: PointProp) {
      if (!map) return
      const points = getMapPoints({ data, key, labelKey, icon, size, color })
      map.add(points)
      return points
    }

    // 删除点
    function remove(points: any) {
      if (!map || !points) return
      map.remove(points)
    }

    return {
      focus,
      setBuildingBlock,
      hideCommunity,
      showCommunity,
      addBoundary,
      rotate,
      addPoint,
      remove,
      setFilter,
    }
  },
})
</script>

<style lang="stylus" scoped>
#MapContainer
  position fixed
  width 100%
  height 100vh
  top 0
  left 0
</style>
<style lang="stylus">
.esri-component.esri-attribution.esri-widget
  display none
</style>
