<template>

    <a-menu v-model:selected-keys="selectedKey"

        :default-open-keys="selectedKey">

        <template v-for="menu in menuData" :key="menu.key">

            <a-sub-menu v-if="menu.children && menu.children.length" :key="menu.key">

                <template #icon>

                    <component :is="menu.icon"></component>

                </template>

                <template #title>{{ menu.label }}</template>

                <a-menu-item v-for="child in menu.children" :key="child.key" :disabled="child.disabled"

                    @click="$router.push(child.key)">

                    {{ child.label }}

                </a-menu-item>

            </a-sub-menu>



            <a-menu-item v-else :key="menu.key" :disabled="menu.disabled" @click="$router.push(menu.key)">

                <template #icon>

                    <component :is="menu.icon"></component>

                </template>

                {{ menu.label }}

            </a-menu-item>

        </template>

    </a-menu>

</template>



<script setup>

import { onMounted, ref, watch } from 'vue'

import { routes } from '@/router'

import { useUserStore } from '@/store/modules/user'

import { useRouteListener } from '@/utils/route-listener'

import { isElectron } from '../../utils/electron'

import { canShowInMenu } from '@/utils/permission'



const userStore = useUserStore()

const user = ref({})

const electron = ref(false)

const menuData = ref([])



const { selectedKey } = useRouteListener()



const checkEnv = (route) => {

    if (!route.meta) return true

    if (route.meta.onlyWeb) return !electron.value

    if (route.meta.onlyElectron) return !!electron.value

    return true

}



const joinRoutePath = (parentPath, routePath) => {

    const base = parentPath.endsWith('/') ? parentPath.slice(0, -1) : parentPath

    const segment = routePath.startsWith('/') ? routePath : `/${routePath}`

    return `${base}${segment}`.replace(/\/+/g, '/')

}



const generateMenu = (routeList, parentPath = '') => {

    return routeList

        .filter((route) => canShowInMenu(route, user.value) && checkEnv(route))

        .map((route) => {

            const fullPath = joinRoutePath(parentPath, route.path)

            const menu = {

                key: fullPath,

                label: route.meta?.title || route.name,

                icon: route.meta?.icon || '',

                disabled: route.meta?.disabled || false

            }



            if (route.children && route.children.length > 0) {

                const childPrefix = fullPath.endsWith('/') ? fullPath : `${fullPath}/`

                menu.children = generateMenu(route.children, childPrefix)

                if (menu.children.length === 0) return null

                if (route.meta?.flatMenu && menu.children.length === 1) {

                    const only = menu.children[0]

                    return {

                        ...only,

                        icon: menu.icon || only.icon,

                        label: menu.label || only.label

                    }

                }

            }



            return menu

        })

        .filter(Boolean)

}



const refreshMenu = async () => {

    user.value = await userStore.getInfo()

    if ((!user.value.permissionCodes || user.value.permissionCodes.length === 0) && userStore.refreshPermissions) {

        await userStore.refreshPermissions()

        user.value = userStore.$state

    }

    electron.value = isElectron()

    menuData.value = generateMenu(routes)

}



onMounted(refreshMenu)



watch(

    () => [userStore.uuid, userStore.session],

    () => {

        refreshMenu()

    }

)

</script>

