<script setup lang="ts">
import { ref, computed } from 'vue';

const props = withDefaults(defineProps<{
  /**
   * 当前缩放值
   */
  currentZoom: number;
  
  /**
   * 最小缩放值
   */
  minZoom?: number;
  
  /**
   * 最大缩放值
   */
  maxZoom?: number;
  
  /**
   * 客户端类型
   */
  clientType?: 'pc' | 'ipad' | 'mobile';
  
  /**
   * 主题色
   */
  themeColor?: string;
}>(), {
  minZoom: 0.4,
  maxZoom: 2,
  clientType: 'pc',
  themeColor: '#00D98D'
});

const emit = defineEmits<{
  change: [zoom: number];
}>();

const isDragging = ref(false);
const sliderRef = ref<HTMLElement | null>(null);
const localZoom = ref<number>(props.currentZoom);

// 验证并限制缩放值在有效范围内
const clampZoom = (zoom: number): number => {
  return Math.max(props.minZoom, Math.min(props.maxZoom, zoom));
};

// 根据 clientType 计算组件大小类
const sizeClass = computed(() => {
  return `cf-zoom-slider--${props.clientType}`;
});

// 计算滑块位置百分比 - 拖动时使用本地值，否则使用 props
const percentage = computed(() => {
  const zoom = isDragging.value ? localZoom.value : props.currentZoom;
  const validZoom = clampZoom(zoom);
  const pct = ((validZoom - props.minZoom) / (props.maxZoom - props.minZoom)) * 100;
  return pct;
});

// 更新缩放值
const updateZoom = (clientX: number) => {
  if (!sliderRef.value) return;
  
  // 获取轨道元素来计算实际可用宽度（排除 padding）
  const trackEl = sliderRef.value.querySelector('.cf-zoom-slider__track') as HTMLElement;
  if (!trackEl) return;
  
  const trackRect = trackEl.getBoundingClientRect();
  const offsetX = clientX - trackRect.left;
  const percent = Math.max(0, Math.min(1, offsetX / trackRect.width));
  
  const newZoom = props.minZoom + percent * (props.maxZoom - props.minZoom);
  const validZoom = clampZoom(Math.round(newZoom * 100) / 100);
  
  localZoom.value = validZoom;
  emit('change', validZoom);
};

// 鼠标移动
const handleMouseMove = (e: MouseEvent) => {
  if (isDragging.value) {
    updateZoom(e.clientX);
  }
};

// 鼠标松开
const handleMouseUp = () => {
  isDragging.value = false;
  document.removeEventListener('mousemove', handleMouseMove);
  document.removeEventListener('mouseup', handleMouseUp);
};

// 鼠标按下
const handleMouseDown = () => {
  isDragging.value = true;
  localZoom.value = props.currentZoom;
  
  document.addEventListener('mousemove', handleMouseMove);
  document.addEventListener('mouseup', handleMouseUp);
};

// 触摸移动
const handleTouchMove = (e: TouchEvent) => {
  if (isDragging.value) {
    updateZoom(e.touches[0].clientX);
  }
};

// 触摸结束
const handleTouchEnd = () => {
  isDragging.value = false;
};

// 触摸开始
const handleTouchStart = () => {
  isDragging.value = true;
  localZoom.value = props.currentZoom;
};
</script>

<template>
  <div 
    ref="sliderRef"
    class="cf-zoom-slider"
    :class="[sizeClass, { 'cf-zoom-slider--dragging': isDragging }]"
    @mousedown="handleMouseDown"
    @touchstart="handleTouchStart"
    @touchmove="handleTouchMove"
    @touchend="handleTouchEnd"
  >
    <div class="cf-zoom-slider__track">
      <div 
        class="cf-zoom-slider__progress"
        :style="{ 
          width: `${percentage}%`,
          backgroundColor: themeColor
        }"
      ></div>
      <div 
        class="cf-zoom-slider__thumb"
        :style="{ 
          left: `${percentage}%`,
          borderColor: themeColor
        }"
      ></div>
    </div>
  </div>
</template>

<style scoped>
.cf-zoom-slider {
    position: relative;
    cursor: pointer;
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    touch-action: none;
    background: rgba(0, 0, 0, 0.30);
    backdrop-filter: blur(10px);
    border-radius: 999px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
}

.cf-zoom-slider__track {
    position: relative;
    width: 100%;
    background-color: #C4C4C4;
    border-radius: 999px;
}

.cf-zoom-slider__progress {
    position: absolute;
    left: 0;
    top: 0;
    height: 100%;
    background-color: #00D98D;
    border-radius: 999px;
    pointer-events: none;
}

.cf-zoom-slider__thumb {
    position: absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    background-color: #ffffff;
    border-radius: 50%;
    cursor: grab;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    pointer-events: none;
}

.cf-zoom-slider--dragging .cf-zoom-slider__thumb {
    cursor: grabbing;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

.cf-zoom-slider__thumb:hover {
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
}

/* PC 尺寸 */
.cf-zoom-slider--pc {
    width: 218px;
    height: 28px;
    padding: 8px 12px;
}

.cf-zoom-slider--pc .cf-zoom-slider__track {
    height: 6px;
}

.cf-zoom-slider--pc .cf-zoom-slider__thumb {
    width: 12px;
    height: 12px;
    border: 1px solid #00D98D;
}

/* iPad 尺寸 */
.cf-zoom-slider--ipad {
    width: 345px;
    height: 48px;
    padding: 14px 20px;
}

.cf-zoom-slider--ipad .cf-zoom-slider__track {
    height: 12px;
}

.cf-zoom-slider--ipad .cf-zoom-slider__thumb {
    width: 20px;
    height: 20px;
    border: 2px solid #00D98D;
}

/* Mobile 尺寸 */
.cf-zoom-slider--mobile {
    width: 345px;
    height: 48px;
    padding: 14px 20px;
}

.cf-zoom-slider--mobile .cf-zoom-slider__track {
    height: 12px;
}

.cf-zoom-slider--mobile .cf-zoom-slider__thumb {
    width: 20px;
    height: 20px;
    border: 2px solid #00D98D;
}
</style>
