<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, MarkerType } 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
    },
    markerType: {
      type: Number,
      default: 1
    },
    radius: {
      type: Number
    }
  },
  data() {
    return {
      currStationInfo: {},
      isGettingInfo: false,
      columns: {},
      popupTitle: ''
    }
  },
  mounted() {
    this.map = this.$parent.getMapInstance()
    this.map.getView().on('change:resolution', () => {
      // 分辨率发生变化时的处理逻辑
      this.changeCircleRadius()
    })

    this.getStationInfo = debounce(stationInfo => {
      // 查询设施详情时去抖动
      if (this.isHover) {
        this._getStationInfo(stationInfo)
      }
    }, 0)
  },
  methods: {
    initCircles() {
      const circleRadius = this.getRadius() * 2

      this.list
        .filter(
          stationInfo =>
            stationInfo.stationType !== MarkerType.NuclearFacility && stationInfo.stationType !== MarkerType.NRL
        )
        .forEach(stationInfo => {
          this.map.addOverlay(this.getCircle(stationInfo, circleRadius))
        })
    },

    getCircle({ lon, lat, stationType, stationId }, circleRadius) {
      const circleDiv = document.createElement('div')
      circleDiv.className = 'custom-map-circle'
      circleDiv.style.width = circleRadius + 'px'
      circleDiv.style.height = circleRadius + 'px'
      circleDiv.style.borderRadius = '50%'
      circleDiv.style.backgroundColor = 'rgba(255, 0, 0, .4)'
      return new Overlay({
        position: fromLonLat([lon, lat]),
        element: circleDiv,
        id: `circle_${stationType}_${stationId}`,
        positioning: 'center-center',
        className: 'circle-overlay'
      })
    },

    // 修改圆的半径
    changeCircleRadius() {
      const overlays = this.map.getOverlays().getArray()
      const circleOverlays = overlays.filter(item => item.id.indexOf('circle') == 0) // 根据id标识获取所有的圆
      const circleRadius = this.getRadius() * 2

      circleOverlays.forEach(circle => {
        const circleEle = circle.getElement()
        circleEle.style.width = circleRadius + 'px'
        circleEle.style.height = circleRadius + 'px'
      })
    },

    // 半径计算
    getRadius() {
      const metersPerUnit = this.map
        .getView()
        .getProjection()
        .getMetersPerUnit()

      const distance = (this.radius * 1000) / metersPerUnit
      const resolution = this.map.getView().getResolution()
      return distance / resolution
    },

    // 初始化marker
    initMarkers() {
      this.list.forEach(stationInfo => {
        this.map.addOverlay(this.getMarker(stationInfo))
      })
    },

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

      const img = document.createElement('img')
      img.draggable = false
      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: `marker_${stationInfo.stationType}_${stationInfo.stationId}`,
        positioning: 'center-center'
      })
    },

    // 初始化波纹
    initRipples() {
      this.list
        .filter(
          stationInfo =>
            stationInfo.stationType !== MarkerType.NuclearFacility && stationInfo.stationType !== MarkerType.NRL
        )
        .forEach(stationInfo => {
          this.map.addOverlay(this.getRipple(stationInfo))
        })
    },

    getRipple({ lon, lat, stationId, stationType, quality }) {
      // console.log("lon, lat, stationId, stationType, quality",lon, lat, stationId, stationType, quality);
      const rippleDiv = document.createElement('div')
      rippleDiv.className = 'custom-ripple'
      if (quality == "excellent") {
        rippleDiv.innerHTML = ` <div class="inner-ripple-excellent-1"></div>
                                <div class="inner-ripple-excellent-2"></div>
                              `
      } else if (quality == "good") {
        rippleDiv.innerHTML = ` <div class="inner-ripple-good-1"></div>
                                <div class="inner-ripple-good-2"></div>
                              `
      } else if(quality == "bad"){
        rippleDiv.innerHTML = ` <div class="inner-ripple-bad-1"></div>
                                <div class="inner-ripple-bad-2"></div>
                              `
      }

      return new Overlay({
        position: fromLonLat([lon, lat]),
        element: rippleDiv,
        id: `ripple_${stationType}_${stationId}`,
        positioning: 'center-center',
        className: 'ripple-overlay'
      })
    },

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

    // 显示地图弹窗
    async showMapPopup(stationInfo) {
      this.popupOverlay.setPosition(fromLonLat([stationInfo.lon, stationInfo.lat]))
      this.popupOverlay.setOffset([stationInfo.stationType == MarkerType.NuclearFacility ? 9 : 0, 35])
      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()
      if (this.markerType == 2) {
        this.initCircles()
      }
    }
  }
}
</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: -17px;
      left: 50%;
      content: '';
      transform: translateX(-50%);
      border: 6px solid transparent;
      border-bottom-color: rgba(2, 26, 29, 0.9);
      border-bottom-width: 12px;
    }

    h2 {
      color: #6ebad0;
      font-size: 16px;
      text-align: center;
      line-height: 30px;
      border-bottom: 1px solid #0a544e;
      margin-bottom: 0;
      color: rgb(187, 138, 18);
    }
  }

  @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;

  @duration: 1.8s;
  @delay: 0.9s;

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

  .inner-ripple-excellent-2 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    transform: scale(0);
    background-image: radial-gradient(circle, transparent 10%, rgba(15, 148, 28, 0.2) 30%, rgba(15, 148, 28, 0.5) 60%);
    animation: rippleEffect @duration linear @delay infinite;
  }
  .inner-ripple-good-1 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-image: radial-gradient(circle, transparent 10%, rgba(187, 138, 18, 0.2) 30%, rgba(187, 138, 18, 0.5) 60%);
    animation: rippleEffect @duration linear 0s infinite;
  }

  .inner-ripple-good-2 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    transform: scale(0);
    background-image: radial-gradient(circle, transparent 10%, rgba(187, 138, 18, 0.2) 30%, rgba(187, 138, 18, 0.5) 60%);
    animation: rippleEffect @duration linear @delay infinite;
  }
  .inner-ripple-bad-1 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-image: radial-gradient(circle, transparent 10%, rgba(165, 58, 35, 0.2) 30%, rgba(165, 58, 35, 0.5) 60%);
    animation: rippleEffect @duration linear 0s infinite;
  }

  .inner-ripple-bad-2 {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    transform: scale(0);
    background-image: radial-gradient(circle, transparent 10%, rgba(165, 58, 35, 0.2) 30%, rgba(165, 58, 35, 0.5) 60%);
    animation: rippleEffect @duration linear @delay infinite;
  }
}

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

.ripple-overlay,
.circle-overlay {
  pointer-events: none !important;
}
</style>
