<template>
  <view class="tab-container">
    <!-- tab标题栏 -->
    <scroll-view
      scroll-x
      class="tab-scroll-view"
      :scroll-left="scrollLeft"
      scroll-with-animation
      show-scrollbar="false"
      :id="tabScrollId"
    >
      <view class="tab-items-container">
        <view
          v-for="(item, index) in tabs"
          :key="index"
          class="tab-item"
          :class="{ active: currentIndex === index }"
          @click="handleTabClick(index)"
          :id="`tab-item-${index}`"
        >
          <text class="tab-text">{{ item.title }}</text>
        </view>

        <!-- 独立的滑块元素 -->
        <view
          class="tab-line"
          :style="{
            transform: `translateX(${lineLeft}px)`,
            width: `${lineWidth}rpx`,
            backgroundColor: props.themeColor,
          }"
        ></view>
      </view>
    </scroll-view>
  </view>
</template>

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

// 唯一ID，防止多个Tab组件冲突
const tabScrollId = `tab-scroll-${Date.now()}`

// 定义组件属性
const props = defineProps({
  // tabs数据，格式：[{title: '标签1'}, {title: '标签2'}]
  tabs: {
    type: Array,
    default: () => [],
  },
  // 默认选中的索引
  modelValue: {
    type: Number,
    default: 0,
  },
  // 主题色
  themeColor: {
    type: String,
    default: '#3C9CFD',
  },
  // 滑块宽度
  lineWidth: {
    type: [Number, String],
    default: 48,
  },
})

// 定义事件
const emit = defineEmits(['update:modelValue', 'change'])

// 当前激活的索引
const currentIndex = ref(props.modelValue)

// 滚动位置
const scrollLeft = ref(0)

// 滑块位置
const lineLeft = ref(0)

// 监听props变化
watch(
  () => props.modelValue,
  (newVal) => {
    if (currentIndex.value !== newVal) {
      currentIndex.value = newVal
      updateTabPosition()
    }
  },
)

// 监听currentIndex变化
watch(
  () => currentIndex.value,
  (newVal, oldVal) => {
    if (newVal !== oldVal) {
      updateTabPosition()
      // 向父组件同步更新
      emit('update:modelValue', newVal)
      emit('change', {
        index: newVal,
        item: props.tabs[newVal] || {},
      })
    }
  },
)

// 监听tabs变化，重新计算滑块位置
watch(
  () => props.tabs,
  () => {
    nextTick(() => {
      updateTabPosition()
    })
  },
  { deep: true },
)

// 组件挂载后初始化
onMounted(() => {
  nextTick(() => {
    updateTabPosition()
  })
})

const instance = getCurrentInstance()

// 更新标签位置和滑块位置 - 优化版
const updateTabPosition = () => {
  nextTick(() => {
    // 创建查询对象
    const query = uni.createSelectorQuery().in(instance)

    // 获取滚动视图和当前选中标签的信息
    query.select(`#${tabScrollId}`).boundingClientRect()
    query.select(`#tab-item-${currentIndex.value}`).boundingClientRect()

    query.exec((res) => {
      if (res && res[0] && res[1]) {
        const scrollView = res[0]
        const currentTab = res[1]

        // 1. 计算滑块位置 - 直接使用当前标签的中心位置
        const tabCenter = currentTab.left + currentTab.width / 2 - scrollView.left

        // 2. 计算滑块左侧应该在的位置（居中）
        const lineWidthPx = uni.upx2px(Number(props.lineWidth))
        lineLeft.value = tabCenter - lineWidthPx / 2

        // 3. 计算滚动位置，使选中的标签居中显示在滚动视图中
        const offsetLeft = currentTab.left - scrollView.left
        scrollLeft.value = offsetLeft - scrollView.width / 2 + currentTab.width / 2
      }
    })
  })
}

// 点击标签切换
const handleTabClick = (index) => {
  if (currentIndex.value !== index) {
    currentIndex.value = index
  }
}
</script>

<style scoped>
.tab-container {
  width: 100%;
}

.tab-scroll-view {
  white-space: nowrap;
  width: 100%;
  height: 88rpx;
  background-color: #ffffff;
  border-bottom: 1rpx solid #f5f5f5;
  position: relative;
}

.tab-items-container {
  display: inline-flex;
  height: 100%;
  position: relative;
  width: 100%;
  justify-content: space-around;
}

.tab-item {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 0 32rpx;
  position: relative;
  height: 100%;
}

.tab-text {
  font-size: 28rpx;
  color: #333333;
  transition: all 0.3s;
}

.tab-item.active .tab-text {
  color: v-bind('props.themeColor');
}

.tab-line {
  position: absolute;
  height: 6rpx;
  border-radius: 6rpx;
  bottom: 0;
  left: 0;
  /* 平滑过渡效果 */
  transition: transform 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
</style>
