<template>
  <div class="timeAxis-component">
    <div class="time">{{ TansTimestamp(startTime, "YYYY.MM.DD HH:mm:ss") }}</div>
    <div class="axis" ref="axisRef" @pointerdown="handlePointerDown">
      <el-tooltip
        v-for="time in timeList"
        :key="time"
        :content="TansTimestamp(time, 'YYYY.MM.DD HH:mm:ss')"
        placement="bottom"
        effect="light"
      >
        <div
          class="time-section"
          :style="{ left: getTimeSectionLeft(time) + 'px' }"
          @pointerdown.stop="handleSectionPointerDown(time)"
        ></div>
      </el-tooltip>

      <div class="progress-bar" :style="trackStyle"></div>
      <div class="active-sign">
        <el-tooltip
          v-if="cursor"
          :content="TansTimestamp(cursor, 'YYYY.MM.DD HH:mm:ss')"
          placement="bottom"
          effect="light"
        >
          <div class="active-needle" :style="showHidden"></div>
        </el-tooltip>

        <el-tooltip
          :content="TansTimestamp(currentTime, 'YYYY.MM.DD HH:mm:ss')"
          placement="bottom"
          effect="light"
        >
          <div
            class="timeLine-point"
            @pointerdown.stop="handlePointPointerDown"
            :style="{ left: `${currentPosition - 9}px` }"
          ></div>
        </el-tooltip>
      </div>
    </div>
    <div class="time">{{ TansTimestamp(endTime, "YYYY.MM.DD HH:mm:ss") }}</div>
  </div>
</template>

<script setup>
import { ref, defineProps, defineEmits, computed, onUnmounted, onMounted, watch } from "vue"
import { TansTimestamp } from "@/utils/transform"

const props = defineProps({
  timeList: {
    type: Array,
    default: () => []
  },
  startTime: {
    //起始时间
    type: Date,
    default: new Date("2024-05-16 16:56:04")
  },
  endTime: {
    //结束时间
    type: Date,
    default: new Date("2024-05-23 10:16:56")
  },
  initPosition: {
    //初始位置
    type: Number,
    default: 0
  },
  cursor: {
    //初始时，游标标出指定的时间
    type: Date,
    default: null
  },
  isAutoPlay: {
    //创建组件后，是否自动播放
    type: Boolean,
    default: true
  }
})

const startTime = ref(props.startTime) //开始时间
const endTime = ref(props.endTime) //结束时间
const timeList = ref(props.timeList) //时间列表
const currentTime = ref(new Date("2024-05-16 16:56:04")) // 当前选中的时间
const currentPosition = ref(props.initPosition) // 初始位置
const isPlaying = ref(props.isAutoPlay) // 是否自动播放
const axisRef = ref(null) // 轴的引用
const isDragging = ref(false) // 是否正在拖动
const axisWidth = 415 // 轴的长度(px)
const startTimeMs = startTime.value.getTime() // 起始时间的毫秒数
const endTimeMs = endTime.value.getTime() // 结束时间的毫秒数
const totalDuration = endTimeMs - startTimeMs // 计算总持续时间
const step = 4 // 每次移动的像素数(px)
let playTimer = null // 自动播放定时器

const emit = defineEmits(["click:pointerDown", "slide:pointerUp"])

// 计算进度条的样式
const trackStyle = computed(() => {
  const progressPercent = Math.min(100, (currentPosition.value / axisWidth) * 100)
  return {
    background: `linear-gradient(90deg, #00F3FF 0%, #00F3FF ${progressPercent}%, #3B7699 ${progressPercent}%, #3B7699 100%)`,
    width: "100%"
  }
})

//点击用户组列表后，显示这两个用户的交互时间切片，获得每一个时间距离时间轴初始位置的距离
const getTimeSectionLeft = computed(() => {
  return (time) => {
    const total = endTime.value.getTime() - startTime.value.getTime()
    const offset = new Date(time).getTime() - startTime.value.getTime()
    return Math.max(0, Math.min(axisWidth, (offset / total) * axisWidth))
  }
})

// 监听 props.timeList 的变化，更新 timeList
watch(
  () => props.timeList,
  (newVal) => {
    timeList.value = newVal
  },
  { deep: true }
)
// 让 active-needle 标定在 timeList 最后一个时间点
const showHidden = computed(() => {
  if (!timeList.value || timeList.value.length === 0) return {}
  const left = getTimeSectionLeft.value(timeList.value[timeList.value.length - 1]) + 5 // +5px 保持和 time-section 对齐
  return { left: `${left}px` }
})

//自动播放暂停处理函数
const pause = () => {
  if (!isPlaying.value) return
  isPlaying.value = false
  if (playTimer) {
    clearInterval(playTimer)
    playTimer = null
  }
}

// 自动播放控制
const play = () => {
  if (!isPlaying.value) return
  playTimer = setInterval(() => {
    if (currentPosition.value >= axisWidth) {
      pause()
      return
    }
    currentPosition.value = Math.min(axisWidth, currentPosition.value + step)
    currentTime.value = getTimeFromPosition(currentPosition.value)
    emit("slide:pointerUp", currentTime.value)
  }, 300) // 每300ms移动一次
}

