<template>
  <div class="map_assembly_container">

    <!-- 地图 -->
    <div id="map"/>

    <div id="mapAssembly_container" class="body_container">
      <div class="body_flex_box">
        <!-- 左侧面板 -->
        <div class="left">
          <base-table :info="info" use-type="dutyInfo"/>
          <base-table :info="info" use-type="reservePlanInfo" is-reserve-plan/>
          <base-table :info="info" use-type="addressBook"/>
        </div>
        <!-- 右侧面板 -->
        <div class="right">
          <sysChat :chat-data="chatData" @orderMessage="handlerOrderMessage" @reFlush="initInfo()" @endRescue="endRescue()"/>
        </div>
      </div>
      <div class="top_search">
        <span
          v-for="(item, index) in rangeList"
          :class="{ active: activeIndex === index }"
          :key="index"
          class="range_item"
          @click="setActive(item, index)"
        >{{ item }} 米</span>
      </div>
      <div class="bottom-center">
        <div class="secon_modal">
          <span v-for="(sos, ind) in currSubControlPoint" :key="ind" @click="subToggleCheck(sos, ind)">
            <img :src="!sos.check ? sos.imgUrl : sos.check_img" alt="">
            <p>{{ sos.label }}</p>
          </span>
        </div>
        <div class="control_pointer">
          <span
            v-for="(item, index) in controlPoint"
            :key="index"
            style="cursor: pointer;"
            @click="toggleCheck(item, index)">
            <img :src="!item.check ? item.imgUrl : item.check_img" alt="">
            <p>{{ item.label }}</p>
          </span>
        </div>
      </div>
    </div>

    <dialog-index :visible.sync="infoDialog.visible" :value="{ ...infoDialog.info }" :title="infoDialog.title"/>
  </div>
</template>

<script>
import { requestFN } from '@/utils/request'
import baseTable from './baseTable.vue'
import sysChat from './sysChat.vue'
import DialogIndex from './dialog.vue'

let mapInstance

