<template>
  <div
    class="mv-map-icon-container"
    :class="['icon-' + defaultConfig.type, isChecked ? 'active' : '', defaultConfig.className]"
    @click.stop="!defaultConfig.disabled && onIconClick()"
  >
    <!-- 图例 图标 -->
    <div class="mv-map-icon-img-box"
        v-if="defaultConfig.img && defaultConfig.img.length"
        :style="{
          width: defaultConfig.width,
          height: defaultConfig.height,
        }"
        @mouseover="onIconMouseOver"
        @mouseout="onIconMouseOut"
          >
      <div
        class="mv-map-icon-img"
        v-for="(item, index) in defaultConfig.img"
        :key="index"
        v-show="index === 0 ? !isChecked : isChecked"
        :class="{ opacity: loading || toolTipHover }"
      >
        <img
          :src="item"
        />
      </div>
      <!-- loading -->
      <div v-if="loading" class="mv-map-icon-loading">
        <span><i></i><i></i><i></i><i></i></span>
      </div>

      <div v-if="defaultConfig.tooltipShow">
        <!-- 默认提示框 -->
        <tool-tip
          v-show="toolTipHover"
          :text="defaultConfig.name"
          :postiton="iconConfig.tooltipPostiton"
          :theme="theme"
        />
      </div>
    </div>
    <!-- slot -->
    <slot></slot>
  </div>
</template>

<script>
import { markRaw } from 'vue-demi'
import ToolTip from './ToolTip.vue'
import { getLegendConfig } from '../lib/theme'
import {getMvMapIconSdk, getModelConfig} from '../lib/sdk/business-sdk/mv-map-icon-sdk'
/**
 * @description     图例组件
 * @author          朱琦
 * @time            2022/3/3
 */
// 图例尺寸
const ICON_SIZE = '2.5vw'
// 定时器默认时间间隔 1 min
const INTERVAL = 60

