<template>
  <div 
    ref="bubbleRef"
    class="floating-bubble"
    :style="bubbleStyle"
    @touchstart="onTouchStart"
    @touchmove="onTouchMove"
    @touchend="onTouchEnd"
  >
    <slot></slot>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { useThrottleFn } from '@vueuse/core'

const props = defineProps({
  offset: {
    type: Number,
    default: 0
  }
})

const bubbleRef = ref(null)
const position = ref({
  right: props.offset,
  bottom: 100
})

let startTouch = { x: 0, y: 0 }
let startPos = { right: 0, bottom: 0 }
let isDragging = false

const bubbleStyle = computed(() => ({
  position: 'fixed',
  right: `${position.value.right}px`,
  bottom: `${position.value.bottom}px`,
  zIndex: 99999,
  transition: isDragging ? 'none' : 'all 0.3s'
}))

const onTouchStart = (event) => {
  isDragging = true
  const touch = event.touches[0]
  startTouch = { x: touch.clientX, y: touch.clientY }
  startPos = { ...position.value }
}

const onTouchMove = useThrottleFn((event) => {
  if (!isDragging) return
  event.preventDefault()
  
  const touch = event.touches[0]
  const { clientWidth, clientHeight } = document.documentElement
  const rect = bubbleRef.value.getBoundingClientRect()
  
  // 计算新位置
  const deltaX = startTouch.x - touch.clientX
  const deltaY = startTouch.y - touch.clientY
  const newRight = startPos.right + deltaX
  const newBottom = startPos.bottom + deltaY
  
  // 边界检测
  position.value = {
    right: Math.min(Math.max(newRight, props.offset), 
           clientWidth - rect.width - props.offset),
    bottom: Math.min(Math.max(newBottom, props.offset), 
            clientHeight - rect.height - props.offset)
  }
}, 16)

const onTouchEnd = () => {
  if (!isDragging) return
  isDragging = false
  
  const { clientWidth } = document.documentElement
  const rect = bubbleRef.value.getBoundingClientRect()
  const left = clientWidth - position.value.right - rect.width
  
  // 吸附
  position.value.right = left < clientWidth / 2
    ? clientWidth - rect.width - props.offset
    : props.offset
}
</script>

<style scoped>
.floating-bubble {
  touch-action: none;
  user-select: none;
}
</style>