<template>
    <el-dialog
        v-model="visible"
        :title="title"
        width="600px"
        :close-on-click-modal="false"
        @open="handleOpen"
    >
        <div class="topic-edit">
            <draggable
                v-model="items"
                item-key="id"
                handle=".drag-handle"
                :animation="200"
                class="space-y-4"
            >
                <template #item="{ element: item, index }">
                    <div
                        class="flex items-center gap-4 p-3 border rounded bg-gray-50 relative group box-border"
                    >
                        <!-- Drag Handle -->
                        <div
                            class="drag-handle cursor-move text-gray-400 hover:text-gray-600"
                        >
                            <el-icon :size="20">
                                <Rank />
                            </el-icon>
                        </div>

                        <ImageUpload
                            v-model="item.imgUrl"
                            :limit="1"
                            :isShowTip="false"
                        />

                        <div class="flex-1">
                            <div class="flex items-center gap-2 mb-2">
                                <el-select
                                    v-model="item.showCateId"
                                    filterable
                                    remote
                                    reserve-keyword
                                    placeholder="请搜索并选择专题"
                                    :remote-method="
                                        (query) => remoteMethod(query, index)
                                    "
                                    :loading="item.loading"
                                    @change="
                                        (val) => handleSelectChange(val, index)
                                    "
                                    clearable
                                    class="flex-1"
                                >
                                    <el-option
                                        v-for="opt in itemOptions[item._key] ||
                                        []"
                                        :key="opt.value"
                                        :label="opt.label"
                                        :value="opt.value"
                                        :disabled="
                                            isOptionDisabled(opt.value, index)
                                        "
                                    />
                                </el-select>
                            </div>
                            <el-input
                                v-model="item.jumpUrl"
                                placeholder="请输入跳转链接"
                            >
                                <template #prepend>链接</template>
                            </el-input>
                            <div
                                v-if="item.showCateId"
                                class="text-xs text-gray-400 mt-1"
                            >
                                已绑定专题ID: {{ item.showCateId }}
                            </div>
                        </div>

                        <!-- Delete Button -->
                        <el-button
                            type="danger"
                            circle
                            size="small"
                            class="opacity-0 group-hover:opacity-100 transition-opacity absolute -top-2 -right-2"
                            @click="handleRemove(index)"
                        >
                            <el-icon>
                                <Delete />
                            </el-icon>
                        </el-button>
                    </div>
                </template>
            </draggable>

            <!-- Add Button -->
            <el-button
                v-if="items.length < limit"
                class="w-full border-dashed mt-4"
                @click="handleAdd"
            >
                <el-icon class="mr-1">
                    <Plus />
                </el-icon>
                添加专题
            </el-button>
        </div>

        <template #footer>
            <span class="dialog-footer">
                <el-button @click="visible = false">取消</el-button>
                <el-button
                    type="primary"
                    :loading="loading"
                    @click="handleConfirm"
                    >确定</el-button
                >
            </span>
        </template>
    </el-dialog>
</template>

