<template>
  <div id="MapContainer" :style="`width:${width}`" />
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
import point2 from '@/assets/images/point2.png'
import store from '@/store'
declare const JMap: 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,
    },
    width: {
      type: String as PropType<string>,
      default: '67vw',
    },
  },
  emits: ['complete', 'event'],
  setup(props, ctx) {
    let map: any = null
    function initMap(config?: any) {
      map = new JMap()
      ;(window as any).jMap = map
      map.createMap(
        'MapContainer',
        '6b446c2db7094389aef2acb11e9cd27b',
        window.location.origin,
        {
          area: '12',
          base_layer_name: 'blue',
          model_data_name: '',
          showGov: false, // 显示区政府标志
          camera: {
            x: 121.4772444529965,
            y: 31.216214566384625,
            radius: 3200.0,
            offset: { heading: -10.11789142234001, pitch: -90, range: 0 },
          },
          ...config,
          ...props.config,
          map_complete_callback: function () {
            ctx.emit('complete', map)
            // addListener()
            // hideCommunity()
            map.queryDistrict('南京东路街道')
            // map.switchBuildingModel('BM_G_JianLan,BM_D_JianLan')
            map.switchBuildingModel('tietu')
          },
        }
      )
      // map = new SMap.Map('MapContainer', {
      //   viewMode: '3D',
      //   center: [1019.614669, 54.167243],
      //   // center: [-135.98002789627407, -722.1597065437004],
      //   zooms: [6, 20],
      //   zoom: 8,
      //   pitch: 45,
      //   mapStyle: 'smap://styles/dark',
      //   showBuildingBlock: true,
      //   ...config,
      //   ...props.config,
      // }).on(SMap.MapEvent.maploaded, () => {
      //   // setBuildingBlock()
      //   ctx.emit('complete', map)
      //   addListener()
      //   hideCommunity()
      // })
    }
    // function setMouseEvent(val: boolean) {
    //   map.enableMouseEvent(val)
    // }
    function layer(name: string) {
      return map.getLayer(name)
    }
    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} = '${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([x, y])
    //     // console.log(map.getZoom(), map.getCenter())
    //     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,
      options = undefined
    ) {
      if (!map || !x || !y) {
        console.error('传入的坐标点不能为空')
        return
      }
      map.goTo(
        {
          x: +x,
          y: +y,
          radius: +zoom * 100,
        },
        options
      )
    }

    function zoom(type: string) {
      if (!map) return
      if (type === 'in') map.zoomIn()
      else map.zoomOut()
    }

    // 添加边界
    function addBoundary({
      name = '',
      type = 'jd_boundary',
      weight = 10,
      count = 10,
      color = 'rgba(51,145,255,.6)',
      maskColor = [0, 17, 33, 0.9],
    }) {
      // const boundary = {
      //   boundaryType: type,
      //   boundaryDefinition: `name like '%${name}%'`,
      //   boundarydistance: weight,
      //   bounarycount: count,
      //   boundaryColor: color,
      //   maskColor: maskColor,
      // }
      // console.log('=====', boundary)
      // const Boundary = new Plugins.MaskBoundary(map.view)
      // Boundary.add(boundary)
      // return Boundary
      // const region = {
      //   id: key,
      //   attributes,
      //   position: paths.map((item: any) => ({ x: item[0], y: item[1], z: 0 })),
      // }
      // map.Locate.regionLocate(region, {
      //   isZoom: false,
      //   style: {
      //     color: bgColor,
      //     outlineColor: strokeColor,
      //     transparency: 0.6,
      //   },
      // })
      // return key
    }

    function rotate(
      location = [121.4642191813353, 31.229242441205542],
      deg: number,
      type = '3D'
    ) {
      map.goTo(
        {
          x: location[0],
          y: location[1],
          radius: 100,
        },
        {
          duration: 2.0,
          offset: { heading: deg, pitch: type === '2D' ? -90 : -35, range: 0 },
        }
      )
    }
    // function cameraTo({
    //   center = [0, 0],
    //   heading = 180,
    //   tilt = 45,
    // }: {
    //   center: number[]
    //   heading: number
    //   tilt: number
    // }) {
    //   // map.setPitch(60)
    //   // map.setCenter(0, 0, 0)
    //   // map.setRotation(180)

    //   map.view.goTo({
    //     // center,
    //     heading,
    //     tilt,
    //   })
    // }
    // 将数据转换为符合地图的点数组
    function getMapPoints({
      data = [],
      key,
      labelKey,
      icon,
      size,
      color = '#47B3FF',
    }: PointProp) {
      return data.map((item: any, i) => {
        let sizeProp = Array.isArray(size) ? size : [size, size]
        if (item.size) {
          sizeProp = Array.isArray(item.size)
            ? item.size
            : [item.size, item.size]
        }
        const result: any = {
          id: `${key}-${i + 1}`,
          position: {
            x:
              +item.x ||
              +item.communityMinx ||
              +item.X ||
              +item.cx ||
              +item.gpsx,
            y:
              +item.y ||
              +item.communityMiny ||
              +item.Y ||
              +item.cy ||
              +item.gpsy,
            z:
              +item.z ||
              +item.communityMinz ||
              +item.Z ||
              +item.cz ||
              +item.gpsz ||
              0.1,
          },
          attributes: { key, ...item },
        }
        if (item.icon || icon) {
          result.image = {
            url: item.icon || icon,
            width: sizeProp[0],
            height: sizeProp[1],
            pixelOffset: [0, -20],
          }
        } else {
          result.image = {
            show: false,
          }
        }
        if (labelKey) {
          result.label = {
            show: true,
            text: labelKey ? (item[labelKey] || item[key]) + '' : '',
            font: '1rem',
            color,
            pixelOffset: [0, -70],
          }
        }
        return result
      })
    }
    // 添加点
    function addPoint({
      key,
      data = [],
      labelKey = '',
      icon = '',
      size = 14,
      color = '#47B3FF',
    }: PointProp) {
      if (!map) return
      const points = getMapPoints({ data, key, labelKey, icon, size, color })
      map.Locate.pointLocate(points, {
        isZoom: false,
        click: (res: any) => {
          if (res?._attributes) {
            ctx.emit('event', res._attributes)
          }
        },
      })
      return points.map((item) => item.id)
    }

    // 添加旗标
    function addFlag({ id, x, y, z = 0, name, style, sectId }: any) {
      const target = {
        id,
        position: { x, y, z },
        element: `
        <div class='ysc-dynamic-layer ys-css3-box _building-btn' data-id="${sectId}" style="pointer-events:auto;">
          <div class='biaozhu' style="cursor:pointer;${style || ''}">
          ${name}
          </div>
        </div>
        `,
      }
      map.FlagInfo.show(target, { isZoom: true })
      return id
    }
    function hideFlag(ids?: string[]) {
      map.FlagInfo.hide(ids)
    }

    // 删除点
    function remove(points?: string[]) {
      if (!map) return
      points && map.Locate.clearLocate(points)
    }

    // 添加线状覆盖物
    function addPolyLine({
      key,
      paths = [],
      attributes = {},
      strokeColor = 'rgba(51,145,255,.6)',
      width = 2,
    }: {
      key: string
      paths: any[]
      attributes: any
      strokeColor: string
      width: number
    }) {
      if (!map) return
      const polyline = {
        id: key,
        attributes,
        position: paths.map((item: any) => ({
          x: item[0],
          y: item[1],
          z: 0.1,
        })),
      }
      map.Locate.trackLocate(polyline, {
        isZoom: false,
        style: {
          width: width,
          color: strokeColor,
        },
      })
      return key
    }

    return {
      initMap,
      focus,
      zoom,
      // setMouseEvent,
      layer,
      setBuildingBlock,
      hideCommunity,
      showCommunity,
      addBoundary,
      rotate,
      // cameraTo,
      addPoint,
      addPolyLine,
      remove,
      setFilter,
      addFlag,
      hideFlag,
    }
  },
})
</script>

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