<template>
    <div class="default-main">
        <TableHeader :showSearch="false" v-show="flag">
            <template v-slot:select>
                <el-form-item label="日期" v-show="layout?.length != 1">
                    <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" v-if="hasAdmin || adminInfo.id == userId" @click="editd">
                    编辑
                </el-button>
                <el-button
                    type="primary"
                    icon="el-icon-Tools"
                    @click="settings"
                    v-if="router.currentRoute.value.name == 'dashboard/index'"
                >
                    驾驶舱管理
                </el-button>
            </template>
        </TableHeader>
        <GridLayout
            v-model:layout="layout"
            :row-height="rowHeight"
            :is-resizable="false"
            :is-draggable="false"
            :responsive="false"
            :vertical-compact="false"
            :col-num="12"
            :style="{
                transform: `scale(${zoom})`,
                transformOrigin: 'top left',
                width: zoom !== 1 ? `${100 / zoom}%` : '100%'
            }"
        >
            <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="setZoom(item)" /> -->
                        <span style="display: flex; align-items: center">
                            <img
                                :src="!flag && (item as LayoutItem).i === zoomedId ? img1 : img"
                                style="cursor: pointer; height: 16px"
                                @click="setZoom(item as LayoutItem)"
                            />
                        </span>
                    </div>
                    <div>
                        <component
                            :is="(item as LayoutItem).component"
                            v-if="(item as LayoutItem).component"
                            :key="(item as LayoutItem).i"
                            class="pd10"
                            :timeValue="datePickerRef?.timeValue"
                            :height="rowHeight * item.h - seRowHeight(item.h) + 'px'"
                            :width="rowWidth * item.w - 30 + 'px'"
                            :timeKey="(item as LayoutItem).timeKeys"
                            :interval="datePickerRef?.interval"
                            :w="item.w"
                            :h="item.h"
                            :flag="flag"
                        />
                        <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, defineAsyncComponent, nextTick, 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'
import { Sort } from '@element-plus/icons-vue'
const { push } = useRouter()
const datePickerRef = ref()
const router = useRouter()
const route = useRoute()
const timeCacheStore = useTimeCacheStore()
import { useAdminInfo } from '@/stores/adminInfo'
const adminInfo = useAdminInfo()
const hasAdmin = adminInfo.roleCode.some(item => item.includes('operation_manager') || item.includes('root'))||
    adminInfo.userType == 1
defineOptions({
    // name: 'dashboard/index'
})

// 定义类型
interface LayoutItem {
    x: number
    y: number
    w: number
    h: number
    timeKeys: any
    i: string | number
    name: string
    path: string
    icon?: string // 新增 icon 可选字段
    component?: Component | string
    loading?: boolean
    error?: any
}
const zoom = ref(1)
const RoutingConfigRef = ref()
const userId = ref('')
const zoomedId = ref<string | number | null>(null)
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') as HTMLElement | null
    zoom.value =
        layoutCopy.value.length <= 1 || !flag.value
            ? 1
            : (elMain?.offsetHeight ?? 0) > 1080
              ? 1
              : (elMain?.offsetHeight ?? 0) / 1080
    // console.log('🚀 ~ getMainHeight ~ elMain:', elMain?.offsetHeight)
    return ((elMain?.offsetHeight || 0) - 70) / zoom.value
}
// 获取主内容区域高度
const getMainWidth = () => {
    const elMain = document.querySelector('.el-main') as HTMLElement | null
    return ((elMain?.offsetWidth || 0) - 20) / zoom.value
}

// 初始化行高
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
    }
}

// 根据 layoutCopy 构建布局，放大时保留全部组件实例仅调整坐标
const buildLayoutFromCopy = (zoomItem?: LayoutItem | null) => {
    return layoutCopy.value.map((item: LayoutItem) => {
        const entry: LayoutItem = {
            ...item,
            component: registerComponent(item.path) || undefined
        }
        if (zoomItem != null && String(item.i) === String(zoomItem.i)) {
            return { ...entry, x: 0, y: 0, w: 12, h: 6 }
        }
        if (zoomItem != null) {
            return { ...entry, x: -100, y: -100, w: 1, h: 1 }
        }
        return entry
    })
}

// 缩放
const setZoom = async (value: LayoutItem) => {
    if (flag.value) {
        zoomedId.value = value.i
        layout.value = buildLayoutFromCopy(value)
    } else {
        zoomedId.value = null
        layout.value = buildLayoutFromCopy()
    }

    flag.value = !flag.value
    await nextTick()
    initRowHeight()
}
// 计算组件高度
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 })
        userId.value = data.userId
        dataList.value = data
        const parsedLayout = JSON.parse(data.containerConfig || '[]') as LayoutItem[]
        // 处理布局数据
        layoutCopy.value = parsedLayout.map((item, index) => ({
            ...item,
            i: item.i ?? index
        }))
        layout.value = buildLayoutFromCopy()
        if (layout.value.length == 1) {
            setZoom(layout.value[0])
        }

        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>