export default {
  name: "MvMapIcon",
  props: {
    // 图标配置
    iconConfig: {
      type: [String, Object],
      default: () => {
        return {}
      },
    },
  },
  components: { ToolTip },
  inject: ['mapConfigure'],
  data () {
    return {
      mvMapIconClass:null,
      defaultConfig: {
        cache: true, // 数据是否缓存
        active: false, // 图例是否默认选中加载数据
        tooltipShow: true, // 提示框是否显示
        img: [],
        width: ICON_SIZE,
        height: ICON_SIZE,
        queryParam: {},
        timer: false,
        disabled: false,
        hasClickStatus: true
      },
      timer: null,
      isChecked: false,
      loading: false,
      toolTipHover: false,
      modelConfig: true
    }
  },
  watch: {
    'mapConfigure.mapLoadFinish': {
      handler(v) {
        v && this.init()
      },
      deep: true
    },
    'mapConfigure.theme': {
      handler(v) {
        if (!this.mapConfigure.mapLoadFinish) return
        v && this.setTheme(v)
      },
      deep: true
    },
    'mapConfigure.roadType': {
      handler(v) {
        this.setRoadType(v)
      },
      deep: true
    }
  },
  computed: {
    mapId () {
      return this.mapConfigure.mapId
    },
    theme () {
      return this.mapConfigure.theme || ''
    },
    areaCode () {
      return this.mapConfigure.areaCode || ''
    },
    roadType () {
      return this.mapConfigure.roadType || ''
    },
    model () {
      return this.defaultConfig.model
    },
    // 是否缓存数据
    isCache () {
      return this.defaultConfig.cache && !this.defaultConfig.timer
    }
  },
  created () {
  },
  mounted() {
  },
  methods: {
    /**
     * 初始化地图图例配置
     */
    init () {
      const config = typeof this.iconConfig === 'string' ? { type: this.iconConfig } : this.iconConfig

      // 图例 createType 区分图例
      const createType = `${new Date().getTime()}-${config.type}` 
      Object.assign(this.defaultConfig, this.getThemeIconConfig(this.theme, config.type), config, {createType})
      
      
      const iconSdk = getMvMapIconSdk(this.defaultConfig, this.$mapSdk(this.mapId))
      
      this.mvMapIconClass = markRaw(iconSdk)

      this.modelConfig = getModelConfig(this.defaultConfig.model)

      if (this.defaultConfig.active) {
        // 图例默认选中加载数据
        this.onIconClick()
      }
    },
    /**
     * 获取数据
     */
    getData() {
      return this.mvMapIconClass.data
    },
    /**
     * 获取图层
     */
    getLayer() {
      return this.mvMapIconClass.layer
    },
    /**
     * 修改主题
     */
    setTheme (theme) {
      if (this.defaultConfig.img && this.defaultConfig.img.length) {
        const newThemeIconConfig = this.getThemeIconConfig(theme, this.defaultConfig.type)
        // 图例图片修改
        newThemeIconConfig && Object.assign(this.defaultConfig, { img: newThemeIconConfig.img })
      }

      if (this.modelConfig && this.modelConfig.hasTheme && this.defaultConfig.hasTheme !== false) {
        // 海量点图层 图标替换
        this.hideMapLayer(true)
        this.updateLayer()
      }
    },
    /**
     * 修改路网类型
     */
    setRoadType () {
      this.hideMapLayer(true)
      this.updateLayer()
    },
    /**
     * 获取该主题的图例默认配置
     */
    getThemeIconConfig (theme, type) {
      return getLegendConfig(theme, type)
    },

    /**
     * 图例点击事件
     */
    onIconClick () {
      if (this.loading) {
        return
      }
      this.isChecked = !this.isChecked
      
      this.isChecked ? this.loadMapLayer() : this.hideMapLayer()

      this.$emit('layer-click', this.defaultConfig, this.isChecked)
    },
    /**
     * 更新图层
     */
    updateLayer () {
      this.isChecked && this.loadMapLayer()
    },
    /**
     * 隐藏图层
     * @param {Boolean} isClear 是否清除图层
     */
    hideMapLayer (isClear = false) {
      this.setTimer(false)

      this.setMapLayer(false)

      isClear && (this.mvMapIconClass.layer = null)

      const currentClickMarker = this.$mapSdk(this.mapId).currentClickMarker
      if (currentClickMarker && currentClickMarker.getExtData().createType === this.defaultConfig.createType) {
        // 当前点击选中的marker 是该图例下的，清除
        this.$mapSdk(this.mapId).setMvMapClickMarker()
      }
    },

    /**
     * 加载图层
     */
    loadMapLayer () {
      this.setTimer(false)
      // 高德路况 图层
      if (this.model === 'lk') {
        this.mvMapIconClass.setData('高德路况')
        this.setMapLayer()
        return
      }

      // 缓存状态时
      if (this.isCache && this.mvMapIconClass.layer) {
        this.setMapLayer()
        return
      }

      try {
        if (this.defaultConfig.queryData) {
          this.getLayerData()
        }
      } catch (error) {
        console.error("mv-map-icon get data error, " + error)
      }

    },
    /**
     * 获取数据
     */
    getLayerData () {
      this.loading = true
      this.$emit('load-layer', 'start', this.defaultConfig)

      const param = { areaCode: this.areaCode, roadType: this.roadType }
      const queryParam = Object.assign(this.defaultConfig.queryParam, param)

      this.defaultConfig.queryData(queryParam).then(res => {

        if (!this.modelConfig) {
          // 未设置model的情况下，数据给父组件处理
          this.mvMapIconClass.setData(res)
          this.isCache && this.mvMapIconClass.loadLayer()
          this.$emit('query-callback', res, this.defaultConfig)
          this.setTimer(true)
          return
        }

        if (res.status != 0 && !res.data && !res.data.length) return

        this.setTimer(true)

        // 设置数据
        this.mvMapIconClass.setData(res.data)

        this.setMapLayer()

      }).catch((e) => {
        console.error('MvMapIcon query data is error:', e)
        this.$emit('load-layer', 'error', this.defaultConfig)
      }).finally(() => {
        this.loading = false
        this.$emit('load-layer', 'end', this.defaultConfig)
      })
    },
    /**
     * 设置图层
     * @param {Boolean} show 是否显示图层
     */
    async setMapLayer(show = true) {
        // model 自定义时
        if (!this.modelConfig) {
          return
        }

        if (show) {
          if (this.getLayer()) {
            // 显示图层
            this.mvMapIconClass.showLayer()
          } else {
            if (!this.getData()) return
            // 创建图层
            await this.mvMapIconClass.loadLayer(this.emitPointClick)

            // 回调成功后，图例已取消选中时
            !this.isChecked && this.hideMapLayer(false)
          }
        } else {
          // 隐藏图层
          if (this.getLayer()) {
            this.mvMapIconClass.hideLayer()
          }
        }
        
        
        
    },
    /**
     * 设置定时器
     * @param {Boolean} isOpen 是否开启定时器
     */
    setTimer (isOpen) {
      // 该图例未开启定时器
      if (!this.defaultConfig.timer) return
      
      if (this.timer) {
        // 关闭定时器
        clearInterval(this.timer)
        this.timer = null
      }

      // 开启定时器
      if (isOpen) {
        const interval = typeof this.defaultConfig.timer === 'number' ? Number(this.defaultConfig.timer) : INTERVAL

        this.timer = setInterval(() => {
          // 更新图层
          this.updateLayer()
        }, interval * 1000)
        return
      }
    },
    /**
     * 触发点击事件
     * @param {Object} event 点击对象
     * @param {Object} point 点击对象数据
     */
    emitPointClick(event, point) {
      this.$emit('point-click', event, point, this.defaultConfig)
    },
    /**
     * 图例鼠标移入事件
     */
    onIconMouseOver () {
      this.toolTipHover = true
    },

    /**
     * 图例鼠标移出事件
     */
    onIconMouseOut () {
      this.toolTipHover = false
    },

    /**
     * 图例销毁
     */
    destroy () {
      // 销毁定时器
      this.setTimer(false)

      this.mvMapIconClass && this.mvMapIconClass.destroy && this.mvMapIconClass.destroy()
    }
  },
  beforeDestroy () {
    this.destroy()
  },
  beforeUnmount() {
    this.destroy()
  },
}
</script>

