<template>
    <div class="crossing-multi-view">
        <!-- 展开模式下的返回栏 -->
        <div v-if="expandedId" class="expand-toolbar">
            <span class="back-btn" @click="exitExpand">&larr; 返回多路口视图</span>
        </div>

        <draggable
            v-model="localSlots"
            class="multi-view-grid"
            :class="gridClass"
            :style="gridStyle"
            :animation="300"
            :swap-threshold="0.5"
            ghost-class="drag-ghost"
            chosen-class="drag-chosen"
            drag-class="drag-active"
            handle=".drag-handle"
            :disabled="!!expandedId"
            @end="onDragEnd"
        >
            <div
                v-for="(slot, index) in visibleSlots"
                :key="slot.type === 'empty' ? slot.data.id : 'panel-' + slot.data.id"
                class="grid-cell"
                :class="{ 'empty-cell': slot.type === 'empty' }"
                @dblclick="slot.type === 'panel' && handleDblClick(slot)"
            >
                <template v-if="slot.type === 'panel'">
                    <div class="cell-header">
                        <div class="drag-handle" title="拖拽换位" v-if="!expandedId">
                            <span class="drag-icon">&#x2807;</span>
                        </div>
                        <CrossingDetailHeader
                            :currentRoute="slot.headerData ? { ...slot.headerData.currentRoute, name: slot.data.label || slot.headerData.currentRoute.name } : { name: slot.data.label || slot.data.name }"
                            :intersectionData="slot.headerData ? slot.headerData.intersectionData : {}"
                            :cycleLength="slot.headerData ? slot.headerData.cycleLength : 0"
                        />
                        <span class="cell-close" @click.stop="handleRemove(slot.data.id)">✕</span>
                    </div>
                    <div class="cell-body">
                        <CrossingDetailPanel
                            :id="slot.data.id"
                            v-bind="slot.data"
                            :preloadedData="slot.headerData"
                        />
                    </div>
                </template>
                <template v-else>
                    <div class="empty-placeholder">暂无路口</div>
                </template>
            </div>
        </draggable>
    </div>
</template>

<script>
import draggable from 'vuedraggable';
import CrossingDetailPanel from '@/components/ui/CrossingDetailPanel.vue';
import CrossingDetailHeader from '@/components/ui/CrossingDetailHeader.vue';
import { apiGetCrossingDetailData } from '@/api';

export default {
    name: 'CrossingMultiView',
    components: {
        draggable,
        CrossingDetailPanel,
        CrossingDetailHeader
    },
    props: {
        crossings: {
            type: Array,
            default: () => []
        },
        maxSlots: {
            type: Number,
            default: 1,
            validator: v => v >= 1 && v <= 6
        },
        onRemove: {
            type: Function,
            default: null
        },
        onReorder: {
            type: Function,
            default: null
        }
    },
    data() {
        return {
            localSlots: [],
            expandedId: null,
            rebuildVersion: 0
        };
    },
    computed: {
        // 实际面板数量
        panelCount() {
            return this.crossings.length;
        },
        visibleSlots() {
            if (this.expandedId) {
                const found = this.localSlots.find(
                    s => s.data && s.data.id === this.expandedId
                );
                return found ? [found] : this.localSlots;
            }
            if (this.panelCount <= 1) return this.localSlots;
            // 2个以上时，补空占位到 maxSlots
            const slots = [...this.localSlots];
            while (slots.length < this.maxSlots) {
                slots.push({ type: 'empty', data: { id: '__empty_' + slots.length } });
            }
            return slots;
        },
        // 1个→全屏, 2个以上→按 maxSlots 布局
        gridCols() {
            if (this.expandedId) return 1;
            if (this.panelCount <= 1) return 1;
            return 2;
        },
        gridRows() {
            if (this.expandedId) return 1;
            if (this.panelCount <= 1) return 1;
            return Math.ceil(this.maxSlots / 2);
        },
        gridStyle() {
            return {
                gridTemplateColumns: `repeat(${this.gridCols}, 1fr)`,
                gridTemplateRows: `repeat(${this.gridRows}, 1fr)`
            };
        },
        gridClass() {
            if (this.expandedId) return 'slots-1';
            if (this.panelCount <= 1) return 'slots-1';
            return 'slots-' + this.maxSlots;
        }
    },
    watch: {
        crossings: {
            handler() { this.rebuildSlots(); },
            deep: true,
            immediate: true
        },
        maxSlots() { this.rebuildSlots(); }
    },
    methods: {
        async rebuildSlots() {
            // 保留已加载过的 headerData，避免重复请求
            const oldMap = {};
            this.localSlots.forEach(s => {
                if (s.data && s.headerData) oldMap[s.data.id] = s.headerData;
            });
            this.localSlots = this.crossings.map(c => ({
                type: 'panel', data: c, headerData: oldMap[c.id] || c._preloadedData || null
            }));
            // 如果展开的路口被外部移除了，退出展开
            if (this.expandedId) {
                const stillExists = this.crossings.find(c => c.id === this.expandedId);
                if (!stillExists) this.expandedId = null;
            }
            this.$nextTick(() => {
                window.dispatchEvent(new Event('resize'));
            });
            // 只对还没有 headerData 的路口发请求
            const needLoad = this.localSlots
                .map((s, i) => (!s.headerData ? { index: i, id: s.data.id } : null))
                .filter(Boolean);
            if (needLoad.length === 0) return;
            const version = ++this.rebuildVersion;
            const results = await Promise.all(
                needLoad.map(item => apiGetCrossingDetailData(item.id, { iconMode: 'simple' }).catch(() => null))
            );
            if (version !== this.rebuildVersion) return;
            results.forEach((data, i) => {
                const slotIndex = needLoad[i].index;
                if (data && this.localSlots[slotIndex]) {
                    this.$set(this.localSlots[slotIndex], 'headerData', data);
                }
            });
        },

        handleDblClick(slot) {
            if (slot.type !== 'panel') return;
            if (this.panelCount <= 1) return;

            const id = slot.data.id;
            if (this.expandedId === id) {
                this.expandedId = null;
            } else {
                this.expandedId = id;
            }
            this.$nextTick(() => {
                window.dispatchEvent(new Event('resize'));
            });
        },

        exitExpand() {
            this.expandedId = null;
            this.$nextTick(() => {
                window.dispatchEvent(new Event('resize'));
            });
        },

        handleRemove(id) {
            if (this.expandedId === id) {
                this.expandedId = null;
            }
            if (typeof this.onRemove === 'function') {
                this.onRemove(id);
            }
        },

        onDragEnd() {
            const newOrder = this.localSlots
                .filter(s => s.type === 'panel')
                .map(s => s.data);
            if (typeof this.onReorder === 'function') {
                this.onReorder(newOrder);
            }
            this.$nextTick(() => {
                window.dispatchEvent(new Event('resize'));
            });
        }
    }
};
</script>

