<template>
  <div ref="floatPanel" :style="panelStyle" class="float-panel" 
       @mousedown="handleMouseDown" 
       @touchstart="handleTouchStart">
    <slot></slot>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue';

const props = defineProps({
  position: {
    type: Object,
    default: () => ({})
  },
  fixedX: Boolean,
  fixedY: Boolean,
  snapEdge: {
    type: Boolean,
    default: false
  }
});

const floatPanel = ref(null);
const panelPos = ref({ x: 0, y: 0 });
const panelSize = ref({ width: 0, height: 0 });
const windowSize = ref({ width: 0, height: 0 });
const dragOffset = ref({ x: 0, y: 0 });
const wasDragged = ref(false);

// 更新面板和窗口尺寸信息
const updateSizes = () => {
  if (floatPanel.value) {
    panelSize.value = {
      width: floatPanel.value.offsetWidth,
      height: floatPanel.value.offsetHeight
    };
  }
  windowSize.value = {
    width: window.innerWidth,
    height: window.innerHeight
  };
};

// 初始位置计算
const initPosition = () => {
  updateSizes();
  const { left, right, top, bottom } = props.position;
  
  if (right !== undefined) {
    panelPos.value.x = windowSize.value.width - parseInt(right || 0) - panelSize.value.width;
  } else if (left !== undefined) {
    panelPos.value.x = parseInt(left || 0);
  }
  
  if (bottom !== undefined) {
    panelPos.value.y = windowSize.value.height - parseInt(bottom || 0) - panelSize.value.height;
  } else if (top !== undefined) {
    panelPos.value.y = parseInt(top || 0);
  }
};

// 面板样式
const panelStyle = computed(() => {
  return {
    left: `${panelPos.value.x}px`,
    top: `${panelPos.value.y}px`
  };
});

// 处理鼠标按下事件
const handleMouseDown = (event) => {
  // 只有点击浮动面板本身时才启动拖拽
  if (event.target === floatPanel.value || floatPanel.value.contains(event.target)) {
    // 判断是否是面板自身,如果是才阻止默认行为
    if (event.target === floatPanel.value) {
      event.preventDefault();
    }
    
    wasDragged.value = false;
    
    const startX = event.clientX;
    const startY = event.clientY;
    
    // 计算点击位置与面板左上角的偏移
    dragOffset.value = {
      x: startX - panelPos.value.x,
      y: startY - panelPos.value.y
    };
    
    const handleMouseMove = (e) => {
      wasDragged.value = true;
      
      const newX = e.clientX - dragOffset.value.x;
      const newY = e.clientY - dragOffset.value.y;
      
      // 应用约束
      if (!props.fixedX) {
        panelPos.value.x = Math.max(0, Math.min(newX, windowSize.value.width - panelSize.value.width));
      }
      
      if (!props.fixedY) {
        panelPos.value.y = Math.max(0, Math.min(newY, windowSize.value.height - panelSize.value.height));
      }
    };
    
    const handleMouseUp = (e) => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
      
      if (wasDragged.value && props.snapEdge) {
        snapToEdge();
      }
    };
    
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);
  }
};

// 处理触摸开始事件
const handleTouchStart = (event) => {
  // 只有触摸浮动面板本身时才启动拖拽
  if (event.target === floatPanel.value || floatPanel.value.contains(event.target)) {
    // 判断是否是面板自身,如果是才阻止默认行为
    if (event.target === floatPanel.value) {
      event.preventDefault();
    }
    
    wasDragged.value = false;
    
    const touch = event.touches[0];
    const startX = touch.clientX;
    const startY = touch.clientY;
    
    // 计算点击位置与面板左上角的偏移
    dragOffset.value = {
      x: startX - panelPos.value.x,
      y: startY - panelPos.value.y
    };
    
    const handleTouchMove = (e) => {
      e.preventDefault();
      wasDragged.value = true;
      
      const touch = e.touches[0];
      const newX = touch.clientX - dragOffset.value.x;
      const newY = touch.clientY - dragOffset.value.y;
      
      // 应用约束
      if (!props.fixedX) {
        panelPos.value.x = Math.max(0, Math.min(newX, windowSize.value.width - panelSize.value.width));
      }
      
      if (!props.fixedY) {
        panelPos.value.y = Math.max(0, Math.min(newY, windowSize.value.height - panelSize.value.height));
      }
    };
    
    const handleTouchEnd = (e) => {
      document.removeEventListener('touchmove', handleTouchMove);
      document.removeEventListener('touchend', handleTouchEnd);
      
      if (wasDragged.value && props.snapEdge) {
        snapToEdge();
      }
    };
    
    document.addEventListener('touchmove', handleTouchMove, { passive: false });
    document.addEventListener('touchend', handleTouchEnd);
  }
};

// 执行吸附
const snapToEdge = () => {
  const centerX = windowSize.value.width / 2;
  const panelCenterX = panelPos.value.x + panelSize.value.width / 2;
  
  if (panelCenterX < centerX) {
    panelPos.value.x = 0; // 吸附到左边
    console.log('吸附到左边边缘');
  } else {
    panelPos.value.x = windowSize.value.width - panelSize.value.width; // 吸附到右边
    console.log('吸附到右边边缘');
  }
};

// 窗口大小变化处理
const handleResize = () => {
  const oldWidth = windowSize.value.width;
  const oldHeight = windowSize.value.height;
  
  updateSizes();
  
  // 保持相对右边和底部的距离
  if (props.position.right !== undefined) {
    const rightDistance = oldWidth - (panelPos.value.x + panelSize.value.width);
    panelPos.value.x = windowSize.value.width - rightDistance - panelSize.value.width;
  }
  
  if (props.position.bottom !== undefined) {
    const bottomDistance = oldHeight - (panelPos.value.y + panelSize.value.height);
    panelPos.value.y = windowSize.value.height - bottomDistance - panelSize.value.height;
  }
  
  // 确保不超出边界
  panelPos.value.x = Math.max(0, Math.min(panelPos.value.x, windowSize.value.width - panelSize.value.width));
  panelPos.value.y = Math.max(0, Math.min(panelPos.value.y, windowSize.value.height - panelSize.value.height));
};

onMounted(() => {
  console.log('组件挂载, snapEdge =', props.snapEdge);
  updateSizes();
  initPosition();
  window.addEventListener('resize', handleResize);
});

onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
});

// 暴露方法
defineExpose({
  snapToEdge
});
</script>

<style scoped>
.float-panel {
  position: fixed;
  z-index: 1000;
  cursor: move;
  user-select: none;
  touch-action: none;
  transition: left 0.2s ease-out;
}
</style>