<template>
    <div class="default-main">
        <!-- <div class=" layoutHeader">
            <div class="title">{{title}}</div>
            <back-component />
        </div> -->
        <TableHeader :showSearch="false">
            <template v-slot:select>
                <el-form-item label="日期">
                    <DatePicker ref="datePickerRef" :nextFlag="false" :theCurrentTime="true"></DatePicker>
                </el-form-item>
            </template>
            <template v-slot:operation>
                <back-component />
            </template>
        </TableHeader>
        <GridLayout
            v-model:layout="layout"
            :row-height="rowHeight"
            :is-resizable="false"
            :is-draggable="false"
            :responsive="false"
            :vertical-compact="false"
            prevent-collision
            :col-num="12"
        >
            <template #item="{ item }">
                <div class="box">
                    <div class="title">
                        <div style="display: flex; align-items: center">
                            <Icon class="HelpFilled" :name="item.icon" />
                            {{ item.name }}
                        </div>
                        <!-- <FullScreen class="HelpFilled" style="cursor: pointer" @click="zoom(item)" /> -->
                        <img :src="flag ? img : img1" style="cursor: pointer; height: 16px" @click="zoom(item)" />
                    </div>
                    <div>
                        <component
                            :is="item.component"
                            v-if="item.component"
                            class="pd10"
                            :key="key"
                            :timeValue="datePickerRef.timeValue"
                            :height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
                            :width="rowWidth * item.w - 30 + 'px'"
                            :timeKey="item.timeKeys"
                        />
                        <div v-else class="pd10">组件加载失败...</div>
                    </div>
                </div>
            </template>
        </GridLayout>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, markRaw, onUnmounted, defineAsyncComponent, type Component } from 'vue'
import { GridLayout } from 'grid-layout-plus'
import { useDebounceFn } from '@vueuse/core'
import { useRouter } from 'vue-router'
import TableHeader from '@/components/table/header/index.vue'
import DatePicker from '@/components/form/datePicker/index.vue'
import BackComponent from '@/components/icon/back/index.vue'
import { queryById } from '@/api/system-boot/csstatisticalset'
import { HelpFilled, FullScreen } from '@element-plus/icons-vue'
import { useRoute } from 'vue-router'
// defineOptions({
//     name: 'cockpit/view'
// })
const { query } = useRoute()
// 定义类型
interface LayoutItem {
    x: number
    y: number
    w: number
    h: number
    i: string | number
    name: string
    path: string
    component?: Component | string
    loading?: boolean
    error?: any
}
const datePickerRef = ref()
const title = ref('')
const key = ref(0)
const img = new URL(`@/assets/img/amplify.png`, import.meta.url)
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url)
// 响应式数据
const rowHeight = ref(0)
const rowWidth = ref(0)
const layout: any = ref<LayoutItem[]>([
    // {
    //     x: 4,
    //     y: 0,
    //     w: 4,
    //     h: 2,
    //     i: '1',
    //     name: '',
    //     path: '/src/views/pqs/runManage/assessment/components/uese/index.vue'
    // },
])
const layoutCopy = ref<LayoutItem[]>([])
const flag = ref(true)
// 组件映射
const componentMap = reactive(new Map<string, Component | string>())

// 获取主内容区域高度
const getMainHeight = () => {
    const elMain = document.querySelector('.el-main')
    return (elMain?.offsetHeight || 0) - 70
}
// 获取主内容区域高度
const getMainWidth = () => {
    const elMain = document.querySelector('.el-main')
    return (elMain?.offsetWidth || 0) - 20
}

// 初始化行高
const initRowHeight = () => {
    rowHeight.value = Math.max(0, (getMainHeight() - 72) / 6)
    rowWidth.value = Math.max(0, getMainWidth() / 12)
}

// 动态注册组件
const registerComponent = (path: string): Component | string | null => {
    if (!path) return null

    const cacheKey = path

    // 使用缓存的组件
    if (componentMap.has(cacheKey)) {
        return componentMap.get(cacheKey)!
    }

    try {
        // 动态导入组件
        const modules = import.meta.glob('@/**/*.vue')
        if (!modules[path]) {
            console.error(`组件加载失败: ${path}`)
            return null
        }

        const AsyncComponent = defineAsyncComponent({
            loader: modules[path],
            loadingComponent: () => h('div', '加载中...'),
            errorComponent: ({ error }) => h('div', `加载错误: ${error.message}`),
            delay: 200,
            timeout: 10000
        })

        // 保存到映射中
        componentMap.set(cacheKey, markRaw(AsyncComponent))
        return AsyncComponent
    } catch (error) {
        console.error('注册组件失败:', error)
        return null
    }
}
// 缩放
const zoom = (value: any) => {
    if (flag.value) {
        layout.value = [{ ...value, x: 0, y: 0, w: 12, h: 6 }]
    } else {
        layout.value = layoutCopy.value.map((item, index) => ({
            ...item,
            i: item.i || index, // 确保有唯一标识
            component: registerComponent(item.path)
        }))
    }
    flag.value = !flag.value
    key.value += 1
}
// 获取布局数据
const fetchLayoutData = async () => {
    try {
        const { data } = await queryById({ id: query.id })
        title.value = data.pageName + '_预览'
        const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
        // 处理布局数据
        layout.value = parsedLayout.map((item, index) => ({
            ...item,
            i: item.i || index, // 确保有唯一标识
            component: registerComponent(item.path)
        }))
        layoutCopy.value = JSON.parse(JSON.stringify(layout.value))
    } catch (error) {
        console.error('获取布局数据失败:', error)
        // 可以添加错误提示逻辑
    }
}
// 计算组件高度
const seRowHeight = (value: any) => {
    if (value == 6) return 0
    if (value == 5) return 12
    if (value == 4) return 20
    if (value == 3) return 30
    if (value == 2) return 40
    if (value == 1) return 50
    return 0
}

// 窗口大小变化处理 - 使用防抖
const handleResize = useDebounceFn(() => {
    initRowHeight()
    key.value += 1
}, 200)

// 生命周期钩子
onMounted(() => {
    initRowHeight()
    fetchLayoutData()

    // 添加窗口大小变化监听器
    window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
    // 移除监听器防止内存泄漏
    window.removeEventListener('resize', handleResize)
})
</script>

<style lang="scss" scoped>
.vgl-layout {
    background-color: #f8f9fa;
    border-radius: 5px;
    overflow: hidden;
}

:deep(.vgl-item:not(.vgl-item--placeholder)) {
    background-color: #ffffff;
    border-radius: 5px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
    transition: all 0.3s ease;
}

:deep(.vgl-item:hover:not(.vgl-item--placeholder)) {
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.12);
}

:deep(.vgl-item--static) {
    background-color: #f0f2f5;
}

.text {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    color: #606266;
}

:deep(.vgl-item) {
    overflow: hidden;
}

.box {
    overflow: hidden;

    .title {
        border-bottom: 1px solid #000;
        font-size: 14px;
        height: 30px;
        font-weight: 600;
        padding: 0px 10px;
        color: #fff;
        background-color: var(--el-color-primary);
        display: flex;
        align-items: center;
        justify-content: space-between;
    }

    .HelpFilled {
        height: 16px;
        width: 16px;
        color: #fff !important;
        margin-right: 5px;
    }
}

.layoutHeader {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 20px;
    font-size: 16px;

    .title {
        font-weight: 600;
    }
}
</style>
