<template>
  <div class="map-playback">
    <div id="mapContainer" v-loading="mapLoading"></div>
    <div class="info-card" @mousedown="dragStart" :style="cardStyle">
      <div class="info-item drag-handle" style="cursor: move;">
        <div>所属路段： {{ trackData.roadName || '-' }}</div>
        <div>巡检队伍： {{ trackData.teamName || '-' }}</div>
        <div>开始巡检站： {{ trackData.startPatrolName || '-' }}</div>
        <div>结束巡检站： {{ trackData.endPatrolName || '-' }}</div>
        <div>巡检开始时间： {{ trackData.startTime || '-' }}</div>
        <div>巡检结束时间： {{ trackData.endTime || '-' }}</div>
        <div>巡检人： {{ trackData.inspectUsersName || '-' }}</div>
        <div>应打卡点： {{ trackData.requestPoint || '-' }}</div>
        <div>上报点： {{ trackData.reportingPoint || '-' }}</div>
        <div>固定点： {{ trackData.fixedPoint || '-' }}</div>
        <div>临时点： {{ trackData.tempPoint || '-' }}</div>
        <div>异常点： {{ trackData.outlierPoint || '-' }}</div>
      </div>
      <div class="info-item">
        <el-button size="small" type="primary" @click="startAnimation()"
          >开始动画</el-button
        >
        <el-button size="small" type="warning" @click="pauseAnimation()"
          >暂停动画</el-button
        >
        <el-button size="small" type="primary" @click="resumeAnimation()"
          >继续动画</el-button
        >
        <el-button size="small" type="danger" @click="stopAnimation()"
          >停止动画</el-button
        >
      </div>
    </div>
  </div>
</template>

