<template>
    <a-select :mode="multiple ? 'multiple' : undefined" :disabled="see || disabled" :value="value" :options="mergedData"
        :loading="loading" :allowClear="true" :placeholder="placeholder" :style="style" v-bind="filteredAttrs"
        @change="change">
        <template #dropdownRender="{ menuNode }">
            <a-input-search v-model:value="filter" placeholder="搜索" style="width: 100%; margin-bottom: 8px;"
                @search="search" />
            <v-nodes :vnodes="menuNode" />
            <a-divider style="margin: 2px 0" />
            <div style="display: flex; justify-content: flex-end; padding: 8px;">
                <a-button :disabled="page.current <= 1" @click="up" type="link" size="small">
                    <LeftOutlined />
                </a-button>
                <span>{{ page.current }}/{{ totalPages }}</span>
                <a-button :disabled="!hasNextPage" @click="down" type="link" size="small">
                    <RightOutlined />
                </a-button>
            </div>
        </template>
    </a-select>
</template>
<script>
import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
import { defineComponent } from 'vue';

const VNodes = defineComponent({
    props: { vnodes: Object },
    render() {
        return this.vnodes
    },
})

export default {
    name: 'PaasPageSelect',
    components: { VNodes, LeftOutlined, RightOutlined },
    inheritAttrs: false,
    computed: {
        see() {
            return this.$store?.forms?.see || false;
        },
        filteredAttrs() {
            const attrs = { ...this.$attrs };
            Object.keys(attrs).forEach(key => {
                if (key.startsWith('on') || key.startsWith('@') || key.startsWith('on-')) {
                    delete attrs[key];
                }
            });
            delete attrs.onChange;
            return attrs;
        }
    },
    props: {
        placeholder: String,
        multiple: { type: Boolean, default: false },
        disabled: { type: Boolean, default: false },
        modelValue: [String, Array],
        url: { type: String, required: true },
        vars: { type: Object, default: () => ({}) },
        style: { type: [String, Object], default: "width: 100%;" },
    },
    data() {
        return {
            value: [],
            selected: [],
            filter: '',
            loading: false,
            data: [],
            initFlag: true,
            page: { current: 1, size: 20 },
            total: 0, // 新增总记录数
        }
    },
    computed: {
        mergedData() {
            const map = new Map()
            this.data.forEach(item => {
                if (item?.value !== '' && item?.value != null) {
                    map.set(String(item.value), item)
                }
            })
            this.selected.forEach(val => {
                const strVal = String(val).trim()
                if (strVal && !map.has(strVal)) {
                    map.set(strVal, { label: strVal, value: strVal })
                }
            })
            return Array.from(map.values())
        },
        // 计算总页数
        totalPages() {
            return Math.ceil(this.total / this.page.size)
        },
        // 判断是否有下一页
        hasNextPage() {
            return this.page.current < this.totalPages
        }
    },
    watch: {
        vars: {
            deep: true,
            handler() {
                if (this.loading) return;
                this.filter = ''
                this.page.current = 1
                this.initFlag = false
                this.loadData()
            },
        },
        modelValue: {
            immediate: true,
            handler(newVal) {
                this.initFromModelValue(newVal);
                if (this.initFlag || this.data?.length === 0) {
                    this.initFlag = false
                    this.loadData()
                }
            },
        },
    },
    mounted() {
        if (this.initFlag || this.data?.length === 0) {
            this.initFlag = false
            this.initFromModelValue()
        }
    },
    methods: {
        initFromModelValue(val = this.modelValue) {
            if (!val || (Array.isArray(val) && val.length === 0)) {
                this.value = []
                this.selected = []
                return
            }
            if (Array.isArray(val)) {
                this.value = val.filter(Boolean).map(String)
                this.selected = this.value
            } else if (typeof val === 'string') {
                const trimmed = val.trim()
                if (trimmed === '') {
                    this.value = []
                    this.selected = []
                } else if (trimmed.includes(',')) {
                    this.value = trimmed.split(',').map(v => v.trim()).filter(Boolean)
                    this.selected = this.value
                } else {
                    this.value = [trimmed]
                    this.selected = this.value
                }
            }
        },
        search() {
            this.page.current = 1
            this.loadData()
        },
        up() {
            if (this.page.current > 1) {
                this.page.current--
                this.loadData()
            }
        },
        down() {
            if (this.hasNextPage) {
                this.page.current++
                this.loadData()
            }
        },
        change(data) {
            this.selected = Array.isArray(data) ? data : [data]
            let emitValue
            if (this.multiple) {
                emitValue = this.selected.join(',')
            } else {
                emitValue = this.selected[0]
            }
            this.$emit('update:modelValue', emitValue)
            this.$emit('change', emitValue)
        },
        loadData() {
            if (this.loading) return
            this.loading = true
            const params = {
                page: this.page,
                label: this.filter,
                vars: this.vars,
                selected: this.selected,
            }
            this.$post(this.url, params)
                .then((res) => {
                    const result = res?.data?.data
                    if (result && result.rows) {
                        this.data = result.rows
                        this.total = result.total || 0 // 更新总记录数
                    } else {
                        // 如果API返回格式不符合预期，给出提示
                        console.warn('API返回数据格式不符合预期')
                        this.data = []
                        this.total = 0
                    }
                })
                .catch(error => {
                    console.error('加载数据失败:', error)
                    this.data = []
                    this.total = 0
                })
                .finally(() => {
                    this.loading = false
                })
        },
    },
}
</script>