export default {
  components: { baseTable, sysChat, DialogIndex },
  data() {
    return {
      info: {
        dutyInfoData: [],
        reservePlan: {},
        addressBook: []
      },
      chatData: [],
      infoDialog: {
        visible: false,
        id: '',
        info: {},
        title: ''
      },
      activeIndex: 0,
      range: 20,
      rangeList: [20, 50, 100, 500, 1000, 5000],
      mapIco: [
        {
          id: 'e1899a925eb7478653007a9e7d17d588',
          ico: require('../../../../assets/map/emergency_rescue/point/img1.png')
        },
        {
          id: 'ea3555185c6498b2d3d07023de723806',
          ico: require('../../../../assets/map/emergency_rescue/point/img2.png')
        },
        {
          id: '52ddb251b528987c58c4d84fe0d83952',
          ico: require('../../../../assets/map/emergency_rescue/point/img3.png')
        },
        {
          id: '7f3d41464cdf450422ffe385c3aa870e',
          ico: require('../../../../assets/map/emergency_rescue/point/img4.png')
        },
        {
          id: '2ef8327624adad89b2dbf6b2e03ac6ef',
          ico: require('../../../../assets/map/emergency_rescue/point/img5.png')
        },
        {
          id: 'e1899a925eb7478653007a9e7d17d588',
          ico: require('../../../../assets/map/emergency_rescue/point/img6.png')
        },
        {
          id: '122abe9858feaecae1c80d2d851fcd57',
          ico: require('../../../../assets/map/emergency_rescue/point/img7.png')
        },
        {
          id: '637b70684bddcfbee0421db1443a972a',
          ico: require('../../../../assets/map/emergency_rescue/point/img8.png')
        },
        {
          id: '950700c9cd80c5e1b22a6c6cdf63a61d',
          ico: require('../../../../assets/map/emergency_rescue/point/img9.png')
        },
        {
          id: '1edb69abc25785c02e2e475162d65b17',
          ico: require('../../../../assets/map/emergency_rescue/point/img10.png')
        },
        {
          id: 'd25f2cae07902e373b72e74757e7a6ea',
          ico: require('../../../../assets/map/emergency_rescue/point/img11.png')
        },
        {
          id: 'be31acea122c423a9dbb431cc66a1351',
          ico: require('../../../../assets/map/emergency_rescue/point/img12.png')
        },
        {
          id: '759d323be34eae4bd83289b36af9ea47',
          ico: require('../../../../assets/map/emergency_rescue/point/img13.png')
        }
      ],
      controlPoint: [
        {
          id: '0',
          label: '应急资源',
          imgUrl: require('../../../../assets/map/emergency_rescue/ico1.png'),
          check_img: require('../../../../assets/map/emergency_rescue/ico1_on.png'),
          check: true
        },
        {
          id: '1',
          label: '消防信息',
          imgUrl: require('../../../../assets/map/emergency_rescue/ico2.png'),
          check_img: require('../../../../assets/map/emergency_rescue/ico2_on.png'),
          check: false
        },
        {
          id: '2',
          label: '人员定位',
          imgUrl: require('../../../../assets/map/emergency_rescue/ico3.png'),
          check_img: require('../../../../assets/map/emergency_rescue/ico3_on.png'),
          check: false
        },
        {
          id: '3',
          label: '视频监控',
          imgUrl: require('../../../../assets/map/emergency_rescue/ico4.png'),
          check_img: require('../../../../assets/map/emergency_rescue/ico4_on.png'),
          check: false
        },
        {
          id: '4',
          label: '气象监测',
          imgUrl: require('../../../../assets/map/emergency_rescue/ico5.png'),
          check_img: require('../../../../assets/map/emergency_rescue/ico5_on.png'),
          check: false
        }
      ],
      ctlActiveIndex: 0,
      subControlPoint: {
        '0': [
          {
            id: '9b3b9451cf9a86b1e8a44c9a9b0de826',
            code: '0',
            label: '资料装备库',
            imgUrl: require('../../../../assets/map/emergency_rescue/i1.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i1_on.png'),
            check: true
          },
          {
            id: 'f61af43a0af59c86187913f9fe084588',
            code: '1',
            label: '应急避难场所',
            imgUrl: require('../../../../assets/map/emergency_rescue/i2.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i2_on.png'),
            check: false
          },
          {
            id: '7a38cf58e55995c0a5ce2c8e1f5bcc79',
            code: '2',
            label: '排水井',
            imgUrl: require('../../../../assets/map/emergency_rescue/i3.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i3_on.png'),
            check: false
          },
          {
            id: 'a0fd60946978e28dac5b8a2965e00a2b',
            code: '3',
            label: '封闭卡口',
            imgUrl: require('../../../../assets/map/emergency_rescue/i4.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i4_on.png'),
            check: false
          }
        ],
        '1': [
          {
            id: '1768cf2b0fb0844dedbb6db1dca3cc79',
            code: '4',
            label: '消防控制室',
            imgUrl: require('../../../../assets/map/emergency_rescue/i5.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i5_on.png'),
            check: false
          },
          {
            id: '18849e29cce63a9408117ca26186203b',
            code: '5',
            label: '消防泵房',
            imgUrl: require('../../../../assets/map/emergency_rescue/i6.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i6_on.png'),
            check: false
          },
          {
            id: 'da52ba25c3f15ad932b18fbd4d028062',
            code: '6',
            label: '消防水源',
            imgUrl: require('../../../../assets/map/emergency_rescue/i7.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i7_on.png'),
            check: false
          },
          {
            id: 'e241e3ef479ac7fb217c7b496816dc7e',
            code: '7',
            label: '消防点位',
            imgUrl: require('../../../../assets/map/emergency_rescue/i8.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i8_on.png'),
            check: false
          }
        ],
        '2': [
          {
            id: '93f7e01c8e4d906053916d314e1d3a2a',
            code: '8',
            label: '人员定位',
            imgUrl: require('../../../../assets/map/emergency_rescue/i9.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i9_on.png'),
            check: false
          },
          {
            id: '30fcda69c3eae93adbab78dea360b6b0',
            code: '9',
            label: '人员轨迹',
            imgUrl: require('../../../../assets/map/emergency_rescue/i10.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i10_on.png'),
            check: false
          }
        ],
        '3': [
          {
            id: '6ac1fc24fde38671ee70d7aebeed5276',
            code: '10',
            label: '摄像头',
            imgUrl: require('../../../../assets/map/emergency_rescue/i11.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i11_on.png'),
            check: false
          }
        ],
        '4': [
          {
            id: '3f858ab418dbf791353ba6ff87c59e85',
            code: '12',
            label: '气象站',
            imgUrl: require('../../../../assets/map/emergency_rescue/i12.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i12_on.png'),
            check: false
          },
          {
            id: '997392774d64efd8507c7c518c23fc44',
            code: '11',
            label: '风速站',
            imgUrl: require('../../../../assets/map/emergency_rescue/i13.png'),
            check_img: require('../../../../assets/map/emergency_rescue/i13_on.png'),
            check: false
          }
        ]
      },
      // 当前点击后选择的二级坐标点位分类集合
      currSubControlPoint: [],
      subControlPointIndex: 0,
      webSocket: null,
      heartbeat: null,
      REPORT_ID: null,
      FIRERESERVEPLAN_ID: null,
      CODE: null,
      CORPIFNO_ID: JSON.parse(sessionStorage.getItem('user')).CORPIFNO_ID,
      firstPoint: {
        x: null,
        y: null
      },
      mapLevel: 20
    }
  },
  mounted() {
    /** 调用地图初始化方法 */
    this.firstInitPoint()
    /** 调用初始化点位绘制方法 */
    // this.initPoints()
    /** 初始化选中首个二级坐标点位分类 */
    this.currSubControlPoint = this.subControlPoint['0']
  },
  created() {
    this.REPORT_ID = this.$route.query.REPORT_ID
    this.FIRERESERVEPLAN_ID = this.$route.query.FIRERESERVEPLAN_ID
    this.initInfo()
    this.initWebsocket()
    this.initPoint({ code: 0, REPORT_ID: this.REPORT_ID, range: this.range })
  },
  beforeDestroy() {
    if (this.webSocket) {
      this.webSocket.close()
    }
    if (this.heartbeat) {
      clearInterval(this.heartbeat)
    }
  },
  methods: {
    /** 地图初始化 */
    mapInit(e) {
      this.firstPoint.x = e.x
      this.firstPoint.y = e.y
      mapInstance = new window.BMapGL.Map('map') // 创建地图实例
      mapInstance.centerAndZoom(new window.BMapGL.Point(e.y, e.x), this.mapLevel) // 创建点坐标
      mapInstance.enableScrollWheelZoom(true) // 开启鼠标滚轮缩放能力
      var point = new window.BMapGL.Point(this.firstPoint.y, this.firstPoint.x) // 设置中心点坐标（例如北京天安门）
      mapInstance.centerAndZoom(point, this.mapLevel) // 设置中心点和缩放级别
      mapInstance.enableScrollWheelZoom(true)
      var circle = new window.BMapGL.Circle(point, this.range, {
        strokeColor: 'blue',
        strokeWeight: 2,
        strokeOpacity: 0.5,
        fillColor: 'blue',
        fillOpacity: 0.2
      })
      mapInstance.addOverlay(circle)
    },
    setActive(item, index) {
      // 设置被选中项的索引
      this.activeIndex = index
      this.range = item
      mapInstance.clearOverlays()
      var point = new window.BMapGL.Point(this.firstPoint.y, this.firstPoint.x) // 设置中心点坐标（例如北京天安门）
      mapInstance.centerAndZoom(point, this.mapLevel) // 设置中心点和缩放级别
      mapInstance.enableScrollWheelZoom(true)
      var circle = new window.BMapGL.Circle(point, item, { // 2000米半径
        strokeColor: 'blue',
        strokeWeight: 2,
        strokeOpacity: 0.5,
        fillColor: 'blue',
        fillOpacity: 0.2
      })
      mapInstance.addOverlay(circle)
      this.initPoint({ code: this.CODE, reportId: this.REPORT_ID, range: this.range })
    },
    /** 扎点方法 */
    addPoint(anchor) {
      if (!anchor.icon) throw new Error('请传入图标')
      if (!anchor.y) throw new Error('请传入经度')
      if (!anchor.x) throw new Error('请传入纬度')
      const imageSize = new window.BMapGL.Size(23, 30)
      const icon = new window.BMapGL.Icon(config.fileUrl + anchor.icon, imageSize, { imageSize })
      const point = new window.BMapGL.Point(anchor.y, anchor.x)
      const marker = new window.BMapGL.Marker(point, { icon }) // 创建标注
      marker.addEventListener('click', async() => {
        this.infoDialog.visible = true
        this.infoDialog.info = anchor
        this.infoDialog.title = anchor.typeName
      })
      mapInstance.addOverlay(marker) // 将标注添加到地图中
    },
    /** 给地图扎点标记事件事故 */
    addPointCallback(anchor) {
      if (!anchor.icon) throw new Error('请传入图标')
      if (!anchor.y) throw new Error('请传入经度')
      if (!anchor.x) throw new Error('请传入纬度')
      const imageSize = new window.BMapGL.Size(33, 40)
      const icon = new window.BMapGL.Icon(config.fileUrl + anchor.icon, imageSize, { imageSize }) // 创建 icon 图标
      var point = new window.BMapGL.Point(anchor.y, anchor.x)
      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)
          })
        }
      })
    },
    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)
      })
    },
    /** 获取指定点位所在周围范围等详细信息 */
    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)
        })
      })
    },
    /** 初始化点位绘制方法 */
    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) => {
          })
      })
    },
    // 一级坐标点位点击事件
    toggleCheck(item, index) {
      // 遍历所有项，将点击项的 check 设置为 true，其他项的 check 设置为 false
      this.controlPoint.forEach((item, idx) => {
        if (idx === index) {
          item.check = true
        } else {
          item.check = false
        }
      })
      this.currSubControlPoint = this.subControlPoint[index]
    },
    // 二级坐标点位点击事件
    subToggleCheck(sos, ind) {
      mapInstance.clearOverlays()
      var point = new window.BMapGL.Point(this.firstPoint.y, this.firstPoint.x) // 设置中心点坐标（例如北京天安门）
      mapInstance.centerAndZoom(point, 10) // 设置中心点和缩放级别
      mapInstance.enableScrollWheelZoom(true)
      var circle = new window.BMapGL.Circle(point, this.range, { // 2000米半径
        strokeColor: 'blue',
        strokeWeight: 2,
        strokeOpacity: 0.5,
        fillColor: 'blue',
        fillOpacity: 0.2
      })
      mapInstance.addOverlay(circle)
      this.initPoint(sos)
      this.currSubControlPoint.forEach((item, idx) => {
        if (idx === ind) {
          item.check = true
        } else {
          item.check = false
        }
      })
    },
    // 接收子组件传递出来的指令发送的事件
    handlerOrderMessage() {
      this.infoDialog.visible = true
      this.infoDialog.info = { type: 'sendMessage', FIRERESERVEPLAN_ID: this.FIRERESERVEPLAN_ID, REPORT_ID: this.REPORT_ID }
      this.infoDialog.title = '指令信息'
    },
    initInfo() {
      const loading = this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      requestFN(
        '/bi/emergency/getYjBiInformation',
        {
          FIRERESERVEPLAN_ID: this.FIRERESERVEPLAN_ID,
          REPORT_ID: this.REPORT_ID
        }
      ).then((data) => {
        if (data.result === 'success') {
          // 值班列表
          this.info.dutyInfoData = data.dutyList
          // 预案信息
          this.info.reservePlan = data.planInfo
          this.info.addressBook = data.addressBookList
          this.chatData = data.instructList
        }
        loading.close()
      }).catch((e) => {
        console.log(e)
        loading.close()
      })
    },
    initWebsocket() {
      const wsUrl = config.YjSysUrl + '/yjMessage/' + this.REPORT_ID
      this.webSocket = new WebSocket(encodeURI(wsUrl))
      this.webSocket.onopen = () => {
        console.info('指挥调度的webSocket链接成功')
        this.webSocket.send('链接成功')
      }
      this.webSocket.onerror = () => {
        this.$router.back()
      }
      this.webSocket.onclose = () => {
        this.$router.push('/emergen_cyrescue/incident_management')
      }
      var _this = this
      this.webSocket.onmessage = function(message) {
        _this.initInfo()
      }
      // 新建心跳，持续监听链接是否存活
      this.heartbeat = setInterval(() => {
        try {
          if (this.webSocket) {
            this.webSocket.send('企业端' + this.REPORT_ID)
          }
        } catch (e) {
          console.log('链接已断开')
        }
      }, 3000)
    },
    initPoint(row) {
      const loading = this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      this.CODE = row.code
      requestFN(
        '/bi/emergency/getPoint',
        {
          code: row.code,
          reportId: this.REPORT_ID,
          range: this.range
        }
      ).then((data) => {
        if (data.result === 'success') {
          for (let i = 0; i < data.list.length; i++) {
            this.addPoint(data.list[i])
          }
        }
        loading.close()
      }).catch((e) => {
        console.log(e)
        loading.close()
      })
    },
    firstInitPoint() {
      const loading = this.$loading({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(0, 0, 0, 0.7)'
      })
      requestFN(
        '/bi/emergency/firstPoint', { code: 0, reportId: this.REPORT_ID, range: this.range }
      ).then((data) => {
        if (data.result === 'success') {
          this.mapInit(data.firstPoint)
        }
        loading.close()
      }).catch((e) => {
        console.log(e)
        loading.close()
      })
    },
    endRescue() {
      requestFN('/bi/emergency/endRescue', { ID: this.REPORT_ID })
        .then((data) => {
          this.$message({
            message: '确认已收到指令',
            type: 'success'
          })
          this.$router.push('/emergen_cyrescue/incident_management')
        }).catch((error) => {
          console.log(error)
        })
    }
  }
}
</script>

