<template>
  <n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
    <n-drawer-content closable title="飞行直播">
      <div class="main_container">
        <div id="live-map" />
        <!-- 视频播放 -->
        <div class="videobox">
          <!-- 视频开关 -->
          <div
            class="flagbox"
            :class="videoShow == 'back' ? 'flagbox_open' : 'flaxbox_back'"
          >
            <span class="videotitle">巡检视频</span>
            <img
              v-if="videoShow == 'back'"
              src="@/assets/img/back.png"
              alt=""
              class="closedetail imageicon"
              @click="showVideo('open')"
            >
            <img
              v-else
              src="@/assets/img/open.png"
              alt=""
              class="closedetail imageicon"
              @click="showVideo('back')"
            >
          </div>
          <!-- 直播视频 -->
          <div
            controls
            class="video_content"
            :class="videoShow == 'back' ? 'video_show' : 'video_hidden'"
          >
            <VideoPlayer id="live-video" ref="originRef" @video-status="handleVideoStatus" />
          </div>
        </div>
      </div>
    </n-drawer-content>
  </n-drawer>
</template>

<script>
import { defineComponent, computed, ref, reactive, toRefs, watch, nextTick } from 'vue'
import { Map, View, Feature } from 'ol'
import 'ol/ol.css'
import { Tile, Vector as VectorLayer } from 'ol/layer'
import LineString from 'ol/geom/LineString'
import Point from 'ol/geom/Point'
import { XYZ, Vector as VectorSource } from 'ol/source'
import { transform, fromLonLat } from 'ol/proj'
import { getVectorContext } from 'ol/render'
import VectorContext from 'ol/render/VectorContext'
import * as control from 'ol/control'
import { styleList } from '../tools/style.js'
import { getTrackList, getLineList } from '@/api/task/index.js'

