<template>
  <div ref="mapPopupRef" class="facility-info-popover">
    <h2>{{ popupTitle }} Info</h2>
    <a-spin :spinning="isGettingInfo">
      <div class="facility-info-item" v-for="(item, index) in columns" :key="index">
        <div class="facility-info-item-label">{{ item.label }}</div>
        <div class="facility-info-item-content">{{ currStationInfo[item.key] || '--' }}</div>
      </div>
    </a-spin>
  </div>
</template>
<script>
import Overlay from 'ol/Overlay'

import { MarkerIcon } from './markerEnum'
import { fromLonLat } from 'ol/proj'

import PopupColumns from './markerPopupColumns'
import { getAction } from '../../../api/manage'
import { debounce } from 'lodash'
import { decimalToDms } from '@/utils/map'

const POPUP_OVERLAY_ID = 'map_popup'

export default {
  props: {
    list: {
      type: Array,
      required: true
    }
  },
  data() {
    return {
      currStationInfo: {},
      isGettingInfo: false,
      columns: {},
      popupTitle: ''
    }
  },
  mounted() {
    this.map = this.$parent.getMapInstance()
    this.getStationInfo = debounce(stationInfo => {
      // 查询设施详情时去抖动
      if (this.isHover) {
        this._getStationInfo(stationInfo)
      }
    }, 500)
  },
  methods: {
    // 初始化marker
    initMarkers() {
      this.list.forEach(eventItem => {
        this.map.addOverlay(this.getMarker(eventItem))
      })
    },

    // 获取marker图标
    getMarker(stationInfo) {
      const { lon, lat } = stationInfo

      const img = document.createElement('img')
      img.src = MarkerIcon[stationInfo.stationType]
      img.addEventListener('click', () => {
        this.$emit('markerClick')
      })

      img.addEventListener('mouseover', () => {
        this.isHover = true
        this.showMapPopup(stationInfo)
      })

      img.addEventListener('mouseout', () => {
        this.isHover = false
        this.closeMapPopup()
      })

      return new Overlay({
        position: fromLonLat([lon, lat]),
        element: img,
        id: stationInfo.stationId,
        positioning: 'center-center'
      })
    },

    initRipples() {
      this.list.forEach(eventItem => {
        this.map.addOverlay(this.getRipple(eventItem))
      })
    },

    getRipple({ lon, lat, stationId }) {
      const rippleDiv = document.createElement('div')
      rippleDiv.className = 'custom-ripple'

      rippleDiv.innerHTML = ` <div class="inner-ripple-1"></div>
                              <div class="inner-ripple-2"></div>
                            `

      return new Overlay({
        position: fromLonLat([lon, lat]),
        element: rippleDiv,
        id: 'ripple_' + stationId,
        positioning: 'center-center'
      })
    },

    // 初始化地图弹窗
    initMapPopup() {
      this.popupOverlay = new Overlay({
        element: this.$refs.mapPopupRef,
        positioning: 'top-center',
        id: POPUP_OVERLAY_ID,
        offset: [0, 27]
      })
      this.map.addOverlay(this.popupOverlay)
    },

    // 显示地图弹窗
    async showMapPopup(stationInfo) {
      this.popupOverlay.setPosition(fromLonLat([stationInfo.lon, stationInfo.lat]))
      this.columns = PopupColumns[stationInfo.stationType]
      this.popupTitle = stationInfo.stationType
      this.isGettingInfo = true
      this.getStationInfo(stationInfo)
    },

    // 获取站点详情
    async _getStationInfo(stationInfo) {
      try {
        const { success, result, message } = await getAction('/jeecg-station-operation/stationOperation/findInfo', {
          stationId: stationInfo.stationId,
          type: stationInfo.stationType
        })
        if (success) {
          result.lon = decimalToDms(result.lon || result.longitude)
          result.lat = decimalToDms(result.lat || result.latitude, false)

          this.currStationInfo = result
        } else {
          this.$message.error(message)
        }
      } catch (error) {
        console.error(error)
      } finally {
        this.isGettingInfo = false
      }
    },

    //关闭地图弹窗
    closeMapPopup() {
      this.popupOverlay.setPosition(null)
    }
  },
  watch: {
    list() {
      this.map.getOverlays().clear()
      this.initMapPopup()
      this.initMarkers()
      this.initRipples()
    }
  }
}
</script>
<style lang="less" scoped>
.facility-info {
  &-popover {
    position: relative;
    width: 350px;
    background-color: rgba(2, 26, 29, 0.9);
    border-radius: 4px;
    box-shadow: 0 0 5px rgba(2, 26, 29, 0.9);
    padding: 5px;

    &::before {
      position: absolute;
      top: -6px;
      left: 50%;
      content: '';
      width: 12px;
      height: 12px;
      border: 1px solid rgba(2, 26, 29, 0.9);
      background: rgba(2, 26, 29, 0.9);
      transform: translateX(-50%) rotate(45deg) skew(14deg, 14deg);
      border-bottom: 0;
      border-right: 0;
    }

    h2 {
      color: #6ebad0;
      font-size: 16px;
      text-align: center;
      line-height: 30px;
      border-bottom: 1px solid #0a544e;
      margin-bottom: 0;
    }
  }

  @border: 1px solid #0a544e;
  &-item {
    display: flex;
    border: @border;
    border-top: 0;
    line-height: 25px;

    &-label,
    &-content {
      width: 50%;
      padding: 0 3px;
      text-align: center;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    &-label {
      border-right: @border;
      color: #6ebad0;
    }
  }
}
</style>
<style lang="less">
.custom-ripple {
  width: 85px;
  height: 85px;
  z-index: -1;

  @duration: 1.8s;
  @delay: 0.9s;
  .inner-ripple-1 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.1) 30%, rgba(15, 148, 28, 0.5) 60%);
    animation: rippleEffect @duration linear @delay infinite;
  }
  .inner-ripple-2 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.1) 30%, rgba(15, 148, 28, 0.5) 60%);
    animation: rippleEffect @duration linear @delay * 2 infinite;
  }
}

@keyframes rippleEffect {
  0% {
    transform: scale(0.6);
    opacity: 1;
  }
  100% {
    transform: scale(1.2);
    opacity: 0;
  }
}
</style>
