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

// 修复props和emit的使用方式
const props = defineProps({
  direction: {
    type: String,
    default: 'vertical', // 'vertical' 或 'horizontal'
    validator: (value) => ['vertical', 'horizontal'].includes(value)
  },
  position: {
    type: String,
    default: 'left', // 'left', 'right', 'top' 或 'bottom'
    validator: (value) => ['left', 'right', 'top', 'bottom'].includes(value)
  },
  initialSize: {
    type: Number,
    default: null
  },
  minSize: {
    type: Number,
    default: 200
  },
  maxSize: {
    type: Number,
    default: 1000
  }
})

const emit = defineEmits(['resize', 'resizeEnd', 'handleClick', 'collapse', 'expand']) // 添加collapse和expand事件

const dividerRef = ref(null)
const isResizing = ref(false)
let startX = 0
let startY = 0
let startWidth = 0
let startHeight = 0
// 使用 ref 管理 currentSize 状态
// 注意：具体初始化值将在 onMounted 中设置，确保能正确访问 props
const currentSize = ref(0)
// 使用 ref 管理 isCollapsed 状态，与 isResizing 保持一致
const isCollapsed = ref(false) // 用于跟踪面板是否处于折叠状态

// 添加统一的边界检查函数
const clampSize = (size, min, max) => {
  return Math.max(min, Math.min(max, size))
}

// 计算是否处于有效折叠状态（考虑右侧面板的边框影响）
const isPanelEffectivelyCollapsed = (elementSize, minSize) => {
  // 对于右侧分隔条，需要特殊处理最小尺寸的判断
  // 因为右侧面板有 border-left: 1px，即使宽度为 0，offsetWidth 也可能返回 1
  return elementSize <= minSize + 1
}

// 计算鼠标移动的 delta 值
const calculateDelta = (e) => {
  const deltaX = e.clientX - startX
  const deltaY = e.clientY - startY
  return { deltaX, deltaY }
}

// 获取目标元素
const getTargetElement = () => {
  // 边界检查：确保dividerRef.value存在
  if (!dividerRef.value) {
    console.warn('可调整分隔条：dividerRef 不可用')
    return null
  }
  
  // 根据position属性获取正确的相邻元素
  let targetElement = null
  if (props.position === 'left' || props.position === 'top') {
    targetElement = dividerRef.value.previousElementSibling
  } else if (props.position === 'right' || props.position === 'bottom') {
    targetElement = dividerRef.value.nextElementSibling
  }
  
  return targetElement
}

// 计算新的尺寸
const calculateNewSize = (startSize, delta, minSize, maxSize, position) => {
  let newSize = startSize
  if (position === 'left' || position === 'top') {
    // 左侧或顶部分隔条：向左/上拖减小尺寸，向右/下拖增大尺寸
    // 当向左拖动时，delta 为负数，startSize + delta 会减小
    // 当向右拖动时，delta 为正数，startSize + delta 会增大
    newSize = startSize + delta
  } else if (position === 'right' || position === 'bottom') {
    // 右侧或底部分隔条：向左/上拖减小尺寸，向右/下拖增大尺寸
    // 当向左拖动时，delta 为负数，startSize - delta 会增大
    // 当向右拖动时，delta 为正数，startSize - delta 会减小
    // 注意：这里的逻辑与左侧相反，因为右侧分隔条控制的是右侧面板
    newSize = startSize - delta
  }
  return Math.max(minSize, Math.min(maxSize, newSize))
}


const onMouseDown = (e) => {
  // 边界检查：确保dividerRef.value存在
  if (!dividerRef.value) {
    console.warn('可调整分隔条：dividerRef 不可用')
    return
  }
  
  isResizing.value = true
  startX = e.clientX
  startY = e.clientY
  
  // 获取目标元素
  const targetElement = getTargetElement()
  
  // 边界检查：确保targetElement存在
  if (!targetElement) {
    console.warn('可调整分隔条：未找到目标元素')
    isResizing.value = false
    return
  }
  
  // 获取相邻元素的初始尺寸
  startWidth = targetElement.offsetWidth
  startHeight = targetElement.offsetHeight
  // 注意：不再重新初始化 currentSize，避免覆盖拖拽时的更新值
  
  // 阻止默认行为，防止选中文本
  e.preventDefault()
  
  // 添加事件监听器到document
  document.addEventListener('mousemove', onMouseMove)
  document.addEventListener('mouseup', onMouseUp)
  document.body.style.cursor = props.direction === 'vertical' ? 'col-resize' : 'row-resize'
  
  // 添加拖拽样式
  dividerRef.value.classList.add('resizing')
}



