<template>
  <div id="mapAssembly_container" class="mapAssembly-container">
    <!-- 地图 -->
    <div id="map" />

    <!-- 悬浮框主体 -->
    <div class="mainer">

      <div v-if="currentSelectPointAccident" class="center">
        <div v-for="(item, index) in pointsList" :key="index" class="point" @click="handlePoint(item, index)">
          <div class="rescue-box">
            <img :src="item.check ? item.check_img : item.img" class="rescue-img" alt="">
            <p class="rescue-text"> {{ item.label }} </p>
          </div>
        </div>
      </div>

      <div class="left">
        <!-- 应急机构 -->
        <div class="emergency-department">
          <h2 class="department-title">应急机构</h2>
          <div class="department-body">
            <ul
              v-for="(item, index) in expertGroupInfo"
              :key="index"
              class="department-ul"
              @click="expertInfoItemClick(item, index)">
              <li class="department-li">专家组名称: {{ item.EXPERT_GROUP_NAME }}</li>
              <li class="department-li">联系电话: {{ item.CONTACT_TELEPHONE }}</li>
            </ul>
          </div>
        </div>
        <div class="line" />
        <!-- 联系人方式 -->
        <div class="contact-information">
          <h2 class="contact-title">联系人方式</h2>
          <div v-if="varList.length > 0">
            <ul v-for="(item, index) in varList" :key="index" class="contact-ul">
              <li class="contact-li">专家姓名: {{ item.GENDER }}</li>
              <li class="contact-li">性别: {{ item.EXPERT_NAME }}</li>
              <li class="contact-li">专家类型: {{ item.EXPERT_TYPE }}</li>
              <li class="contact-li">专家姓名: {{ item.EXPERT_NAME }}</li>
              <li class="contact-li">办公电话: {{ item.OFFICE_TELEPHONE }}</li>
              <li class="contact-li">移动电话: {{ item.MOBILE_TELEPHONE }}</li>
            </ul>
          </div>
          <div v-else class="contact-empty">
            <span>暂无数据</span>
          </div>
        </div>
      </div>

      <!-- 对话框 -->
      <div class="right">
        <!-- 对话框组件渲染 -->
        <chat />
      </div>

    </div>
  </div>
</template>

<script>
import { requestFN } from '@/utils/request'
import autofit from 'autofit.js'
import chat from './chat.vue'

let mapInstance