<style scoped>
.mv-map-icon-container {
  z-index: 111;
  cursor: pointer;
}
.mv-map-icon-img-box{
  position: relative;
}
.mv-map-icon-img {
  width: 100%;
  height: 100%;
}
.mv-map-icon-img img {
  height: 100%;
  width: 100%;
  z-index: 111;
  cursor: pointer;
  /* object-fit: cover; */
}

.mv-map-icon-container .opacity {
  opacity: 0.9;
}
/* loading */
.mv-map-icon-loading {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
.mv-map-icon-loading span {
  position: relative;
  display: inline-block;
  font-size: 20px;
  width: 1em;
  height: 1em;
  transform: rotate(45deg);
  -webkit-animation: antRotate 1.2s linear infinite;
  animation: antRotate 1.2s linear infinite;
}
.mv-map-icon-loading span i {
  position: absolute;
  display: block;
  width: 9px;
  height: 9px;
  background-color: #fff;
  border-radius: 100%;
  transform: scale(0.75);
  transform-origin: 50% 50%;
  opacity: 0.3;
  -webkit-animation: antSpinMove 1s linear infinite alternate;
  animation: antSpinMove 1s linear infinite alternate;
}
.mv-map-icon-loading span i:nth-child(1) {
  top: 0;
  left: 0;
}
.mv-map-icon-loading span i:nth-child(2) {
  top: 0;
  right: 0;
  animation-delay: 0.4s;
}
.mv-map-icon-loading span i:nth-child(3) {
  right: 0;
  bottom: 0;
  animation-delay: 0.8s;
}
.mv-map-icon-loading span i:nth-child(4) {
  bottom: 0;
  left: 0;
  animation-delay: 1.2s;
}
@keyframes antRotate {
  to {
    transform: rotate(405deg);
  }
}
@keyframes antSpinMove {
  to {
    opacity: 1;
  }
}
</style>
