<template>
  <div class="main_container">
    <div id="track" ref="map" />
    <div id="pointOverlay" class="point_overlay">
      <over-lay :data="problemData" :show-result="showResult" :type="positionType" @close="closeOverlay" />
    </div>

    <ul v-if="showLegend" class="legend_list">
      <li v-for="(item, index) in legendList" :key="index" class="legend_item">
        <div class="legend_point" :style="{background: item.color}" />
        <span class="legend_name">{{ item.name }}</span>
      </li>
    </ul>
  </div>
</template>
<script>
import { reactive, toRefs, onMounted, watch, ref } from 'vue'
import { styleList, legendList } from './util.js'
import { Map, View, Feature, Overlay } from 'ol'
import 'ol/ol.css'
import { Tile, Vector as VectorLayer } from 'ol/layer'
import LineString from 'ol/geom/LineString'
import { XYZ, Vector as VectorSource } from 'ol/source'
import { transform, fromLonLat } from 'ol/proj'
import * as control from 'ol/control'
import { Select } from 'ol/interaction'
import Point from 'ol/geom/Point'

import OverLay from './OverLay.vue'

export default {
  name: 'PositionMsg',
  components: { OverLay },
  props: {
    data: {
      type: Array,
      default: () => {}
    },
    type: {
      type: String,
      default: 'look'
    },
    showLegend: {
      type: Boolean,
      default: true
    },
    showResult: {
      type: Boolean,
      default: false
    }
  },
  emits: {},
  setup(props, { emit }) {
    const data = reactive({
      problemList: props.data, // 问题矢量点列表
      problemData: {}, // 问题点数据
      positionType: props.type, // 组件展示类型  look 纯展示， handle 带操作
      legendList: legendList
    })

    const mapdata = ref(null)
    const select = ref(null)
    const problemLayer = ref(null)
    const overlay = ref(null)
    const view = ref(null)

    /**
     * 初始化底图
     */
    const initMap = function() {
      const layers = [
        new Tile({
          visible: true,
          source: new XYZ({
            url: 'https://tianditu.t-aaron.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f82bb2fd8115c7fb576a8b2fcf738523'
          })
        })
      ]

      view.value = new View({
        maxZoom: 18,
        zoom: 4,
        center: transform([108.94043, 31.008173], 'EPSG:4326', 'EPSG:3857')
      })
      mapdata.value = new Map({
        layers: layers,
        target: 'track',
        view: view.value,
        controls: control.defaults({
          attribution: false,
          rotate: false,
          zoom: false
        })
      })
      mapdata.value.render()
      // 添加select并设置选中样式
      select.value = new Select({
        style: (feature) => {
          if (feature.getGeometry() instanceof Point) {
            return styleList[0]
          }
        }
      })
      mapdata.value.addInteraction(select.value)
      // 新建overlay弹出框
      overlay.value = new Overlay({
        element: document.getElementById('pointOverlay'),
        autoPan: true
      })
    }

    onMounted(() => {
      initMap()
      getLayer(props.data, view.value, mapdata.value)
    })

    /**
     * 加载矢量图层
     */
    const getLayer = function(data) {
      const pointFeatures = []
      const points = []
      if (data.length) {
        data.forEach((item) => {
          const pointItem = []
          pointItem.push(parseFloat(item.lng))
          pointItem.push(parseFloat(item.lat))
          const featureItem = new Feature(new Point(fromLonLat(pointItem)))
          points.push(fromLonLat(pointItem))
          featureItem.setProperties({ item: item, type: 'problem' }, false)
          featureItem.setStyle(styleList[item.status])
          pointFeatures.push(featureItem)
        })
        const pointSource = new VectorSource({
          wrapX: false,
          features: pointFeatures
        })
        problemLayer.value = new VectorLayer({
          source: pointSource,
          zIndex: 12
        })
        let geom
        if (points.length > 1) {
          geom = new LineString(points)
        } else if (points.length > 0) {
          geom = new Point(points[0])
        }
        if (geom) {
          view.value.fit(geom, { padding: [150, 200, 150, 200] })
        }
        mapdata.value.addLayer(problemLayer.value)
      }
    }

    /**
     * 删除矢量图层
     */
    const removeVector = function(layer) {
      layer.getSource().clear()
      mapdata.value.removeLayer(layer)
      problemLayer.value = null
    }
    /**
     * 选择矢量点数据
     */
    const setOverlay = function() {
      select.value.on('select', (e) => {
        if (e.selected.length > 0) {
          const properties = e.selected[0].getProperties()
          const geom = properties.geometry
          if (geom instanceof Point) {
            data.problemData = properties.item
            const coordinate = e.mapBrowserEvent.coordinate
            overlay.value.setPosition(coordinate)
            overlay.value.setOffset([30, -400])
            mapdata.value.addOverlay(overlay.value)
          } else {
            closeOverlay()
          }
        } else {
          closeOverlay()
        }
      })
    }

    watch(
      () => select.value,
      (value) => {
        setOverlay(mapdata.value, overlay.value)
      }
    )
    watch(() => props.data, (value) => {
      if (value) {
        if (mapdata.value) {
          if (problemLayer.value) {
            removeVector(problemLayer.value)
          }
          getLayer(props.data)
        }
      }
    })

    /**
     * 关闭overlay
     */
    const closeOverlay = () => {
      data.problemData = {}
      select.value.getFeatures().clear()
      mapdata.value.removeOverlay(overlay.value)
    }

    return {
      ...toRefs(data),
      removeVector,
      closeOverlay

    }
  }
}
</script>
<style scoped>
.main_container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}
#track {
  width: 100%;
  height: 100%;
}
.point_overlay {
  width: 400px;
}
.legend_list {
  width: 172px;
  height: 173px;
  padding: 10px 20px;
  background: rgba(31, 31, 31, 0.5);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: flex-start;
  position: absolute;
  bottom: 0;
  right: 0;
}
.legend_item {
  width: 100%;
  display: flex;
  justify-content: flex-start;
  align-items: center;
}
.legend_point {
  width: 24px;
  height: 24px;
  margin-right: 24px;
  border-radius: 50%;
  border: 1px solid #fff;
}
.legend_name {
  font-size: 16px;
  color: #fff;
}
</style>
