<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" v-if="hasTrackData">
        <el-button
          size="small"
          type="primary"
          @click="startAnimation()"
          :disabled="isPlaying"
          >开始动画</el-button
        >
        <el-button
          size="small"
          type="warning"
          @click="pauseAnimation()"
          :disabled="!isPlaying"
          >暂停动画</el-button
        >
        <el-button
          size="small"
          type="success"
          @click="resumeAnimation()"
          :disabled="isPlaying"
          >继续动画</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'
export default {
  name: 'TrackPlaybackPage',
  components: {},
  data() {
    return {
      trackData: {},
      mapLoading: false,
      map: null,
      center: [106.504962, 29.533155], // 重庆市中心
      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,
      mapContainer: null,
      hasTrackData: false,
      isPlaying: false // 是否播放中
    }
  },
  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() {
      if (!this.mapContainer) {
        this.mapContainer = document.getElementById('mapContainer')
      }
      const card = document.querySelector('.info-card')
      if (this.mapContainer && card) {
        this.containerWidth = this.mapContainer.offsetWidth
        this.containerHeight = this.mapContainer.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
      // 清理之前的数据
      this.clearTrackData()
      
      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.hasTrackData = true
        } else {
          this.$message.warning('暂无轨迹数据')
          this.lineArr = []
          this.hasTrackData = false
        }
        this.initMap()
        if (this.lineArr.length > 0) {
          this.initTrackPlayback()
        }
      }).catch(err => {
        console.error('获取轨迹数据失败:', err)
        this.$message.error('获取轨迹数据失败，显示默认地图')
        this.lineArr = []
        this.hasTrackData = false
        this.initMap()
      }).finally(() => {
        this.mapLoading = false
      })
    },
    dragStart(e) {
      if (this.containerWidth === 0 || this.cardWidth === 0) {
        this.updateContainerSize()
      }

      if (!this.mapContainer) {
        this.mapContainer = document.getElementById('mapContainer')
      }

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

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

      document.addEventListener('mousemove', this.onDragMove)
      document.addEventListener('mouseup', this.onDragEnd)
      e.preventDefault()
    },
    onDragMove(e) {
      if (!this.isDragging || !this.mapContainer) return

      const containerRect = this.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))
      }
    },
    onDragEnd() {
      this.isDragging = false
      document.body.style.cursor = ''
      document.body.style.userSelect = ''
      document.removeEventListener('mousemove', this.onDragMove)
      document.removeEventListener('mouseup', this.onDragEnd)
    },
    clearTrackData() {
      // 停止动画并清理地图上的轨迹元素
      if (this.map) {
        if (this.marker) {
          // 停止正在进行的动画
          this.marker.stopMove()
          this.marker.setMap(null)
          this.marker = null
        }
        if (this.polyline) {
          this.polyline.setMap(null)
          this.polyline = null
        }
        if (this.passedPolyline) {
          this.passedPolyline.setMap(null)
          this.passedPolyline = null
        }
        this.map.destroy()
        this.map = null
      }
      // 重置状态
      this.isPlaying = false
    },
    initMap() {
      this.map = new AMap.Map('mapContainer', {
        resizeEnable: true,
        center: this.center,
        zoom: this.zoom,
        mapStyle: 'amap://styles/darkblue'
      })
    },
    initTrackPlayback() {
      if (!this.map || !this.lineArr.length) return
      
      // 确保marker从起点开始
      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,
        path: [] // 初始化为空路径
      })

      this.marker.on('moving', e => {
        if (this.passedPolyline) {
          this.passedPolyline.setPath(e.passedPath)
        }
      })

      // 监听动画结束事件
      this.marker.on('moveend', () => {
        this.isPlaying = false
      })

      this.map.setFitView([this.polyline], false)
    },
    startAnimation() {
      if (!this.marker || !this.lineArr.length) {
        this.$message.warning('轨迹数据未加载完成')
        return
      }
      
      // 重置到起点位置，避免闪烁
      this.marker.setPosition(this.lineArr[0])
      if (this.passedPolyline) {
        this.passedPolyline.setPath([])
      }
      
      this.isPlaying = true
      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.isPlaying = false
      if (this.marker) {
        this.marker.pauseMove()
      }
    },
    resumeAnimation() {
      if (!this.marker) return
      this.isPlaying = true
      this.marker.resumeMove()
    },
    stopAnimation() {
      this.isPlaying = false
      if (this.marker) {
        this.marker.stopMove()
        // 重置到起点
        if (this.lineArr.length > 0) {
          this.marker.setPosition(this.lineArr[0])
        }
      }
      // 清空已走路径
      if (this.passedPolyline) {
        this.passedPolyline.setPath([])
      }
    },
  },
  beforeDestroy() {
    this.clearTrackData()
    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>