<script>
import PubSub from 'pubsub-js'
import {getInspectionTask} from '@/api/patrolAndRescue/roadWatch/inspectionResults'
import carImage from '@/assets/img/patrolAndRescue/car.png'
import {lazyAMapApiLoaderInstance} from 'vue-amap'
const lineArr = [
  [106.550709, 29.605874],
  [106.550454, 29.605927],
  [106.550031, 29.605945],
  [106.549714, 29.605955],
  [106.549349, 29.606034],
  [106.549258, 29.606244],
  [106.549124, 29.606668],
  [106.549011, 29.606836],
  [106.548486, 29.606976],
  [106.548183, 29.606976],
  [106.547749, 29.60678],
  [106.547604, 29.606454],
  [106.547491, 29.605745],
  [106.547475, 29.60511],
  [106.547271, 29.604709],
  [106.547169, 29.604672],
  [106.546815, 29.604681],
  [106.54608, 29.6047055],
  [106.545571, 29.604714],
  [106.544568, 29.604737]
]
export default {
  name: 'TrackPlaybackPage',
  components: {},
  data() {
    return {
      trackData: {},
      mapLoading: false,
      map: null,
      center: [106.551514, 29.606449],
      zoom: 14,
      marker: null,
      isDragging: false,
      startPosition: {x: 0, y: 0},
      cardPosition: {x: 20, y: 20},
      containerWidth: 0,
      containerHeight: 0,
      cardWidth: 0,
      cardHeight: 0,
      lineArr: [],
      polyline: null,
      passedPolyline: null
    }
  },
  mounted() {
    this.pubSub = PubSub.subscribe('TrackPlaybackPage', (_, data) => {
      this.trackData = data
      this.getPoints()
    })

    this.$nextTick(() => {
      lazyAMapApiLoaderInstance.load().then(() => {
        setTimeout(() => {
          this.updateContainerSize()
        }, 100)
      })
      window.addEventListener('resize', this.updateContainerSize)
    })
  },
  computed: {
    cardStyle() {
      return {
        position: 'absolute',
        left: `${this.cardPosition.x}px`,
        top: `${this.cardPosition.y}px`,
        cursor: this.isDragging ? 'grabbing' : 'grab',
        userSelect: 'none'
      }
    }
  },
  methods: {
    updateContainerSize() {
      const container = document.getElementById('mapContainer')
      const card = document.querySelector('.info-card')
      if (container && card) {
        this.containerWidth = container.offsetWidth
        this.containerHeight = container.offsetHeight
        this.cardWidth = card.offsetWidth
        this.cardHeight = card.offsetHeight
        this.constrainCardPosition()
      }
    },
    constrainCardPosition() {
      const maxX = Math.max(0, this.containerWidth - this.cardWidth - 20)
      const maxY = Math.max(0, this.containerHeight - this.cardHeight - 20)
      this.cardPosition.x = Math.max(20, Math.min(maxX, this.cardPosition.x))
      this.cardPosition.y = Math.max(20, Math.min(maxY, this.cardPosition.y))
    },
    getPoints() {
      this.mapLoading = true
      getInspectionTask({
        endTime: this.trackData.endTime,
        startTime: this.trackData.startTime,
        eventId: this.trackData.id
      }).then(res => {
        const points = res.value.trackPointDetails
        if (points && points.length > 0) {
          this.lineArr = points.map(point => [point.longitudeGcj02, point.latitudeGcj02])
          this.center = this.lineArr[0]
          this.initMap()
          this.initTrackPlayback()
        }
      }).finally(() => {
        this.mapLoading = false
      })
    },
    dragStart(e) {
      if (this.containerWidth === 0 || this.cardWidth === 0) {
        this.updateContainerSize()
      }

      this.isDragging = true
      document.body.style.cursor = 'grabbing'
      document.body.style.userSelect = 'none'

      const containerRect = document
        .getElementById('mapContainer')
        .getBoundingClientRect()
      this.startPosition = {
        x: e.clientX - containerRect.left - this.cardPosition.x,
        y: e.clientY - containerRect.top - this.cardPosition.y
      }

      document.addEventListener('mousemove', this.handleDocumentDragMove)
      document.addEventListener('mouseup', this.handleDocumentDragEnd)
      e.preventDefault()
    },
    dragMove(e) {
      if (!this.isDragging) return

      const containerRect = document
        .getElementById('mapContainer')
        .getBoundingClientRect()
      const newX = e.clientX - containerRect.left - this.startPosition.x
      const newY = e.clientY - containerRect.top - this.startPosition.y

      // 边界检测
      const maxX = Math.max(0, this.containerWidth - this.cardWidth - 20)
      const maxY = Math.max(0, this.containerHeight - this.cardHeight - 20)

      this.cardPosition = {
        x: Math.max(20, Math.min(maxX, newX)),
        y: Math.max(20, Math.min(maxY, newY))
      }
    },
    dragEnd() {
      this.isDragging = false
      document.body.style.cursor = ''
      document.body.style.userSelect = ''
    },
    handleDocumentDragMove(e) {
      this.dragMove(e)
    },
    handleDocumentDragEnd() {
      this.dragEnd()
      document.removeEventListener('mousemove', this.handleDocumentDragMove)
      document.removeEventListener('mouseup', this.handleDocumentDragEnd)
    },
    initMap() {
      this.map = new AMap.Map('mapContainer', {
        resizeEnable: true,
        center: this.center,
        zoom: this.zoom,
        layers: [new AMap.TileLayer()]
      })
    },
    initTrackPlayback() {
      if (!this.map || !this.lineArr.length) return
      
      this.marker = new AMap.Marker({
        map: this.map,
        position: this.lineArr[0],
        icon: carImage,
        offset: new AMap.Pixel(-13, -26)
      })

      this.polyline = new AMap.Polyline({
        map: this.map,
        path: this.lineArr,
        showDir: true,
        strokeColor: '#28F',
        strokeWeight: 6
      })

      this.passedPolyline = new AMap.Polyline({
        map: this.map,
        strokeColor: '#AF5',
        strokeWeight: 6
      })

      this.marker.on('moving', e => {
        this.passedPolyline.setPath(e.passedPath)
      })
      
      this.map.setFitView([this.polyline], false)
    },
    startAnimation() {
      if (!this.marker || !this.lineArr.length) {
        this.$message.warning('轨迹数据未加载完成')
        return
      }
      AMap.plugin('AMap.MoveAnimation', () => {
        const path = this.lineArr.map(point => new AMap.LngLat(point[0], point[1]))
        this.marker.moveAlong(path, {
          duration: 100,
          autoRotation: true
        })
      })
    },
    pauseAnimation() {
      this.marker.pauseMove()
    },
    resumeAnimation() {
      this.marker.resumeMove()
    },
    stopAnimation() {
      this.marker.stopMove()
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.updateContainerSize)
    if (this.pubSub) {
      PubSub.unsubscribe(this.pubSub)
    }
  }
}
</script>

<style lang="scss" scoped>
.map-playback {
  position: relative;
  height: calc(100% - 40px);
  width: calc(100% - 40px);
  margin: 20px;
  box-sizing: border-box;
  #mapContainer {
    width: 100%;
    height: 100%;
  }
  .info-card {
    position: absolute;
    top: 20px;
    left: 20px;
    z-index: 1;
    background-color: rgba(17, 64, 102, 0.9);
    border-radius: 10px;
    padding: 20px;
    box-sizing: border-box;
    width: 600px;
    .info-item {
      display: flex;
      flex-wrap: wrap;
      gap: 10px;
      justify-content: space-between;
      div {
        width: calc(50% - 5px);
        color: #fff;
        font-size: 14px;
        margin-bottom: 5px;
      }
      button {
        margin-top: 10px;
      }
    }
  }
}
</style>
