<template>
  <scroll-view
    ref="scrollRef"
    class="scroll-container"
    :scroll-x="direction === 'x'"
    :scroll-y="direction === 'y'"
    :scroll-with-animation="true"
    :show-scrollbar="false"
    :scroll-into-view="targetId"
    @scroll="handleScroll"
	:enable-flex="direction === 'x'?true:false"	
  >
    <slot></slot>
  </scroll-view>
</template>

<script setup>
import { ref, onMounted, nextTick, watch } from 'vue';

const props = defineProps({
  // 滚动方向 'x' 或 'y'
  direction: {
    type: String,
    default: 'y',
    validator: (val) => ['x', 'y'].includes(val)
  },
  // 内容项数量
  itemCount: {
    type: Number,
    required: true
  },
  // 当前激活的索引
  activeIndex: {
    type: Number,
    default: 0
  },
  // 每个内容项的选择器，如 ".list-item"
  itemSelector: {
    type: String,
    required: true
  },
  // 滚动触发索引变化的阈值比例（0-1）
  thresholdRatio: {
    type: Number,
    default: 0.3
  }
});

const emits = defineEmits(['update:activeIndex']);

const scrollRef = ref(null);
const targetId = ref(null);
const itemPositions = ref([]); // 存储每个项的位置信息
const scrollViewInfo = ref(null); // 滚动容器信息

// 获取元素信息的工具函数
const getElementsInfo = (selector) => {
    return new Promise(resolve => {
		uni.createSelectorQuery()
			.selectAll(selector)
			.boundingClientRect(resolve)
			.exec();
	});
};

// 获取滚动容器信息
const getScrollViewInfo = () => {
	return new Promise(resolve => {
		uni.createSelectorQuery()
			.select('.scroll-container')
			.boundingClientRect(resolve)
			.exec();
	});
};

// 初始化每个项的位置信息
const initItemPositions = async () => {
  await nextTick();
  
  // 获取滚动容器信息
  scrollViewInfo.value = await getScrollViewInfo();
  console.log("test")
  if (!scrollViewInfo.value) return;

  // 获取所有内容项信息
  const itemsInfo = await getElementsInfo(props.itemSelector);
  if (!itemsInfo || itemsInfo.length === 0) return;

  // 计算每个项相对于滚动容器的位置
  itemPositions.value = itemsInfo.map((item, index) => {
    const scrollKey = props.direction === 'x' ? 'left' : 'top';
    const sizeKey = props.direction === 'x' ? 'width' : 'height';
    
    return {
      index,
      start: item[scrollKey] - scrollViewInfo.value[scrollKey],
      end: item[scrollKey] - scrollViewInfo.value[scrollKey] + item[sizeKey],
      size: item[sizeKey]
    };
  });
};

// 根据索引滚动到对应位置
const scrollToIndex = (index) => {
  if (index < 0 || index >= props.itemCount) return;
  targetId.value = `${props.itemSelector.replace('.', '')}-${index}`;
  // 重置targetId避免重复点击不生效
  setTimeout(() => {
    targetId.value = null;
  }, 500);
};

// 处理滚动事件
const handleScroll = (e) => {
  if (!itemPositions.value.length || !scrollViewInfo.value) return;

  const scrollKey = props.direction === 'x' ? 'scrollLeft' : 'scrollTop';
  const scrollPos = e.detail[scrollKey];
  const containerSize = props.direction === 'x' 
    ? scrollViewInfo.value.width 
    : scrollViewInfo.value.height;

  // 计算当前应该激活的索引
  for (let i = 0; i < itemPositions.value.length; i++) {
    const item = itemPositions.value[i];
    const threshold = item.size * props.thresholdRatio;
    
    // 判断当前滚动位置是否超过项的阈值
    if (scrollPos >= (item.start - threshold) && scrollPos < (item.end - containerSize + threshold)) {
      if (i !== props.activeIndex) {
        emits('update:activeIndex', i);
      }
      break;
    }
  }
};

// 监听activeIndex变化，滚动到对应位置
watch(
  () => props.activeIndex,
  (newVal) => {
    scrollToIndex(newVal);
	console.log("init",itemPositions.value)
  },
  { immediate: true }
);

// 监听itemCount变化，重新计算位置
watch(
  () => props.itemCount,
  async () => {
    await initItemPositions();
  }
);

// 组件挂载后初始化
onMounted(async () => {
  await initItemPositions();
  console.log("init",itemPositions.value)
});

// 暴露刷新位置信息的方法给父组件
defineExpose({
  refreshPositions: initItemPositions
});
</script>

<style scoped lang="scss">
.scroll-container {
  width: 100%;
}
</style>