// 根据位置计算时间
const getTimeFromPosition = (position) => {
  const ratio = Math.max(0, Math.min(1, position / axisWidth))
  const timeOffset = totalDuration * ratio
  return TansTimestamp(startTimeMs + timeOffset, "YYYY-MM-DD HH:mm:ss")
}

// 在时间轴上点击任意时间
const handlePointerDown = (e) => {
  if (e.target.classList.contains("timeLine-point")) return
  pause() // 拖动或点击时暂停自动播放
  const rect = axisRef.value.getBoundingClientRect()
  const position = Math.max(0, Math.min(axisWidth, e.clientX - rect.left))
  currentPosition.value = position
  currentTime.value = getTimeFromPosition(position)
  emit("click:pointerDown", currentTime.value) //在父组中件发送请求
}

// 时间点指针按下事件
const handlePointPointerDown = (e) => {
  e.stopPropagation()
  e.preventDefault()
  isDragging.value = true
  // 缓存轴的边界矩形，避免重复计算
  const rect = axisRef.value.getBoundingClientRect()
  const axisLeft = rect.left

  const handlePointerMove = (e) => {
    if (!isDragging.value) return
    const position = Math.max(0, Math.min(axisWidth, e.clientX - axisLeft))

    // 直接更新位置，不检查阈值，确保实时响应
    currentPosition.value = position
    currentTime.value = getTimeFromPosition(position)
  }

  //拖动时，鼠标松开时
  const handlePointerUp = () => {
    isDragging.value = false
    // 拖动结束时输出当前时间
    pause() // 拖动或点击时暂停自动播放
    const currentTimes = TansTimestamp(currentTime.value, "YYYY-MM-DD HH:mm:ss")

    emit("slide:pointerUp", currentTimes)

    document.removeEventListener("pointermove", handlePointerMove)
    document.removeEventListener("pointerup", handlePointerUp)
  }

  document.addEventListener("pointermove", handlePointerMove, { passive: true })
  document.addEventListener("pointerup", handlePointerUp)
}

// 点击时间段时的处理函数
const timeSectionWidth = 4 // 与样式保持一致
const handleSectionPointerDown = (time) => {
  pause()
  // 计算该时间点的中心位置
  const left = getTimeSectionLeft.value(time) + timeSectionWidth / 2
  currentPosition.value = left
  currentTime.value = TansTimestamp(new Date(time), "YYYY-MM-DD HH:mm:ss")
  emit("click:pointerDown", currentTime.value)
}

//重置时间轴
const reset = () => {
  currentPosition.value = props.initPosition
  currentTime.value = getTimeFromPosition(props.initPosition)
  // 清理旧定时器
  pause()
  // 重新开始播放
  if (props.isAutoPlay) {
    isPlaying.value = true
    play()
  }
}
onMounted(() => {
  play()
})
// 组件卸载时清理事件监听器
onUnmounted(() => {
  document.removeEventListener("pointermove", () => {})
  document.removeEventListener("pointerup", () => {})
  pause()
})

defineExpose({
  reset
})
</script>

<style scoped lang="less">
.timeAxis-component {
  width: 100%;
  height: 100%;
  background: linear-gradient(270deg, rgba(0, 82, 125, 0.48) 0%, rgba(0, 200, 255, 0.23) 100%);
  backdrop-filter: blur(3px);
  border: 1px solid #3aa1f8;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: #fff;
  padding: 0 10px;
  touch-action: none; // 防止触摸设备上的默认行为
  .time {
    font-family: "PingFang SC";
    font-size: 16px;
    font-style: normal;
    font-weight: 400;
    line-height: normal;
  }
  .axis {
    width: 426px;
    height: 6px;
    border-radius: 20px;
    background-color: #3b7699;
    cursor: pointer;
    transform: translateZ(0); // 启用硬件加速
    position: relative;
    top: 2px;
    .time-section {
      position: absolute;
      top: -8px;
      width: 4px;
      height: 22px;
      background: #ffe066;
      border-radius: 3px;
      z-index: 3;
    }
    .progress-bar {
      position: absolute;
      top: 0;
      left: 0;
      height: 6px;
      background-color: #00ecf9;
      border-radius: 20px;
      z-index: 1;
    }
    .active-sign {
      position: relative;
      z-index: 2;
      .active-needle {
        width: 30px;
        height: 34px;
        background-image: url("@/assets/images/point.png");
        background-size: cover;
        bottom: -8px;
        left: -11px;
        position: absolute;
      }
      .timeLine-point {
        width: 18px;
        height: 18px;
        background-color: transparent;
        border-radius: 50%;
        border: 1.6px solid #ffe5a4;
        position: absolute;
        display: flex;
        align-items: center;
        justify-content: center;
        top: -6px;
        left: -5px;
        cursor: pointer;
        user-select: none;
        will-change: left;
        transform: translate3d(0, 0, 0); // 强制启用硬件加速
        &:hover {
          transform: translate3d(0, 0, 0) scale(1.1);
        }
        &:active {
          transform: translate3d(0, 0, 0) scale(0.95);
        }
        &::after {
          content: "";
          width: 10px;
          height: 10px;
          background-color: #f9bd25;
          border-radius: 50%;
          position: absolute;
        }
      }
    }
  }
}
</style>