// 视频组件
import VideoPlayer from '@/components/VideoPlayer/index.vue'
export default defineComponent({
  name: 'LiveDrawer',
  components: { VideoPlayer },
  props: {
    /* 可见 */
    visible: {
      type: Boolean,
      default: false
    },
    /* 选中的数据 */
    data: {
      type: Object,
      default: () => {}
    }
  },
  emits: {
    'update:visible': null
  },
  setup(props, { emit }) {
    const originRef = ref()
    const data = reactive({
      mapData: null,
      view: null,
      liveTrackLayer: null,
      lineTrackLayer: null,
      trackInfo: null,
      socket: null,
      // 预计航线数据
      lineTrajectoryList: [
        { lng: '118.765591', lat: '32.050993' },
        { lng: '118.665591', lat: '32.150993' },
        { lng: '118.565591', lat: '32.070993' },
        { lng: '118.465591', lat: '32.020993' },
        { lng: '118.365591', lat: '32.110993' },
        { lng: '118.265591', lat: '32.080993' },
        { lng: '118.165591', lat: '32.150993' },
        { lng: '118.765591', lat: '32.150993' },
        { lng: '118.66551', lat: '32.050993' },
        { lng: '118.365591', lat: '32.060993' },
        { lng: '118.265591', lat: '32.180993' },
        { lng: '118.165591', lat: '32.050993' }
      ],
      // 轨迹数据
      trackList: [
        { lng: '118.765591', lat: '32.050993' },
        { lng: '118.665591', lat: '32.150993' },
        { lng: '118.565591', lat: '32.070993' },
        { lng: '118.465591', lat: '32.020993' },
        { lng: '118.365591', lat: '32.110993' },
        { lng: '118.265591', lat: '32.080993' },
        { lng: '118.165591', lat: '32.150993' }
      ],
      disdance: null,
      animating: null,
      detailData: {},
      videoShow: 'back', // 视频展示开关

      videoInfo: {
        url: null,
        status: 'init'
      }
    })
    /* 获取抽屉的信息 */
    const getDrawerOptions = computed(() => {
      return {
        show: props.visible,
        width: '100%',
        placement: 'right'
      }
    })

    /* 初始化播放器 */
    function initOriginPlayer(islive) {
      data.videoInfo.status = 'init'
      const origin = {
        width: '100%',
        height: '446px',
        source: props.data.aiplayUrl,
        isLive: true
      }
      originRef.value?.init(origin)
      setTimeout(() => {
        if (data.videoInfo.status === 'init') {
          initOriginPlayer()
        }
      }, 30000)
    }

    function handleDrawerColse() {
      emit('update:visible', false)
    }

    /* 获取轨迹数据 */
    const getTrackData = async function() {
      const res = await getTrackList(props.data.id)
      const trackList = res.data
      data.trackList = trackList
      return Promise.resolve({
        trackList
      })
    }

    /* 获取航线数据 */
    const getLineData = async function() {
      const res = await getLineList(props.data.id)
      const trackList = res.data
      data.lineTrajectoryList = trackList
      return Promise.resolve({
        trackList
      })
    }

    watch(() => props.visible, (value) => {
      if (value) {
        nextTick(() => {
          if (data.videoInfo.status === 'init') {
            initOriginPlayer()
          }
          if (!data.mapData) {
            initMap()
            // 加载机场航线
            getLineData().then(({ trackList }) => {
              if (trackList.length > 0) {
                initTrack(formatTradeList(data.lineTrajectoryList), 'lineTrackLayer', 'lineRoute')
              }
            })
            // 加载历史轨迹和实时轨迹
            getTrackData().then(({ trackList }) => {
              setLiveTrack(formatTradeList(trackList))
            })
          }
        })
      } else {
        originRef.value?.disposeVideo()
        data.videoInfo = {
          url: null,
          status: 'init'
        }
        data.mapData = null
        clearInterval(data.socket)
        data.socket = null
      }
    }, { deep: true })

    /* 初始化地图 */
    const initMap = function() {
      const layers = [
        new Tile({
          visible: true,
          source: new XYZ({
            url: 'https://tianditu.t-aaron.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=f82bb2fd8115c7fb576a8b2fcf738523'
          })
        })
      ]

      data.view = new View({
        maxZoom: 18,
        zoom: 5,
        center: transform([118.837886, 32.057175], 'EPSG:4326', 'EPSG:3857')
      })
      data.mapData = new Map({
        layers: layers,
        target: 'live-map',
        view: data.view,
        controls: control.defaults({
          attribution: false,
          rotate: false,
          zoom: false
        })
      })
      data.mapData.render()
    }

    /* 处理轨迹列表 */
    const formatTradeList = function(trackList) {
      return trackList.map((item) =>
        fromLonLat([parseFloat(item.lng), parseFloat(item.lat)])
      )
    }

    /* 初始化轨迹 */
    const initTrack = function(coordinate, layer, routeType) {
      let vectorLayer = null
      const route = new LineString(coordinate)
      const routeFeature = new Feature({
        type: routeType,
        geometry: route
      })
      const endMarker = new Feature({
        type: 'icon',
        geometry: new Point(route.getLastCoordinate())
      })
      const position = endMarker.getGeometry().clone()
      if (routeType === 'route') { // 轨迹数据
        const geoMarker = new Feature({
          type: 'geoMarker',
          geometry: position
        })
        geoMarker.setProperties({ type: 'geoMarker' }, false)
        if (data.liveTrackLayer) {
          data.liveTrackLayer.setSource(
            new VectorSource({
              features: [geoMarker, routeFeature]
            })
          )
          vectorLayer = data.liveTrackLayer
        } else {
          vectorLayer = new VectorLayer({
            source: new VectorSource({
              features: [geoMarker, routeFeature]
            }),
            style: function(feature) {
              return styleList[feature.get('type')]
            }
          })
        }
        data[layer] = vectorLayer
        data.mapData.addLayer(data[layer])
        data.view.fit(route, { padding: [50, 50, 50, 50] })
        return {
          vectorLayer,
          geoMarker,
          route,
          position
        }
      } else { // 航线数据
        vectorLayer = new VectorLayer({
          source: new VectorSource({
            features: [routeFeature]
          }),
          style: function(feature) {
            return styleList[feature.get('type')]
          }
        })
        data[layer] = vectorLayer
        data.mapData.addLayer(data[layer])
        data.view.fit(route, { padding: [50, 50, 50, 50] })
      }
    }

    /* 加载实时轨迹 */
    const setLiveTrack = function(hisTrackList) {
      data.animating = false
      data.disdance = 0
      var changeTrack
      if (hisTrackList.length > 1) {
        data.trackInfo = initTrack(hisTrackList, 'liveTrackLayer', 'route')
        if (data.trackInfo.vectorLayer) {
          data.liveTrackLayer.on('change', changeTrack)
        }
      }

      /* 轨迹改变 */
      changeTrack = (event) => {
        try {
          const vectorContext = getVectorContext(event)
          vectorContext.setStyle(styleList['geoMarker'])
          VectorContext.drawGeometry(data.trackInfo.position)
          vectorContext.drawGeometry(data.trackInfo.route)
          data.mapData.render()
        } catch {
          console.log(event)
        }
      }

      // 两秒钟获取一次数据
      data.socket = setInterval(() => {
        getTrackData().then(({ trackList }) => {
          const obj = trackList[0]
          const coordinate = fromLonLat([obj?.lng, obj?.lat])
          if (data.trackInfo) {
            data.trackInfo.route.appendCoordinate(coordinate)
            data.trackInfo.vectorLayer.getSource().changed()
            data.trackInfo.position.setCoordinates(coordinate)
          }
        })
      }, 1000)

      // 移动要素
      const moveFeature = function(event) {
        var lastTime
        const speed = Number(50)
        const time = event.frameState.time
        const elapsedTime = time - lastTime
        data.disdance = (data.disdance + (speed * elapsedTime) / 1e6) % 2
        if (data.disdance > 1) {
          stopAnimation(data.trackInfo)
        }
        lastTime = time

        const currentCoordinate = data.trackInfo.route.getCoordinateAt(
          data.disdance > 1 ? 2 - data.disdance : data.disdance
        )
        data.trackInfo.position.setCoordinates(currentCoordinate)
        const vectorContext = getVectorContext(event)
        vectorContext.setStyle(styleList['geoMarker'])
        vectorContext.drawGeometry(data.trackInfo.position)
        data.mapData.render()
      }

      // 停止动画
      const stopAnimation = function(trackInfo) {
        const { vectorLayer, geoMarker } = trackInfo
        data.animating = false
        geoMarker.setGeometry(trackInfo.position)
        vectorLayer.un('postrender', moveFeature)
      }
    }

    function handleVideoStatus(status) {
      data.videoInfo = {
        ...data.videoInfo,
        status: status
      }
    }

    /* 视频窗口展开收起 */
    const showVideo = function(value) {
      data.videoShow = value
    }

    return {
      ...toRefs(data),
      originRef,
      getDrawerOptions,
      handleDrawerColse,
      handleVideoStatus,
      showVideo
    }
  }
})
</script>

<style scoped lang='scss'>
.n-button+.n-button{
  margin-left: 30px;
}
.main_container {
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
}
#live-map {
  width: 100%;
  height: 100%;
}
/* 视频 */
.videobox {
  width: 810px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-end;
  position: absolute;
  top: 10px;
  right: 10px;
}
.flagbox {
  width: 810px;
  height: 27px;
  background: #fff;
  padding: 0 10px;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
.flagbox_open {
  width: 810px;
  animation: openbox 1s;
}
.flaxbox_back {
  width: 116px;
  animation: backbox 1s;
}
@keyframes backbox {
  from {
    width: 810px;
  }
  to {
    width: 116px;
  }
}
@keyframes openbox {
  from {
    width: 116px;
  }
  to {
    width: 810px;
  }
}
.video_content {
  width: 810px;
  height: 220px;
  position: relative;
  display: flex;
  justify-content: space-between;
}

.video_show {
  opacity: 1;
  animation: showIt 1s;
}
@keyframes showIt {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.video_hidden {
  opacity: 0;
  animation: hiddenIt 1s;
}
@keyframes hiddenIt {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
.imageicon {
  width: 16px;
  height: 16px;
  margin-right: 10px;
}

</style>