<style scoped lang="scss">
.map_assembly_container {
  height: 100%;

  position: relative;

  // 地图的宽高样式限制
  #map {
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
  }

  .body_container {
    position: absolute;
    left: 0;
    top: 0;
    padding: 18px;
    width: 100%;
    height: 100%;

    .body_flex_box {
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .left,
      .right {
        box-sizing: border-box;
        z-index: 99;
        width: 380px;
        height: 100%;
        background-color: #000d27bd;
        border-radius: 6px;
        border: 2px solid #034383;
      }

      .left {
        .scroll-box {
          height: 40px;
          overflow-x: hidden;
          overflow-y: auto;
        }
      }

      .right {
        position: relative;
        width: 410px;
      }
    }

    .top_search {
      z-index: 99;
      position: absolute;
      left: 405px;
      top: 18px;
      display: flex;
      align-items: center;
      justify-content: center;

      .range_item {
        overflow: hidden;
        cursor: pointer;
        border-right: 1px solid #183c70;
        display: inline-block;
        width: 67px;
        text-align: center;
        height: 34px;
        line-height: 34px;
        color: #fff;
        background-color: #223050;

        &:first-child {
          border-top-left-radius: 6px;
          border-bottom-left-radius: 6px;
        }

        &:last-child {
          border-top-right-radius: 6px;
          border-bottom-right-radius: 6px;
          border-right: none;
        }

        &.active {
          background-color: #06417d;
          color: #4aecff;
        }
      }
    }

    .bottom-center {
      z-index: 99;
      position: absolute;
      bottom: 18px;
      left: 50%;
      transform: translateX(-50%);
      width: calc(100% - 1123px);
      min-width: 335px;
      height: 80px;
      background-image: url('../../../../assets/map/emergency_rescue/menubg.png');
      background-repeat: no-repeat;
      background-size: contain;
      background-size: 100% 77px;

      .secon_modal {
        gap: 23px;
        padding: 0 18px;
        height: 60px;
        border-radius: 6px;
        border: 1px solid #364260;
        background-color: #214e8caf;
        position: absolute;
        left: 0px;
        top: -75px;
        display: flex;
        align-items: center;
        justify-content: space-evenly;

        & span {
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
        }

        & img {
          width: 30px;
          height: 30px;
          margin-bottom: 4px;
        }

        & p {
          color: #ffffff;
          margin: 0;
          padding: 0;
          font-size: 12px;
        }
      }

      .control_pointer {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: space-evenly;
        position: absolute;
        top: -23px;

        & img {
          width: 70px;
          height: 70px;
        }

        & p {
          color: #ffffff;
          margin: 0;
          padding: 0;
        }
      }
    }
  }
}
</style>