export default {
  components: { chat },
  data() {
    return {
      config: config,
      pointsList: [
        {
          img: require('@/assets/map/emergency_rescue/ico1.png'),
          check_img: require('@/assets/map/emergency_rescue/ico1_on.png'),
          label: '分类一',
          check: true,
          type: 1
        },
        {
          img: require('@/assets/map/emergency_rescue/ico2.png'),
          check_img: require('@/assets/map/emergency_rescue/ico2_on.png'),
          label: '分类二',
          check: false,
          type: 2
        },
        {
          img: require('@/assets/map/emergency_rescue/ico3.png'),
          check_img: require('@/assets/map/emergency_rescue/ico3_on.png'),
          label: '更多',
          check: false,
          type: 3
        },
        {
          img: require('@/assets/map/emergency_rescue/reset_point.png'),
          check_img: null,
          label: '重置',
          check: false,
          type: 4
        }
      ],
      // 列表查询参数
      listQuery: {
        page: 1,
        limit: 10
      },
      KEYWORDS: '',
      /** 应急救援专家组状态变量 */
      expertGroupInfo: [],
      /** 存储某个专家组的所在成员 */
      varList: [],
      /** 当前选择的事故信息 */
      currentSelectPointAccident: ''
    }
  },
  mounted() {
    // 使用 autofit 第三方库实现PC自适应屏幕
    autofit.init({
      el: '#mapAssembly_container',
      resize: true
    })
    /** 调用地图初始化方法 */
    this.mapInit()
    /** 调用初始化点位绘制方法 */
    this.initPoints()
    this.getYjExpertGroupInfo()
  },
  methods: {
    /** 地图初始化 */
    mapInit() {
      mapInstance = new window.BMapGL.Map('map') // 创建地图实例
      mapInstance.centerAndZoom(new window.BMapGL.Point('119.645516', '39.934547'), 15) // 创建点坐标
      mapInstance.enableScrollWheelZoom(true) // 开启鼠标滚轮缩放能力
    },
    /** 扎点方法 */
    addPoint(anchor) {
      if (!anchor.iconUrl) throw new Error('请传入图标')
      // if (!anchor.imageSize) throw new Error('请传入图片大小')
      if (!anchor.longitude) throw new Error('请传入经度')
      if (!anchor.latitude) throw new Error('请传入纬度')
      const imageSize = new window.BMapGL.Size(23, 30)
      const icon = new window.BMapGL.Icon(config.fileUrl + anchor.iconUrl, imageSize, { imageSize })
      const point = new window.BMapGL.Point(anchor.longitude, anchor.latitude)
      const marker = new window.BMapGL.Marker(point, { icon }) // 创建标注
      const anchorOpts = {
        width: 90,
        height: 70,
        title: '资源信息'
      }
      const infoWindow = new window.BMapGL.InfoWindow(`<p">资源名称: ${anchor.name || '无'}</p>`, anchorOpts)
      marker.addEventListener('mouseover', () => {
        mapInstance.openInfoWindow(infoWindow, point)
      })
      mapInstance.addOverlay(marker) // 将标注添加到地图中
    },
    handleClickInfo() {
      console.log('你惦记了')
    },
    /** 标点的信息窗口控制器 */
    infoWindowPointerController(config) {
      const { point, marker, info } = config
      var opts = {
        width: 300,
        height: 200,
        title: '事故点位信息'
      }
      const sContent = `
      <div>
        <ul>
          <li>机主姓名: ${info.accident.OWNER_NAME || '无'}</li>
          <li>访问模式: ${info.accident.ACCESS_MODE || '无'}</li>
          <li>呼入电话: ${info.accident.INCOMING_PHONE || '无'}</li>
          <li>事件类型: ${info.accident.EVENT_TYPE || '无'}</li>
          <li>接报时间: ${info.accident.REPORT_TIME || '无'}</li>
          <li>发生时间: ${info.accident.OCCURRENCE_TIME || '无'}</li>
          <li>救援情况: ${info.accident.RESCUE_SITUATION || '无'}</li>
        </ul>  
      </div>
      `
      const infoWindow = new window.BMapGL.InfoWindow(sContent, opts)
      marker.addEventListener('mouseover', () => {
        mapInstance.openInfoWindow(infoWindow, point)
      })
    },
    /** 给地图扎点标记事件事故 */
    addPointCallback(anchor) {
      if (!anchor.iconUrl) throw new Error('请传入图标')
      if (!anchor.LONGITUDE) throw new Error('请传入经度')
      if (!anchor.LATITUDE) throw new Error('请传入纬度')
      const { LONGITUDE, LATITUDE } = anchor
      const imageSize = new window.BMapGL.Size(33, 40)
      const icon = new window.BMapGL.Icon(config.fileUrl + anchor.iconUrl, imageSize, { imageSize }) // 创建 icon 图标
      var point = new window.BMapGL.Point(LONGITUDE, LATITUDE)
      const marker = new window.BMapGL.Marker(point, { icon }) // 创建标注
      mapInstance.addOverlay(marker) // 将标注添加到地图中
      // 处理标注事件点击行为
      marker.addEventListener('click', async() => {
        let accidentParams = {}
        let nearbyResourcesList = []
        // 获取指定点位所对应的范围等详细信息
        this.currentSelectPointAccident = anchor

        const result = await this.getQueryScopeAsync(anchor)

        if (result.code === 200) {
          mapInstance.clearOverlays() // 清除地图上所有覆盖物
          const { accident, nearbyResources } = result.data
          accidentParams = accident
          nearbyResourcesList = nearbyResources
          const point = new window.BMapGL.Point(accidentParams.LONGITUDE, accidentParams.LATITUDE)
          const marker = new window.BMapGL.Marker(point, { icon })
          mapInstance.addOverlay(marker)
          this.infoWindowPointerController({ point, marker, info: result.data })

          if (nearbyResourcesList.length === 0) return
          nearbyResourcesList.forEach(item => {
            this.addPoint(item)
          })
        }
      })
    },
    /** 获取指定点位所在周围范围等详细信息 */
    getQueryScopeAsync(enterParams) {
      return new Promise((resolve, reject) => {
        requestFN('major/comprehensive/scope', {
          accidentId: enterParams.id,
          type: enterParams.type ? enterParams.type : ''
        }).then((data) => {
          resolve(data)
          return data
        }).catch((error) => {
          reject(error)
        })
      })
    },
    /** 初始化定位点 */
    getInfo(id) {
      requestFN('/dictionaries/listTree').then((data) => {
        this.treeData = JSON.parse(data.zTreeNodes)
      }).catch((e) => {
        console.error('获取树形数据失败', e)
      })
    },
    /** 初始化点位绘制方法 */
    async initPoints() {
      const result = await this.getAccidentList()
      result.data.forEach((item) => {
        this.addPointCallback(item)
      })
    },
    /** 获取事故列表的所有点位信息 */
    getAccidentList() {
      return new Promise((resolve, reject) => {
        requestFN('/major/comprehensive/accidentList')
          .then((data) => {
            resolve(data)
          }).catch((e) => { })
      })
    },
    /** 初始化获取应急救援专家组 */
    getYjExpertGroupInfo() {
      requestFN(
        '/yjExpertGroup/list?showCount=' + this.listQuery.limit + '&currentPage=' + this.listQuery.page,
        {
          name: this.KEYWORDS
        }
      ).then((data) => {
        this.expertGroupInfo = data.varList
      })
        .catch((e) => {
          this.listISLOADing = false
        })
    },
    /** 点击某一项专家组的处理事件 */
    async expertInfoItemClick(item, index) {
      requestFN(
        '/yjExpertGroup/groupExpertlist?showCount=' + this.listQuery.limit + '&currentPage=' + this.listQuery.page,
        {
          name: null,
          id: item.EXPERT_GROUP_ID
        }
      ).then((data) => {
        this.varList = data.varList
      })
        .catch((e) => { })
    },
    /** 处理分类下的扎点坐标渲染任务 */
    async baseClassifyPointer(type) {
      mapInstance.clearOverlays() // 清除地图上所有覆盖物
      let accidentParams = {}
      let nearbyResourcesList = []
      const response = await this.getQueryScopeAsync({
        id: this.currentSelectPointAccident.id,
        type
      })
      const { accident, nearbyResources } = response.data
      accidentParams = accident
      nearbyResourcesList = nearbyResources
      const imageSize = new window.BMapGL.Size(33, 40)
      const icon = new window.BMapGL.Icon(config.fileUrl + this.currentSelectPointAccident.iconUrl, imageSize, { imageSize }) // 创建 icon 图标
      const point = new window.BMapGL.Point(accidentParams.LONGITUDE, accidentParams.LATITUDE)
      const marker = new window.BMapGL.Marker(point, { icon })
      mapInstance.addOverlay(marker)

      if (nearbyResourcesList.length === 0) return
      nearbyResourcesList.forEach(item => {
        this.addPoint(item)
      })
    },
    /** 处理点坐标 */
    async handlePoint(item, index) {
      switch (index) {
        case 0: {
          this.pointsList[index].check = !this.pointsList[index].check
          this.baseClassifyPointer(item.type)
          break
        }
        case 1: {
          this.pointsList[index].check = !this.pointsList[index].check
          this.baseClassifyPointer(item.type)
          break
        }
        case 2: {
          this.pointsList[index].check = !this.pointsList[index].check
          this.baseClassifyPointer(item.type)
          break
        }
        case 3: {
          mapInstance.clearOverlays()
          this.initPoints()
        }
      }
    }
  }
}
</script>

