<template>
    <div class="paas-menu-container">
        <div class="paas-menu-header">
            <div v-if="logoSrc" class="paas-menu-logo">
                <img :src="logoSrc" :alt="logoAlt" />
            </div>
            <div class="paas-menu-system-name">
                <label>{{ $store.header.system.deviceName }}</label>
            </div>
        </div>
        <div class="paas-menu-scroll-wrapper">
            <a-menu ref="menus" v-bind="$attrs" :theme="theme" :selectedKeys="selectedKeys" :open-keys="openKeys"
                @openChange="onOpenChange" :inline-collapsed="inlineCollapsed" :mode="mode">
                <template v-for="item in data" :key="item.id">
                    <a-sub-menu v-if="item.children && item.children.length" :key="item.key" :title="item.title"
                        :icon="renderIcon(item)">
                        <a-menu-item v-for="child in item.children" :key="child.key" @click="menuSelect(child)"
                            :icon="renderIcon(child)">
                            <span>{{ child.title }}</span>
                        </a-menu-item>
                    </a-sub-menu>
                    <a-menu-item v-else :key="item.key || ''" @click="menuSelect(item)" :icon="renderIcon(item)">
                        <span>{{ item.title }}</span>
                    </a-menu-item>
                </template>
            </a-menu>
        </div>
    </div>
</template>

<script>
import { Menu } from 'ant-design-vue';
import { h, resolveComponent } from 'vue';

