<template>
  <view
    class="drop-menu-item"
    :class="[customClass, { 'drop-menu-item--show': isShow }]"
    :style="{
      'z-index': zIndex,
      'transition-duration': `${duration}ms`,
    }"
  >
    <view class="drop-menu-item__wrapper" :class="{ 'drop-menu-item__wrapper--show': isShow }">
      <!-- 默认选项列表 -->
      <scroll-view v-if="!$slots.default" scroll-y class="drop-menu-item__content">
        <view class="drop-menu-item__option-list">
          <view
            v-for="(option, index) in options"
            :key="index"
            class="drop-menu-item__option"
            :class="{ 'drop-menu-item__option--active': isOptionActive(option) }"
            @click="handleOptionClick(option)"
          >
            <text class="drop-menu-item__text">{{ getOptionText(option) }}</text>
            <text v-if="isOptionActive(option)" class="drop-menu-item__icon">✓</text>
          </view>
        </view>
      </scroll-view>
      <!-- 自定义内容插槽 -->
      <view v-else class="drop-menu-item__custom-content">
        <slot></slot>
      </view>
    </view>
  </view>
</template>

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

const props = defineProps({
  modelValue: {
    type: [String, Number, Object],
    default: '',
  },
  title: {
    type: String,
    required: true,
  },
  options: {
    type: Array,
    default: () => [],
  },
  labelKey: {
    type: String,
    default: 'text',
  },
  valueKey: {
    type: String,
    default: 'value',
  },
  customClass: {
    type: String,
    default: '',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  activation: {
    type: Boolean,
    default: false,
  },
})

const emit = defineEmits(['update:modelValue', 'change', 'open'])

// 注入父组件提供的数据和方法
const { activeIndex, addTitle, closeDropMenu, zIndex, duration, direction, titles } = inject(
  'dropMenu',
) as any

// 当前组件的索引
const itemIndex = ref(-1)

// 是否显示下拉内容
const isShow = computed(() => activeIndex.value !== -1 && activeIndex.value === itemIndex.value)

// 监听显示状态变化
watch(isShow, (newVal) => {
  if (newVal) {
    emit('open')
  }
})

// 获取选项的显示文本
const getOptionText = (option: any) => {
  if (typeof option === 'object' && props.labelKey) {
    return option[props.labelKey]
  }
  return option
}

// 获取选项的值
const getOptionValue = (option: any) => {
  if (typeof option === 'object' && props.valueKey) {
    return option[props.valueKey]
  }
  return option
}

// 判断选项是否被选中
const isOptionActive = (option: any) => {
  const optionValue = getOptionValue(option)
  return props.modelValue === optionValue
}

// 处理选项点击
const handleOptionClick = (option: any) => {
  const value = getOptionValue(option)
  emit('update:modelValue', value)
  emit('change', value)
  closeDropMenu()
}

// 组件挂载时，向父组件注册标题并设置索引
onMounted(() => {
  // 先获取当前索引
  itemIndex.value = titles.value.length
  // 再添加标题
  addTitle({ title: props.title, disabled: props.disabled, activation: props.activation })
})

// 监听标题变化
watch(
  () => props.title,
  (newTitle) => {
    // 更新对应索引位置的标题
    if (titles.value[itemIndex.value].title !== newTitle) {
      titles.value[itemIndex.value].title = newTitle
    }
  },
  { immediate: false },
)

watch(
  () => props.activation,
  (newVal) => {
    titles.value[itemIndex.value].activation = newVal
  },
)
</script>

<style scoped>
.drop-menu-item {
  position: relative;
  width: 100%;
}

.drop-menu-item__wrapper {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  background: #fff;
  transform: translateY(-5px);
  transition: all 0.25s ease;
  overflow: hidden;
  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
  opacity: 0;
  visibility: hidden;
  z-index: 11;
}

.drop-menu-item__wrapper--show {
  transform: translateY(0);
  opacity: 1;
  visibility: visible;
}

.drop-menu-item__content {
  max-height: 400rpx;
}

.drop-menu-item__custom-content {
  width: 100%;
  background: #fff;
  transform-origin: top;
}

.drop-menu-item__option-list {
  padding: 12rpx 0;
}

.drop-menu-item__option {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 24rpx 32rpx;
  line-height: 1.2;
  cursor: pointer;
}

.drop-menu-item__option:active {
  background-color: #f2f2f2;
}

.drop-menu-item__option--active {
  color: #0083ff;
}

.drop-menu-item__text {
  font-size: 28rpx;
}

.drop-menu-item__icon {
  font-size: 32rpx;
  color: #0083ff;
}
</style>