<style scoped lang="scss">
.mapAssembly-container {
  width: 100vw;
  height: 100vh;
  font-family: '微软雅黑', "宋体", "Arial Narrow", Helvetica, sans-serif;
  overflow: hidden;
  margin: 0;

  // 地图的宽高样式限制
  #map {
    width: 100%;
    height: 91%;
  }

  .mainer {
    box-sizing: border-box;
    width: 100%;
    height: 100%;

    .center {
      width: 340px;
      position: absolute;
      left: 50%;
      top: 765px;
      transform: translateX(-170px);
      z-index: 99;
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;

      .point {
        display: flex;
        justify-content: center;
        align-items: center;
        cursor: pointer;
        width: 50px;
        height: 60px;
      }

      .rescue-box {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: column;
        width: 45px;
        height: 45px;

        .rescue-img {
          width: 100%;
          height: 100%;
        }

        .rescue-text {
          margin: 0;
          padding: 0;
          color: rgb(0, 52, 221);
          font-weight: 800;
          font-size: 14px;
        }
      }
    }

    .left {
      width: 477px;
      height: 850px;
      max-height: 850px;
      background: rgba(20, 31, 168, .7);
      border: 1px solid #0060d7;
      z-index: 99;
      position: absolute;
      top: 20px;
      left: 18px;
      border-radius: 8px;
      box-sizing: border-box;
      padding: 12px;

      // 应急机构样式
      .emergency-department {
        max-height: 420px;
        overflow: auto;
        border-radius: 8px;
        width: 100%;

        .department-title {
          padding: 0;
          margin: 0;
          color: rgba(255, 255, 255, 1);
          padding: 5px 0 5px 6px;
          font-size: 21px;
        }

        .department-body {
          height: 85%;
          overflow: auto;

          &::-webkit-scrollbar {
            display: none;
          }

          .department-ul {
            width: 100%;
            margin-bottom: 9px;
            border-radius: 8px;
            padding: 5px;
            display: flex;
            flex-direction: column;
            gap: 5px;
            cursor: pointer;

            &:hover {
              box-shadow:
                inset -1px -3px 4px rgba(255, 255, 255, .9), inset 8px 6px 12px rgba(0, 0, 0, .4);
            }

            .department-li {
              color: rgb(255, 255, 255);
            }
          }
        }
      }

      // 分割线条
      .line {
        width: 100%;
        height: 1px;
        border-bottom: 1px solid #fff;
        margin: 10px 0;
      }

      // 联系人方式样式
      .contact-information {
        border-radius: 8px;
        width: 100%;

        .contact-title {
          padding: 0;
          margin: 0;
          color: rgba(255, 255, 255, 1);
          padding: 5px 0 5px 6px;
          font-size: 21px;
        }

        .contact-ul {
          max-height: 420px;
          overflow: auto;
          width: 100%;
          margin-bottom: 9px;
          border-radius: 8px;
          padding: 5px;
          display: flex;
          flex-direction: column;
          gap: 5px;

          .contact-li {
            color: rgb(255, 255, 255);
          }
        }

        .contact-empty {
          width: 100%;
          height: 600px;
          display: flex;
          justify-content: center;
          align-items: center;
          color: white;
        }
      }
    }

    .right {
      box-sizing: border-box;
      z-index: 99;
      background: rgba(20, 31, 168, .7);
      border: 1px solid #0060d7;
      width: 477px;
      height: 850px;
      max-height: 850px;
      position: absolute;
      top: 20px;
      right: 265px;
      border-radius: 8px;
      padding: 12px;
    }
  }
}
</style>
