<template>
  <div ref="dragRef"
       :style="style"
       class="fixed rounded-5px overflow-hidden shadow-lg cursor-move z-50"
       @mousedown.stop="handleDragStart"
       @touchstart.stop="handleDragStart">
    <div class="relative" @click.stop="handleClick">
      <img :src="props.snapshot"
           class="w-80px object-cover"
           alt="直播画面">

      <div class="absolute inset-0 bg-black/40 flex items-center justify-center"
           >
        <span class="text-white text-12px">点击回到直播</span>
      </div>
      <button @click.stop="handleClose"
              class="absolute top-10px right-10px text-white bg-black/40 rounded-full w-5 h-5 flex items-center justify-center hover:bg-black/60 cursor-pointer">
        <van-icon name="cross" />
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onBeforeUnmount, shallowRef, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useThrottleFn } from '@vueuse/core'

const props = defineProps({
  snapshot: {
    type: String,
    required: true
  },
  onClose: {
    type: Function,
    default: () => {}
  },
  onClick: {
    type: Function,
    default: () => {}
  },
  initialPosition: {
    type: Object,
    default: () => ({
      top: '80px',
      right: '16px'
    })
  }
})

const router = useRouter()
const dragRef = shallowRef(null)
const route = useRoute()

const isDragging = ref(false)
const startX = ref(0)
const startY = ref(0)
const left = ref(0)
const top = ref(0)

onMounted(() => {
  const rect = dragRef.value.getBoundingClientRect()
  left.value = window.innerWidth - rect.width - parseInt(props.initialPosition.right)
  top.value = parseInt(props.initialPosition.top)
})

const style = computed(() => ({
  left: left.value ? `${left.value}px` : 'auto',
  top: top.value ? `${top.value}px` : 'auto',
  right: !left.value ? props.initialPosition.right : 'auto',
  transition: isDragging.value ? 'none' : 'all 0.3s ease',
}))

const handleDragStart = (event) => {
  event.stopPropagation()
  isDragging.value = true

  const point = event.touches ? event.touches[0] : event

  const rect = dragRef.value.getBoundingClientRect()
  left.value = rect.left
  top.value = rect.top

  startX.value = point.clientX - left.value
  startY.value = point.clientY - top.value

  if (event.type === 'mousedown') {
    document.addEventListener('mousemove', handleDragMove)
    document.addEventListener('mouseup', handleDragEnd)
  } else {
    document.addEventListener('touchmove', handleDragMove, { passive: false })
    document.addEventListener('touchend', handleDragEnd)
  }
}

const handleDragMove = useThrottleFn((event) => {
  if (!isDragging.value) return

  event.preventDefault()
  event.stopPropagation()

  const point = event.touches ? event.touches[0] : event
  const rect = dragRef.value.getBoundingClientRect()
  const maxX = window.innerWidth - rect.width
  const maxY = window.innerHeight - rect.height

  left.value = Math.min(Math.max(0, point.clientX - startX.value), maxX)
  top.value = Math.min(Math.max(0, point.clientY - startY.value), maxY)
}, 16)

const handleEdgeSnap = useThrottleFn(() => {
  const rect = dragRef.value.getBoundingClientRect()
  const centerX = rect.left + rect.width / 2

  left.value = centerX > window.innerWidth / 2
    ? window.innerWidth - rect.width - 16
    : 16
}, 100)

const handleDragEnd = () => {
  if (!isDragging.value) return

  isDragging.value = false
  handleEdgeSnap()

  document.removeEventListener('mousemove', handleDragMove)
  document.removeEventListener('mouseup', handleDragEnd)
  document.removeEventListener('touchmove', handleDragMove)
  document.removeEventListener('touchend', handleDragEnd)
}

const handleClick = (event) => {
  event.stopPropagation()
  if (!isDragging.value) {
    handleReturnLive()
  }
}
const handleReturnLive = () => {
  props.onClick()
}

const handleClose = (event) => {
  event?.stopPropagation()
  props.onClose()
}
watch(() => route.path, (newVal) => {
  if (['/','/home'].includes(newVal)){
    handleClose()
  }
})
onBeforeUnmount(() => {
  document.removeEventListener('mousemove', handleDragMove)
  document.removeEventListener('mouseup', handleDragEnd)
  document.removeEventListener('touchmove', handleDragMove)
  document.removeEventListener('touchend', handleDragEnd)
})
</script>
<style scoped>
.fixed {
  will-change: transform, opacity;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  transform: translateZ(0);
}

.min-window-enter-active,
.min-window-leave-active {
  transition: transform 0.3s ease, opacity 0.3s ease;
}

.min-window-enter-from,
.min-window-leave-to {
  transform: translateY(100%);
  opacity: 0;
}

img {
  pointer-events: none;
  -webkit-user-drag: none;
  user-drag: none;
}
</style>