const onHandleClick = (e) => {
  try {
    // 阻止事件冒泡
    e.stopPropagation()
    
    // 边界检查：确保dividerRef.value存在
    if (!dividerRef.value) {
      console.warn('可调整分隔条：dividerRef 不可用')
      return
    }
    
    // 添加简单的视觉反馈
    dividerRef.value.classList.add('collapsing')
    setTimeout(() => {
      dividerRef.value?.classList.remove('collapsing')
    }, 300)
    
    // 获取目标元素
    const targetElement = getTargetElement()
    
    // 边界检查：确保targetElement存在
    if (!targetElement) {
      console.warn('可调整分隔条：未找到目标元素')
      return
    }
    
    // 获取目标元素的当前尺寸
    const currentElementSize = props.direction === 'vertical' ? targetElement.offsetWidth : targetElement.offsetHeight
    
    // 使用统一的尺寸判断逻辑
    const effectivelyCollapsed = isPanelEffectivelyCollapsed(currentElementSize, props.minSize)
    
    // 计算切换后的尺寸
    let newSize = 0
    
    if (!effectivelyCollapsed) {
      // 当前尺寸大于最小尺寸，切换到最小尺寸（折叠）
      currentSize.value = clampSize(currentElementSize, props.minSize, props.maxSize) // 保存当前尺寸，以便稍后恢复
      newSize = props.minSize
      isCollapsed.value = true
      // 只触发折叠事件，让父组件根据需要处理尺寸更新
      emit('collapse', newSize)
    } else {
      // 当前尺寸等于最小尺寸，切换到之前保存的尺寸（展开）
      // 确保 restoreSize 有合理的值
      const restoreSize = clampSize(
        currentSize.value > props.minSize ? currentSize.value : 
        (props.initialSize && props.initialSize > props.minSize ? props.initialSize : 200),
        props.minSize, props.maxSize
      )
      newSize = restoreSize
      isCollapsed.value = false
      // 只触发展开事件，让父组件根据需要处理尺寸更新
      emit('expand', newSize)
    }
  } catch (error) {
    console.error('可调整分隔条：处理单击事件时出错:', error)
  }
}

const onMouseMove = (e) => {
  if (!isResizing.value) return
  
  // 计算鼠标移动的 delta 值
  const { deltaX, deltaY } = calculateDelta(e)
  
  let newSize = 0
  
  if (props.direction === 'vertical') {
    // 垂直分隔条：计算新的宽度
    newSize = calculateNewSize(startWidth, deltaX, props.minSize, props.maxSize, props.position)
    
    // 获取目标元素的实际尺寸
    const targetElement = getTargetElement()
    const currentElementSize = targetElement ? targetElement.offsetWidth : newSize
    
    // 使用统一的尺寸判断逻辑
    const effectivelyCollapsed = isPanelEffectivelyCollapsed(currentElementSize, props.minSize)
    
    // 如果不是折叠状态，更新 currentSize
    if (!effectivelyCollapsed) {
      currentSize.value = clampSize(newSize, props.minSize, props.maxSize)
      isCollapsed.value = false
    } else {
      isCollapsed.value = true
    }
    emit('resize', newSize)
  } else {
    // 水平分隔条：计算新的高度
    newSize = calculateNewSize(startHeight, deltaY, props.minSize, props.maxSize, props.position)
    
    // 获取目标元素的实际尺寸
    const targetElement = getTargetElement()
    const currentElementSize = targetElement ? targetElement.offsetHeight : newSize
    
    // 使用统一的尺寸判断逻辑
    const effectivelyCollapsed = isPanelEffectivelyCollapsed(currentElementSize, props.minSize)
    
    // 如果不是折叠状态，更新 currentSize
    if (!effectivelyCollapsed) {
      currentSize.value = clampSize(newSize, props.minSize, props.maxSize)
      isCollapsed.value = false
    } else {
      isCollapsed.value = true
    }
    emit('resize', newSize)
  }
}

const onMouseUp = (e) => {
  isResizing.value = false
  
  // 计算鼠标移动的 delta 值
  const deltaX = e.clientX - startX
  const deltaY = e.clientY - startY
  
  // 计算最终尺寸
  const finalSize = props.direction === 'vertical' ? 
    calculateNewSize(startWidth, deltaX, props.minSize, props.maxSize, props.position) : 
    calculateNewSize(startHeight, deltaY, props.minSize, props.maxSize, props.position)
  
  // 获取目标元素的实际尺寸
  const targetElement = getTargetElement()
  const currentElementSize = targetElement ? 
    (props.direction === 'vertical' ? targetElement.offsetWidth : targetElement.offsetHeight) : 
    finalSize
  
  // 使用统一的尺寸判断逻辑
  const effectivelyCollapsed = isPanelEffectivelyCollapsed(currentElementSize, props.minSize)
  
  // 如果不是折叠状态，更新 currentSize
  if (!effectivelyCollapsed) {
    currentSize.value = clampSize(finalSize, props.minSize, props.maxSize)
  }
  
  // 触发拖拽结束事件
  emit('resizeEnd', finalSize)
  
  // 移除事件监听器
  document.removeEventListener('mousemove', onMouseMove)
  document.removeEventListener('mouseup', onMouseUp)
  document.body.style.cursor = ''
  
  // 移除拖拽样式
  if (dividerRef.value) {
    dividerRef.value.classList.remove('resizing')
  }
}

