<template>
    <view :class="width" @click="handleClick">
        <view class="flex items-center gap-x-6 justify-start" :class="customClass" :style="customStyle">
            <view v-if="matchValue || customLabel"
                  class="text-[15px] h-[24px] leading-[24px] flex-1 min-w-1 ellipsis-1"
                  :style="getValueStyle"
                  :class="[(disabled || readonly) ? 'text-[#dce4f6]': color]">
                <slot :label="label">
                    {{ label }}
                </slot>
            </view>
            <view v-else class="text-[15px] h-[24px] leading-[24px] text-[#c0c4cc] flex-1 min-w-1 ellipsis-1"
                  :style="getPlaceholderStyle">{{ placeholder }}
            </view>
            <slot name="right">
                <view v-if="!readonly && showArrow" class="transition-all duration-300">
                    <uv-icon :name="icon" size="15" :color="iconColor"/>
                </view>
            </slot>
        </view>
    </view>
    <!-- #ifdef H5 -->
    <teleport to="body">
        <!-- #endif -->
        <!-- #ifdef MP-WEIXIN -->
        <root-portal externalClass="theme-ie">
            <!-- #endif -->
            <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="theme-ie">
                        <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>
                    </view>
                </template>
            </uv-picker>
            <!-- #ifdef MP-WEIXIN -->
        </root-portal>
        <!-- #endif -->
        <!-- #ifdef H5 -->
    </teleport>
    <!-- #endif -->
</template>
<script lang="ts" setup>
defineOptions({
    options: {
        virtualHost: true
    }
});
const modelValue = defineModel<string | number>('modelValue', {
    default: ''
});
const props = defineProps({
    placeholder: {
        type: String,
        default: '请选择',
    },
    customLabel: {
        type: String,
        default: '',
    },
    title: {
        type: String,
        default: '',
    },
    icon: {
        type: String,
        default: 'arrow-right',
    },
    iconColor: {
        type: String,
        default: '#B3B3B3'
    },
    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: () => ({}),
    },
    customClass: {
        type: [String,Array],
        default: ''
    },
    width: {
        type: String,
        default: 'w-full'
    },
    color: {
        type: String,
        default: 'text-fore-title'
    },
    placeholderStyle: {
        type: Object,
        default: () => ({}),
    },
    fontSize: {
        type: Number,
        default: 15,
    },
    showArrow: {
        type: Boolean,
        default: true,
    },
});
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 + 'px'
    }
});
const getValueStyle = computed(() => {
    return {
        fontSize: props.fontSize + 'px'
    }
});
const init = () => {
    if (props.customLabel) {
        label.value = props.customLabel;
        matchValue.value = true;
        return;
    }

    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 = modelValue.value + '';
            matchValue.value = true;
        }
    } 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 || props.readonly) {
        return;
    }
    if (!props.list.length) {
        uni.$ie.showToast('暂无数据');
        return;
    }
    init();
    isOpen.value = true;
    pickerRef.value.open();
}

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