<style scoped>
.crossing-multi-view {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* ===== 展开模式返回栏 ===== */
.expand-toolbar {
    flex-shrink: 0;
    padding: 6px 12px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.back-btn {
    color: #4da8ff;
    cursor: pointer;
    font-size: 13px;
    user-select: none;
}
.back-btn:hover {
    text-decoration: underline;
}

/* ===== 网格容器 ===== */
.multi-view-grid {
    display: grid;
    gap: 4px;
    width: 100%;
    flex: 1;
    min-height: 0;
}

.grid-cell {
    overflow: hidden;
    min-width: 0;
    min-height: 0;
    position: relative;
    display: flex;
    flex-direction: column;
}

/* ===== 面板标题栏 ===== */
.cell-header {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    padding: 4px 10px;
    background: linear-gradient(180deg, rgba(65, 115, 205, 0.4) 0%, transparent 100%);
    color: #e0e6f1;
    font-size: 13px;
    gap: 6px;
}

.cell-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    letter-spacing: 1px;
}

.cell-close {
    cursor: pointer;
    opacity: 0.6;
    font-size: 14px;
    flex-shrink: 0;
}
.cell-close:hover {
    opacity: 1;
}

.cell-body {
    flex: 1;
    min-height: 0;
    overflow: hidden;
    padding: 6px 10px 10px 10px;
}

/* ===== 拖拽把手 ===== */
.drag-handle {
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
    opacity: 0;
    transition: opacity 0.2s;
    flex-shrink: 0;
}

.cell-header:hover .drag-handle {
    opacity: 1;
}

.drag-handle:active {
    cursor: grabbing;
}

.drag-icon {
    color: rgba(255, 255, 255, 0.8);
    font-size: 14px;
    line-height: 1;
}

/* ===== 拖拽状态样式 ===== */
.drag-ghost {
    opacity: 0.3;
    border: 2px dashed rgba(77, 168, 255, 0.6);
    border-radius: 4px;
}

.drag-chosen {
    box-shadow: 0 0 20px rgba(77, 168, 255, 0.4);
}

.drag-active {
    opacity: 0.9;
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
    border-radius: 4px;
}

/* ===== 空占位格 ===== */
.empty-cell {
    border: 1px dashed rgba(255, 255, 255, 0.15);
    border-radius: 4px;
}

.empty-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: rgba(255, 255, 255, 0.2);
    font-size: 14px;
    user-select: none;
}

</style>
