<template>
  <div class="my-tabs">
    <div class="my-tabs__header p-0.5 mb-3 rounded bg-gray-100 cursor-pointers">
      <div class="my-tabs__header-shell relative flex justify-between">
        <div v-for="(tab, index) in tabs" :key="tab.props.label" class="my-tab__title relative flex-auto py-1 text-center" :class="{ 'my-active': tab.props.label === value }" @click="onClickTab(tab, index)">
          {{ tab.props.label }}
        </div>

        <div class="my-tab__slider" :style="sliderStyle"></div>
      </div>
    </div>

    <div class="my-tabs__content">
      <slot />
    </div>
  </div>
</template>

<script>
export default {
  name: 'Tabs',
}
</script>

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

const props = defineProps({
  value: {
    type: String,
    required: true,
  },
})
const emit = defineEmits(['update:value', 'change'])

watch(
  () => props.value,
  () => {
    changeTab()
  },
)

const tabs = ref([])
const sliderStyle = reactive({ width: 0, left: 0 })
let tabWidth = 0
onMounted(() => {
  // 初始化数据
  tabWidth = 100 / tabs.value.length
  sliderStyle.width = `${tabWidth}%`

  changeTab()
})

let preActiveTabVM = null
async function changeTab(index = -1) {
  if (index < 0) {
    index = tabs.value.findIndex((vm) => vm.props.label === props.value)
  }
  sliderStyle.left = `${tabWidth * index}%`

  // 切换 tab 内容
  try {
    await nextTick()
    preActiveTabVM?.exposed?.changeActive?.(false)
    preActiveTabVM = tabs.value[index]
    preActiveTabVM.exposed?.changeActive?.(true)
  } catch (error) {}
}

function onClickTab(tab, index) {
  emit('update:value', tab.props.label)
  changeTab(index)
}

defineExpose({ tabs })
</script>

<style scoped>
.my-tabs__header {
  margin-bottom: 0.75rem;
  border-radius: 0.25rem;
  --tw-bg-opacity: 1;
  background-color: rgb(243 244 246 / var(--tw-bg-opacity));
  padding: 0px;
  padding: 0.125rem;
}

.my-tabs__header-shell {
  justify-content: space-between;
  position: relative;
  display: flex;
}

.my-tab__title {
  text-align: center;
  position: relative;
  flex: 1 1 auto;
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  z-index: 1;
}
.my-tab__title.my-active {
  font-weight: bold;
}

.my-tab__slider {
  position: absolute;
  bottom: 0px;
  top: 0px;
  border-radius: 0.25rem;
  --tw-bg-opacity: 1;
  background-color: rgb(255 255 255 / var(--tw-bg-opacity));
  --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);
  box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
  transition-property: all;
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  transition-duration: 150ms;
  transition-duration: 150ms;
}
</style>