export default {
    name: 'PaasMenu',
    components: {
        AMenu: Menu,
        ASubMenu: Menu.SubMenu,
        AMenuItem: Menu.Item,
    },
    props: {
        url: String,
        logoSrc: String,
        logoAlt: {
            type: String,
            default: 'System Logo'
        },
        disabled: {
            type: Boolean,
            default: false,
        },
        theme: {
            type: String,
            default: 'light',
        },
        selected: {
            type: String,
            default: '',
        },
        mode: {
            type: String,
            default: 'inline',
        },
        inlineCollapsed: {
            type: Boolean,
            default: false,
        }
    },
    data() {
        return {
            selectedKeys: this.selected ? [this.selected] : [],
            selectValue: '',
            selectMenuOpend: false,
            hostname: window.location.protocol + '//' + window.location.host,
        };
    },
    computed: {
        current() {
            return this.$store.menus.current;
        },
        menuOptions() {
            return this.$store.menus.menuOptions || [];
        },
        openKeys() {
            return this.$store.menus.openKeys;
        },
        data() {
            return this.$store.menus.data;
        },
    },
    watch: {
        selected(newValue) {
            this.selectedKeys = newValue ? [newValue] : [];
        },
        url(newValue) {
            if (newValue) {
                this.$post(newValue).then((res) => {
                    this.$store.setMenuData(res.data.data);
                    this.autoSelectMenu();
                });
            } else if (this.data.length > 0) {
                this.autoSelectMenu();
            }
        },
        data(newVal) {
            if (newVal.length > 0 && !this.selectedKeys.length) {
                this.autoSelectMenu();
            }
        },
    },
    beforeUnmount() {
        this.$bus.off('selectAndOpenMenu');
    },
    mounted() {
        if (this.$store.loginFlag && this.data.length === 0) {
            this.$post(this.url).then((res) => {
                this.$store.setMenuData(res.data.data);
                this.autoSelectMenu();
            });
        } else if (this.data.length > 0) {
            this.autoSelectMenu();
        }
        this.$bus.on('selectAndOpenMenu', (data) => {
            this.selectAndOpenMenu(data);
        });
    },
    methods: {
        // 渲染图标的方法
        renderIcon(item) {
            let iconName = '';
            if (!item.icon) {
                // 如果没有指定图标，则根据是否选中返回不同图标
                iconName = this.selectedKeys.includes(item.key) ? 'FolderOpenOutlined' : 'FolderOutlined';
            } else {
                iconName = item.icon;
            }

            // 直接返回解析的组件
            try {
                const IconComponent = resolveComponent(iconName);
                return () => h(IconComponent);
            } catch (e) {
                // 如果图标不存在，返回空的渲染函数
                return null;
            }
        },

        autoSelectMenu() {
            let path = window.location.hash || '';
            path = path.replace('#', '').split('?')[0];

            if (!this.data || this.data.length === 0) return;

            let matchedItem = null;
            let currentFromStore = this.current;

            // 优先从 URL 路径匹配
            if (path && path !== '/') {
                matchedItem = this.findItemByKey(this.data, path);
                if (!matchedItem) {
                    matchedItem = this.findItemByPathPrefix(this.data, path);
                }
                // 如果 URL 路径存在但找不到匹配，保持当前路径不跳转
                if (!matchedItem) {
                    return;
                }
            } else {
                // URL 路径为空时，使用 store 中的缓存路径
                if (currentFromStore) {
                    matchedItem = this.findItemByKey(this.data, currentFromStore);
                }
                // 如果缓存也没有，使用第一个菜单
                if (!matchedItem) {
                    matchedItem = this.findFirstLeaf(this.data);
                }
            }

            if (matchedItem) {
                this.selectAndOpenMenu(matchedItem);
                this.$router.push(matchedItem.key);
            }
        },

        selectAndOpenMenu(item) {
            this.selectedKeys = [item.key];
            const parentKeys = this.getParentKeys(this.data, item.key);
            this.$store.setOpenKeys(parentKeys);

            this.$store.setCurrent(item.key);
            this.$store.setTitle(item.title);
            this.$store.setMenuId(item.id);
            this.$store.setButtons(item.buttons || []);
            this.$store.setMenuCache({
                key: item.key,
                title: item.title,
                id: item.id,
                buttons: item.buttons || [],
            });
        },

        findItemByKey(menuList, key) {
            if (!menuList || key === null) return null;
            for (const item of menuList) {
                if (item.key === key) return item;
                if (item.children) {
                    const found = this.findItemByKey(item.children, key);
                    if (found) return found;
                }
            }
            return null;
        },

        findItemByPathPrefix(menuList, path) {
            if (!menuList || !path) return null;
            for (const item of menuList) {
                if (path === item.key) {
                    return item;
                }
                if (item.children) {
                    const found = this.findItemByPathPrefix(item.children, path);
                    if (found) return found;
                }
            }
            return null;
        },

        findFirstLeaf(menuList) {
            for (const item of menuList) {
                if (item.children && item.children.length > 0) {
                    const found = this.findFirstLeaf(item.children);
                    if (found) return found;
                } else {
                    return item;
                }
            }
            return null;
        },

        getParentKeys(menuList, targetKey, path = []) {
            for (const item of menuList) {
                if (item.key === targetKey) {
                    return path;
                }
                if (item.children) {
                    const result = this.getParentKeys(item.children, targetKey, [...path, item.key]);
                    if (result.length) return result;
                }
            }
            return [];
        },

        menuSelect(data) {
            this.selectAndOpenMenu(data);
            this.$router.push(data.key);
        },

        onOpenChange(openKeys) {
            // 手风琴效果：只保留最新展开的一个
            const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key));
            if (latestOpenKey) {
                this.$store.setOpenKeys([latestOpenKey]);
            } else {
                this.$store.setOpenKeys([]);
            }
        },

        selectMenuClick() {
            if (!this.selectValue) {
                this.selectMenuOpend = false;
                return;
            }
            this.selectMenuOpend = true;
        },
    },
};
</script>

<style scoped>
.paas-menu-container {
    height: 100%;
    display: flex;
    flex-direction: column;
}

.paas-menu-header {
    height: 51px;
    display: flex;
    flex-direction: row;
    align-items: center;
    padding: 0px 8px;
    border-bottom: 1px solid #94929234;
}

.paas-menu-logo {
    margin-right: 8px;
    text-align: center;
    padding: 0 8px;
    height: 51px;
}

.paas-menu-logo img {
    height: 51px;
    max-width: 32px;
    object-fit: contain;
}

.paas-menu-system-name {
    text-align: center;
    padding: 0 8px;
}

.paas-menu-system-name label {
    font-size: 16px;
    font-weight: 600;
    color: #1890ff;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    letter-spacing: 0.5px;
}

.paas-menu-scroll-wrapper {
    height: calc(100% - 51px);
    overflow-y: auto;
    overflow-x: hidden;
    position: relative;
    max-height: calc(100% - 51px);
    -ms-overflow-style: none;
    scrollbar-width: none;
}

.paas-menu-scroll-wrapper::-webkit-scrollbar {
    display: none;
}
</style>