<script setup>
    import { computed, ref } from 'vue';
    import { Plus, Delete, Rank } from '@element-plus/icons-vue';
    import ImageUpload from '@/components/ImageUpload/index.vue';
    import request from '@/utils/request';
    import { EleMessage } from 'ele-admin-plus/es';
    import draggable from 'vuedraggable';

    const props = defineProps({
        modelValue: {
            type: Boolean,
            default: false
        },
        title: {
            type: String,
            default: '专题编辑'
        },
        position: {
            type: String,
            default: 'topic'
        },
        limit: {
            type: Number,
            default: 10
        }
    });

    const emit = defineEmits(['update:modelValue', 'success']);

    const visible = computed({
        get: () => props.modelValue,
        set: (val) => emit('update:modelValue', val)
    });

    const loading = ref(false);
    const items = ref([]);
    const itemOptions = ref({});

    const defaultOptions = ref([]);

    const createItem = () => ({
        _key: Date.now() + Math.random(),
        title: '',
        imgUrl: '',
        jumpUrl: '',
        showCateId: undefined,
        loading: false
    });

    // 计算选项是否应被禁用
    const isOptionDisabled = (value, currentIndex) => {
        return items.value.some((item, index) => {
            if (index === currentIndex) return false;
            return item.showCateId === value;
        });
    };

    const fetchDefaultOptions = async () => {
        try {
            const res = await request.get('/book/showIndex/list', {
                params: { cateType: 1, pageNum: 1, pageSize: 200 }
            });
            const list = res.data?.rows || res.data || [];
            defaultOptions.value = list.map((item) => ({
                value: item.id,
                label: item.showName,
                raw: item
            }));
        } catch (e) {
            console.error('Failed to fetch default options', e);
            defaultOptions.value = [];
        }
    };

    const remoteMethod = async (query, index) => {
        const item = items.value[index];
        const key = item._key;

        if (query) {
            item.loading = true;
            try {
                const res = await request.get('/book/showIndex/list', {
                    params: {
                        showName: query,
                        cateType: 1,
                        pageNum: 1,
                        pageSize: 200
                    }
                });
                const list = res.data?.rows || res.data || [];
                itemOptions.value[key] = list.map((item) => ({
                    value: item.id,
                    label: item.showName,
                    raw: item
                }));
            } catch (e) {
                console.error(e);
                itemOptions.value[key] = [];
            } finally {
                item.loading = false;
            }
        } else {
            // Restore default + selected
            const currentSelectedId = item.showCateId;
            let currentOption = null;

            // Find in current options or defaults
            if (currentSelectedId) {
                currentOption =
                    (itemOptions.value[key] || []).find(
                        (opt) => opt.value === currentSelectedId
                    ) ||
                    defaultOptions.value.find(
                        (opt) => opt.value === currentSelectedId
                    );

                if (!currentOption && item.title) {
                    currentOption = {
                        value: currentSelectedId,
                        label: item.title,
                        raw: { imgUrl: item.imgUrl, showName: item.title }
                    };
                }
            }

            const merged = [...defaultOptions.value];
            if (
                currentOption &&
                !merged.some((opt) => opt.value === currentOption.value)
            ) {
                merged.unshift(currentOption);
            }
            itemOptions.value[key] = merged;
        }
    };

    const handleSelectChange = (val, index) => {
        const item = items.value[index];
        const key = item._key;

        if (!val) {
            item.showCateId = undefined;
            return;
        }

        const opts = itemOptions.value[key] || defaultOptions.value;
        const selectedOption = opts.find((opt) => opt.value === val);

        if (selectedOption) {
            const raw = selectedOption.raw;
            item.imgUrl = raw.imgUrl;
            item.title = raw.showName;
            item.showCateId = raw.id;
            item.jumpUrl = `/pages-sell/pages/topic?id=${raw.id}`;
        }
    };

    const handleAdd = () => {
        if (items.value.length < props.limit) {
            const newItem = createItem();
            items.value.push(newItem);
            // Initialize options for new item
            itemOptions.value[newItem._key] = [...defaultOptions.value];
        }
    };

    const handleRemove = (index) => {
        const item = items.value[index];
        delete itemOptions.value[item._key];
        items.value.splice(index, 1);
    };

    const handleOpen = async () => {
        await fetchDefaultOptions();
        itemOptions.value = {}; // Reset options map

        try {
            const res = await request.get('/book/showIndex/getInfoByPosition', {
                params: { position: props.position }
            });
            const list = res.data?.data || [];

            if (list.length > 0) {
                items.value = list.map((remote) => ({
                    _key: Date.now() + Math.random(),
                    title: remote.title || '',
                    imgUrl: remote.imgUrl || '',
                    jumpUrl: remote.jumpUrl || '',
                    showCateId: remote.showCateId,
                    loading: false
                }));
            } else {
                items.value = []; // Start empty or with one? Let's start with one empty if list is empty
                if (items.value.length === 0) {
                    items.value.push(createItem());
                }
            }

            // Initialize options for each item
            items.value.forEach((item) => {
                const merged = [...defaultOptions.value];
                if (item.showCateId) {
                    const exists = merged.some(
                        (opt) => opt.value === item.showCateId
                    );
                    if (!exists && item.title) {
                        merged.unshift({
                            value: item.showCateId,
                            label: item.title,
                            raw: { imgUrl: item.imgUrl, showName: item.title }
                        });
                    }
                }
                itemOptions.value[item._key] = merged;
            });
        } catch (e) {
            console.error(e);
            items.value = [createItem()];
            itemOptions.value[items.value[0]._key] = [...defaultOptions.value];
        }
    };

    const handleConfirm = async () => {
        loading.value = true;
        try {
            const showIndexInfoList = items.value
                .filter((item) => item.imgUrl)
                .map((item, index) => ({
                    imgUrl: item.imgUrl,
                    jumpUrl: item.jumpUrl,
                    showCateId: item.showCateId || 0,
                    orderNum: index,
                    title: item.title
                }));

            await request.post('/book/showIndex/updateIndex', {
                position: props.position,
                showIndexInfoList
            });

            EleMessage.success('保存成功');
            visible.value = false;
            emit('success');
        } catch (e) {
            console.error(e);
            EleMessage.error(e.message || '保存失败');
        } finally {
            loading.value = false;
        }
    };
</script>

<style scoped>
    .topic-edit {
        max-height: 60vh;
        overflow-y: auto;
        padding: 10px;
        overflow-x: hidden;
    }
</style>
