<template>
    <div class="default-main">
        <TableHeader :showSearch="false" v-show="flag">
            <template v-slot:select>
                <el-form-item label="日期">
                    <DatePicker
                        ref="datePickerRef"
                        :nextFlag="false"
                        :theCurrentTime="true"
                        @change="handleDatePickerChange"
                    ></DatePicker>
                </el-form-item>
            </template>
            <template v-slot:operation>
                <el-button type="primary" icon="el-icon-Edit" @click="editd">编辑</el-button>
                <!-- <el-button type="primary" icon="el-icon-Tools" @click="settings">设置</el-button> -->
            </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 as LayoutItem).icon" />
                            {{ (item as LayoutItem).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 as LayoutItem).component"
                            v-if="(item as LayoutItem).component"
                            class="pd10"
                            :key="key"
                            :timeValue="datePickerRef?.timeValue || 3"
                            :height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
                            :width="rowWidth * item.w - 30 + 'px'"
                            :timeKey="(item as LayoutItem).timeKey"
                            :interval="datePickerRef?.interval"
                            :w="item.w"
                            :h="item.h"
                        />
                        <div v-else class="pd10">组件加载失败...</div>
                    </div>
                </div>
            </template>
        </GridLayout>
        <!-- 设置 -->
        <RoutingConfig ref="RoutingConfigRef" />
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, markRaw, onUnmounted, computed, defineAsyncComponent, type Component } from 'vue'
import TableHeader from '@/components/table/header/index.vue'
import { GridLayout } from 'grid-layout-plus'
import DatePicker from '@/components/form/datePicker/index.vue'
import { useDebounceFn } from '@vueuse/core'
import { queryActivatePage, queryByPagePath } from '@/api/system-boot/csstatisticalset'
import RoutingConfig from '@/views/pqs/cockpit/homePage/components/routingConfig.vue'
import { useRouter, useRoute } from 'vue-router'
import { useTimeCacheStore } from '@/stores/timeCache'
const { push } = useRouter()
const datePickerRef = ref()
const router = useRouter()
const route = useRoute()
const timeCacheStore = useTimeCacheStore()

defineOptions({
    // name: 'dashboard/index'
})
// 定义类型
interface LayoutItem {
    x: number
    y: number
    w: number
    h: number
    timeKey: number | string
    i: string | number
    name: string
    path: string
    icon?: string // 新增 icon 可选字段
    component?: Component | string
    loading?: boolean
    error?: any
}
const RoutingConfigRef = ref()
const key = ref(0)
const img = new URL(`@/assets/img/amplify.png`, import.meta.url).href
const img1 = new URL(`@/assets/img/reduce.png`, import.meta.url).href
// 响应式数据
const rowHeight = ref(0)
const rowWidth = ref(0)
const layout: any = ref([
    // {
    //     x: 4,
    //     y: 0,
    //     w: 4,
    //     h: 2,
    //     i: '1',
    //     name: '',
    //     path: '/src/views/pqs/runManage/assessment/components/uese/index.vue'
    // },
])
const layoutCopy: any = ref([])
const flag = ref(true)
// 组件映射
const componentMap = reactive(new Map<string, Component | string>())
const dataList: any = ref({})
// 获取主内容区域高度
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() - 77 + (flag.value ? 0 : 56)) / 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: any, index: number) => ({
            ...item,
            i: item.i || index, // 确保有唯一标识
            component: registerComponent(item.path)
        }))
    }
    console.log('🚀 ~ zoom ~ layout.value:', layout.value)

    flag.value = !flag.value

    initRowHeight()
    key.value += 1
}
// 计算组件高度
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 fetchLayoutData = async () => {
    try {
        // const { data } = await queryByPagePath({ pagePath: router.currentRoute.value.name })
        // dataList.value = data
        dataList.value = {
            createBy: 'e6a67ccbe789493687766c4304fcb228',
            createTime: '2025-11-26 08:43:56',
            updateBy: 'e6a67ccbe789493687766c4304fcb228',
            updateTime: '2025-11-26 08:43:56',
            id: 'e8218545cc11e32d5d6b87c92fdd0fbc',
            pageName: '测试',
            thumbnail: '',
            remark: '',
            containerConfig:
                '[{"x":0,"y":0,"w":6,"h":3,"i":0.9274640143002512,"name":"终端在线率","path":"/src/components/cockpit/onlineRate/index.vue","icon":"local-审计列表","timeKey":"3","moved":false},{"x":6,"y":0,"w":6,"h":3,"i":0.9154814002445102,"name":"监测点数据完整性","path":"/src/components/cockpit/integrity/index.vue","icon":"local-告警中心","timeKey":"3","moved":false},{"x":0,"y":3,"w":6,"h":3,"i":0.6560899767923003,"name":"终端运行评价","path":"/src/components/cockpit/terminalEvaluation/index.vue","icon":"local-稳态指标超标明细","timeKey":"3","moved":false},{"x":6,"y":3,"w":6,"h":3,"i":0.5812302648025226,"name":"异常数据清洗","path":"/src/components/cockpit/dataCleaning/index.vue","icon":"local-区域暂态评估","timeKey":"3","moved":false}]',
            sort: 100,
            state: 1,
            pagePath: 'dashboard/index6',
            pathName: null,
            routeName: '/src/views/pqs/cockpit/homePage/index.vue',
            icon: ''
        }
        const parsedLayout = JSON.parse(dataList.value.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))
        initRowHeight()
    } catch (error) {
        console.error('获取布局数据失败:', error)
        // 可以添加错误提示逻辑
    }
}

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

// 修改
const editd = (e: any) => {
    if (dataList.value?.id) {
        push(`/admin/cockpit/popup?id=${dataList.value?.id}&&path=${String(router.currentRoute.value.name)}`)
    } else {
        push(`/admin/cockpit/popup?path=${String(router.currentRoute.value.name)}`)
    }
}
// 设置
const settings = () => {
    RoutingConfigRef.value.open()
}

// 处理 DatePicker 值变化事件
const handleDatePickerChange = (value: any) => {
    // 将值缓存到 timeCache
    if (value) {
        timeCacheStore.setCache(route.path, value.interval, value.timeValue)
    }
}

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

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

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

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

:deep(.vgl-item:not(.vgl-item--placeholder)) {
    background-color: #ffffff;
    border-radius: 4px;
    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;
    }
}
</style>
