<template>
  <div
    class="custom-scrollbar-track"
    ref="track"
    @click="jumpToPosition"
    :class="[act ? 'act' : 'disabled']"
  >
    <div :class="['tip', holeType]">
      {{ holeTypeName }}
    </div>
    <!-- 滑块 -->
    <div class="custom-scrollbar-thumb" ref="thumb" @mousedown="startDrag">
      <span class="bg"></span>
    </div>
    <!-- 车流 -->
    <div :class="['cars', direction ? 'out' : 'in']">
      <div v-for="item in cars" :key="item.id" class="car" :style="item.style"> </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { useAppStoreWithOut } from '@/store/modules/app'
import { Car } from '@/views/traffic/roads/Engine/index'
import { ASYNC_DIRECTIONS } from '@/config/dict'

const props = withDefaults(
  defineProps<{
    traffic: any // 车流引擎
    direction: number
    act?: boolean
    holeType: string // 新洞/老洞（new/old）
  }>(),
  {
    isDownCtrls: false,
    act: true
  }
)

const emits = defineEmits(['space-axis-scroll', 'drag-end'])

const appStore = useAppStoreWithOut()

const thumb = ref<HTMLDivElement | null>(null)
const track = ref<HTMLDivElement | null>(null)
let engine: any = null // 动画引擎

const holeTypeName = computed(() => {
  const holeName = ASYNC_DIRECTIONS()[props.direction].name
  return holeName + (props.holeType === 'new' ? '新洞' : '老洞')
})

const scrollContainerWidth = computed(() => {
  let _sections = props.traffic?.sectionsCompute()
  if (!_sections) return 0
  return (_sections.length - 1 + _sections.slice(-1)[0]?.grow) * appStore.getDesign
})

// 车流
const cars = computed(() => {
  
  // 新洞还没接，后续接好后需要去掉 start
  if(props.holeType === 'new') return []
  // 新洞还没接，后续接好后需要去掉 end

  if (!props.traffic || !props.act) return []

  const { cars, miles } = props.traffic

  const _cars = cars
    .filter((item) => item.distance <= miles)
    .map((item) => {
      return new Car({
        ratex: appStore.getDesign / miles,
        id: item.id,
        type: item.type,
        speed: item.speed,
        distance: item.distance,
        line: item.line,
        direction: item.direction,
        plate: item.plate,
        originalCar: item.originalCar,
        car_length: 6,
        car_width: 6,
        lanes: [4, 12]
      })
    })
  return _cars
})

// 新增动画循环
const animate = () => {
  cars.value.forEach((car) => {
    car.run() // 更新每辆车的位置
  })
  engine = requestAnimationFrame(animate)
}

const stopAnimate = () => {
  if (engine) {
    cancelAnimationFrame(engine)
  }
}

let isDragging = false

// 计算滑块宽度
const updateThumbWidth = () => {
  if (!thumb.value || !track.value) return
  const visibleWidth = track.value.clientWidth
  const thumbWidth = (visibleWidth / scrollContainerWidth.value) * visibleWidth
  thumb.value.style.width = `${thumbWidth}px`
}

// 更新滑块位置
const updateThumb = ({ scrollLeft }) => {
  if (!thumb.value || !track.value) return
  const trackWidth = track.value.clientWidth
  const thumbWidth = thumb.value.clientWidth
  const maxLeft = trackWidth - thumbWidth
  const thumbLeft = (scrollLeft / scrollContainerWidth.value) * trackWidth
  thumb.value.style.left = `${Math.min(thumbLeft, maxLeft)}px`
}

// 点击轨道跳转
const jumpToPosition = (e) => {
  if (!track.value || !thumb.value) return
  const trackWidth = track.value.clientWidth
  const trackRect = track.value.getBoundingClientRect()
  const clickPosition = e.clientX - trackRect.left
  const thumbWidth = thumb.value.clientWidth
  // 点击位置需要先进行缩放
  const clickPositionCenter = clickPosition / appStore.zoom - thumbWidth / 2
  const contentToTrackRatio = clickPositionCenter / trackWidth
  const scrollLeft = contentToTrackRatio * scrollContainerWidth.value
  emits('space-axis-scroll', scrollLeft)
  emits('drag-end', scrollLeft)
}