onMounted(() => {
  // 初始化 currentSize 为合理的默认值
  if (props.initialSize && props.initialSize > props.minSize) {
    currentSize.value = clampSize(props.initialSize, props.minSize, props.maxSize)
    isCollapsed.value = false
  } else {
    currentSize.value = 200 // 默认值
    isCollapsed.value = false
  }
  
  // 初始化时设置初始尺寸
  if (props.initialSize) {
    emit('resize', props.initialSize)
  }
})

onUnmounted(() => {
  // 清理全局事件监听器，避免内存泄漏
  document.removeEventListener('mousemove', onMouseMove)
  document.removeEventListener('mouseup', onMouseUp)
  
  // 清理DOM相关资源
  if (dividerRef.value) {
    // 移除拖拽和折叠样式
    dividerRef.value.classList.remove('resizing', 'collapsing')
  }
  
  // 清理全局样式
  document.body.style.cursor = ''
  
  // 重置组件状态
  isResizing.value = false
  isCollapsed.value = false
  
  // Vue的响应式数据会自动清理，无需额外处理
})
</script>

<template>
  <div 
    ref="dividerRef"
    class="cube-splitter"
    :class="direction"
    @mousedown="onMouseDown"
  >
    <div class="splitter-handle" @click.stop.prevent="onHandleClick"></div>
  </div>
</template>

<style scoped>
/* CSS 变量定义 */
:root {
  --cube-splitter-color: #e0e0e0;
  --cube-splitter-hover-color: #667eea;
  --cube-splitter-active-color: #5568d3;
  --cube-splitter-handle-color: #fff;
  --cube-splitter-handle-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
  --cube-splitter-collapsing-color: #667eea;
  --cube-splitter-collapsing-shadow: 0 0 10px rgba(102, 126, 234, 0.5);
  --cube-splitter-transition-speed: 0.3s;
}

.cube-splitter {
  position: relative;
  background-color: var(--cube-splitter-color);
  display: flex;
  align-items: center;
  justify-content: center;
  /* 确保可以接收鼠标事件 */
  cursor: pointer;
  user-select: none;
  flex-shrink: 0;
  z-index: 100;
}

.cube-splitter:hover {
  background-color: var(--cube-splitter-hover-color);
}

.cube-splitter.vertical {
  width: 6px;
  height: 100%;
  cursor: col-resize;
}

.cube-splitter.horizontal {
  width: 100%;
  height: 6px;
  cursor: row-resize;
}

.splitter-handle {
  position: absolute;
  opacity: 0;
}

.cube-splitter.vertical .splitter-handle {
  width: 4px;
  height: 40px;
  background-color: var(--cube-splitter-handle-color);
  box-shadow: var(--cube-splitter-handle-shadow);
  cursor: pointer;
}

.cube-splitter.horizontal .splitter-handle {
  width: 40px;
  height: 4px;
  background-color: var(--cube-splitter-handle-color);
  box-shadow: var(--cube-splitter-handle-shadow);
  cursor: pointer;
}

.cube-splitter:hover .splitter-handle {
  opacity: 1;
}

/* 拖拽时的样式 */
.cube-splitter:active,
.cube-splitter.resizing {
  background-color: var(--cube-splitter-active-color);
  transition: none;
}

.cube-splitter:active .splitter-handle,
.cube-splitter.resizing .splitter-handle {
  opacity: 1;
  transition: none;
}

/* 折叠/展开时的视觉反馈 */
.cube-splitter.collapsing {
  background-color: var(--cube-splitter-collapsing-color);
  transition: background-color var(--cube-splitter-transition-speed) ease;
  box-shadow: var(--cube-splitter-collapsing-shadow);
}

.cube-splitter.collapsing .splitter-handle {
  opacity: 1;
  transform: scale(1.1);
  transition: transform var(--cube-splitter-transition-speed) ease;
  box-shadow: 0 0 8px rgba(102, 126, 234, 0.8);
}
</style>