<template>
  <view class="w-full" @click="handleClick">
    <view class="flex items-center gap-x-10" :style="customStyle">
      <view v-if="matchValue" class="flex-1 text-fore-title" :style="getValueStyle"
        :class="{ 'text-[#c0c4cc]': disabled || readonly }">
        <slot :label="label">
          {{ label }}
        </slot>
      </view>
      <view v-else class="flex-1 text-[#c0c4cc]" :style="getPlaceholderStyle">{{ placeholder }}</view>
      <view v-if="!readonly" class="transition-all duration-300">
        <uv-icon :name="icon" size="15" color="#B3B3B3" />
      </view>
    </view>
  </view>
  <root-portal>
    <uv-picker ref="pickerRef" :showToolbar="false" :columns="columns" :defaultIndex="defaultIndex" :round="16"
      activeColor="#31A0FC" :keyName="keyLabel" :title="title" @change="handleChange" @close="onClose">
      <template #toolbar>
        <view class="flex items-center justify-between pt-20">
          <view class="px-46 py-20 text-28 text-fore-light" @click="handleCancel">取消</view>
          <text class="text-30 text-fore-title font-bold">{{ title }}</text>
          <view class="px-46 py-20 text-28 text-fore-title" @click="handleConfirm">确认</view>
        </view>
      </template>
    </uv-picker>
  </root-portal>
</template>
<script lang="ts" setup>

const modelValue = defineModel<string | number>('modelValue', {
  default: ''
});
const props = defineProps({
  placeholder: {
    type: String,
    default: '请选择',
  },
  title: {
    type: String,
    default: '',
  },
  icon: {
    type: String,
    default: 'arrow-right',
  },
  list: {
    type: Array as PropType<any[]>,
    default: () => [],
  },
  keyLabel: {
    type: String,
    default: 'label',
  },
  keyValue: {
    type: String,
    default: 'value',
  },
  disabled: {
    type: Boolean,
    default: false,
  },
  readonly: {
    type: Boolean,
    default: false,
  },
  customStyle: {
    type: Object,
    default: () => ({}),
  },
  placeholderStyle: {
    type: Object,
    default: () => ({}),
  },
  fontSize: {
    type: Number,
    default: 30,
  }
});
const defaultIndex = ref([0]);
const label = ref('');
const isOpen = ref(false);
const matchValue = ref(false);
const columns = computed(() => {
  return [props.list];
});
const getPlaceholderStyle = computed(() => {
  return {
    ...props.placeholderStyle,
    fontSize: props.fontSize + 'rpx'
  }
});
const getValueStyle = computed(() => {
  return {
    fontSize: props.fontSize + 'rpx'
  }
});
const init = () => {
  if (modelValue.value !== null && modelValue.value !== undefined && modelValue.value !== '') {
    const index = props.list.findIndex(item => item[props.keyValue] == modelValue.value);
    if (index !== -1) {
      defaultIndex.value = [index];
      label.value = props.list[index][props.keyLabel];
      matchValue.value = true;
    } else {
      // 如果找不到匹配项，重置状态
      defaultIndex.value = [0];
      label.value = props.placeholder;
      matchValue.value = false;
    }
  } else {
    defaultIndex.value = [0];
    label.value = props.placeholder;
    matchValue.value = false;
  }
}

// 使用 watch 替代 watchEffect，避免循环更新
watch([() => modelValue.value, () => props.list], init, { immediate: true });

const pickerRef = ref();

const emit = defineEmits<{
  (e: 'change', value: number, selectedItem: any): void;
  (e: 'click'): void;
}>();

const handleConfirm = () => {
  const { value } = pickerRef.value.manualConfirm();
  const oldValue = modelValue.value;
  const newValue = value[0][props.keyValue];

  // 更新 modelValue
  modelValue.value = newValue;

  // 手动更新显示状态，确保界面同步
  const selectedItem = value[0];
  label.value = selectedItem[props.keyLabel];
  matchValue.value = true;

  // 发出 change 事件
  if (oldValue !== newValue) {
    emit('change', newValue, selectedItem);
  }

  pickerRef.value.close();
}
const handleCancel = () => {
  pickerRef.value.close();
}
const handleChange = () => { }

const handleClick = () => {
  emit('click');
  if (props.disabled) {
    return;
  }
  isOpen.value = true;
  pickerRef.value.open();
}

const onClose = () => {
  isOpen.value = false;
}
</script>
<style lang="scss" scoped></style>