// 拖动滑块
const startDrag = (e) => {
  e.preventDefault()
  isDragging = true
  const startX = e.clientX
  const startLeft = parseFloat(thumb.value?.style.left || '0')
  let actualScrollLeft = 0

  const moveHandler = (e) => {
    if (!isDragging || !thumb.value || !track.value) return
    // 拖动需要先进行缩放
    const deltaX = (e.clientX - startX) / appStore.zoom
    const newLeft = Math.min(
      Math.max(0, startLeft + deltaX),
      track.value.clientWidth - thumb.value.clientWidth
    )
    thumb.value.style.left = `${newLeft}px`
    const contentToTrackRatio = scrollContainerWidth.value / track.value.clientWidth
    actualScrollLeft = newLeft * contentToTrackRatio

    emits('space-axis-scroll', actualScrollLeft)
  }

  const upHandler = () => {
    isDragging = false
    emits('drag-end', actualScrollLeft)
    document.removeEventListener('mousemove', moveHandler)
    document.removeEventListener('mouseup', upHandler)
  }

  document.addEventListener('mousemove', moveHandler)
  document.addEventListener('mouseup', upHandler)
}

// 设置滑块位置
const setThumbPosition = (scrollLeft: number) => {
  if (!thumb.value) return
  thumb.value.style.left = `${scrollLeft}px`
}

watch(
  scrollContainerWidth,
  (e) => {
    updateThumbWidth()
  },
  { immediate: true }
)

onMounted(() => {
  //   updateThumbWidth()
  animate()
})

onUnmounted(() => {
  stopAnimate()
})

defineExpose({
  updateThumb,
  setThumbPosition
})
</script>

<style lang="scss" scoped>
$base-url: '@/assets/images/section/';

.custom-scrollbar-track {
  position: relative;
  // right: 0;
  // top: 0;
  width: 100%;
  height: 16px;
  background: #486794;
  border-radius: 5px;
  margin-bottom: 4px;
  &.disabled {
    opacity: 0.3;
    pointer-events: none;
  }

  .tip {
    font-size: 14px;
    font-weight: normal;
    line-height: 14px;
    letter-spacing: 0.5em;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.75;
    cursor: default;
    &::before {
      display: inline-block;
      content: '';
      margin-right: 10px;
      width: 11px;
      height: 12px;
      background: url($base-url + 'hole-icon.png') no-repeat;
      background-size: cover;
    }
  }

  .custom-scrollbar-thumb {
    position: absolute;
    top: 0;
    left: 0;
    width: 110px;
    height: 100%;
    cursor: pointer;
    transition: opacity 0.2s;
    display: flex;
    align-items: center;
    justify-content: space-between;
    opacity: 0.65;
    .bg {
      flex-grow: 1;
      height: 100%;
      margin: 0 2px;
      background: rgba(255, 255, 255, 0.25);
    }
    &::before,
    &::after {
      display: inline-block;
      content: '';
      width: 0;
      height: 0;
      border-top: 5px solid transparent;
      border-bottom: 5px solid transparent;
      border-right: 5px solid #fff;
    }
    &::after {
      border-left: 5px solid #fff;
      border-right: none;
    }
  }

  .custom-scrollbar-thumb:hover {
    opacity: 1;
  }

  .cars {
    .car {
      position: absolute;
      width: 6px;
      height: 6px;
      border-radius: 2px;
      background: #0bc7fa;
    }
    &.in {
      .car {
        right: 0px;
        bottom: 0px;
      }
    }

    &.out {
      .car {
        left: 0px;
        top: 0px;
      }
    }
  }
}
</style>
