import { IBimComponent } from '../../types/component';
import { ThemeConfig } from '../../themes/types';
import { localeManager, t } from '../../services/locale';
import { MenuItemConfig } from './item';
import { MenuOptions } from './types';
import './index.css';
import { themeManager } from '../../services/theme';

/**
 * 通用菜单列表组件
 * 负责渲染一组菜单项，支持分组、排序、图标、快捷键提示和递归多级子菜单。
 * 它不包含定位逻辑，仅负责内容渲染。
 */
export class BimMenu implements IBimComponent {
    public element: HTMLElement;
    private options: MenuOptions;
    private unsubscribeLocale: (() => void) | null = null;
    private unsubscribeTheme: (() => void) | null = null;

    // 当前激活的子菜单引用，用于自动关闭
    private activeSubMenu: { menu: BimMenu; container: HTMLElement } | null = null;

    constructor(options: MenuOptions) {
        this.options = options;
        this.element = document.createElement('ul');
        this.element.className = 'bim-menu';
    }

    /**
     * 初始化组件
     * 渲染 DOM 结构并订阅语言变更
     */
    public init(): void {
        this.render();

        // 订阅语言变更事件，实现国际化自动更新
        this.unsubscribeLocale = localeManager.subscribe(() => {
            this.setLocales();
        });
        // 自动订阅主题变更
        this.unsubscribeTheme = themeManager.subscribe((theme) => {
            this.setTheme(theme);
        });
    }

    /**
     * 设置主题
     * @param theme 全局主题配置
     */
    public setTheme(theme: ThemeConfig) {
        const style = this.element.style;
        style.setProperty('--bim-ui_bg_color', theme.panelBackground);
        style.setProperty('--bim-ui_text_primary', theme.textPrimary);
        style.setProperty('--bim-ui_border_color', theme.border);
        style.setProperty('--bim-ui_bg_hover', theme.componentHover);
    }

    /**
     * 响应语言变更
     * 重新渲染整个菜单以更新文本
     */
    public setLocales(): void {
        this.element.innerHTML = '';
        this.render();
    }

    /**
     * 销毁组件
     * 清理事件监听、子菜单和 DOM 元素
     */
    public destroy(): void {
        // 取消语言订阅
        if (this.unsubscribeLocale) {
            this.unsubscribeLocale();
            this.unsubscribeLocale = null;
        }
        if (this.unsubscribeTheme) {
            this.unsubscribeTheme();
            this.unsubscribeTheme = null;
        }
        // 关闭并销毁所有打开的子菜单
        this.closeSubMenu();
        // 移除自身 DOM
        this.element.remove();
    }

    /**
     * 获取组件根元素
     * 实现 IRightKeyContent 接口，允许被 RightKey 容器挂载
     */
    public getElement(): HTMLElement {
        return this.element;
    }

    /**
     * 核心渲染逻辑
     * 处理分组、排序和 DOM 生成
     */
    private render(): void {
        const { items, groupOrder } = this.options;

        // 1. 数据分桶：按 group 字段将菜单项分组
        const groups = new Map<string, MenuItemConfig[]>();
        const defaultGroup = 'default';

        items.forEach(item => {
            const groupName = item.group || defaultGroup;
            if (!groups.has(groupName)) {
                groups.set(groupName, []);
            }
            groups.get(groupName)!.push(item);
        });

        // 2. 确定分组顺序
        let sortedGroupKeys: string[] = [];
        if (groupOrder) {
            // 优先按照 groupOrder 指定的顺序排序
            sortedGroupKeys = groupOrder.filter(g => groups.has(g));
            // 将未在 groupOrder 中定义的组追加到最后
            for (const key of groups.keys()) {
                if (!sortedGroupKeys.includes(key)) {
                    sortedGroupKeys.push(key);
                }
            }
        } else {
            // 如果未指定顺序，则按默认遍历顺序
            sortedGroupKeys = Array.from(groups.keys());
        }

        // 3. 渲染分组和组内项
        sortedGroupKeys.forEach((groupName, index) => {
            // 除了第一组外，每组之前插入分割线
            if (index > 0) {
                const divider = document.createElement('li');
                divider.className = 'bim-menu-divider';
                this.element.appendChild(divider);
            }

            const groupItems = groups.get(groupName)!;
            // 组内排序：根据 item.order 升序排列
            groupItems.sort((a, b) => (a.order || 0) - (b.order || 0));

            groupItems.forEach(item => {
                // 仅渲染可见的项
                if (item.visible !== false) {
                    this.element.appendChild(this.createItemElement(item));
                }
            });
        });
    }

    /**
     * 创建单个菜单项的 DOM 元素
     */
    private createItemElement(item: MenuItemConfig): HTMLElement {
        const li = document.createElement('li');
        // 根据状态设置样式类
        const isEnabled = !item.disabled;
        li.className = `bim-menu-item ${isEnabled ? '' : 'disabled'}`;

        // 1. 图标区域 (Icon Slot)
        const iconDiv = document.createElement('div');
        iconDiv.className = 'bim-menu-item-icon';
        if (item.icon) {
            iconDiv.innerHTML = item.icon;
        }
        li.appendChild(iconDiv);

        // 2. 文本区域 (Label Slot)
        const labelDiv = document.createElement('div');
        labelDiv.className = 'bim-menu-item-label';
        // 获取翻译后的文本
        labelDiv.textContent = t(item.label);
        li.appendChild(labelDiv);

        // 3. 子菜单指示器 (Arrow Slot)
        const children = item.children;
        const hasChildren = children && children.length > 0;

        if (hasChildren) {
            const arrowDiv = document.createElement('div');
            arrowDiv.className = 'bim-menu-item-arrow';
            // 简单的右箭头 SVG
            arrowDiv.innerHTML = '<svg viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>';
            li.appendChild(arrowDiv);

            // 绑定子菜单交互事件
            // 鼠标移入：打开子菜单
            li.addEventListener('mouseenter', () => this.openSubMenu(item, li));
        } else {
            // 鼠标移入普通项：关闭当前已打开的子菜单
            li.addEventListener('mouseenter', () => this.closeSubMenu());
        }

        // 4. 绑定点击事件
        if (isEnabled) {
            // Debug Log: 检查是否绑定了事件
            // console.log(`[BimMenu] Binding click for ${item.id}, hasChildren: ${hasChildren}, hasOnClick: ${!!item.onClick}`);
            
            li.addEventListener('click', (e) => {
                e.stopPropagation(); // 防止冒泡
                console.log(`[BimMenu] Clicked item: ${item.id}`);
                
                // 如果是叶子节点（没有子菜单），则触发点击动作
                if (!hasChildren) {
                    if (item.onClick) {
                        console.log(`[BimMenu] Executing onClick for ${item.id}`);
                        item.onClick();
                    } else {
                        console.warn(`[BimMenu] No onClick handler for ${item.id}`);
                    }
                }
            });
        }

        return li;
    }

    /**
     * 打开子菜单
     * @param item 当前菜单项
     * @param parentLi 触发的 DOM 元素（用于定位）
     */
    private openSubMenu(item: MenuItemConfig, parentLi: HTMLElement): void {
        const children = item.children;
        if (!children || children.length === 0) return;

        // 如果当前已经打开了子菜单，先关闭它
        this.closeSubMenu();

        // 创建子菜单容器 (模拟一个临时的悬浮层)
        const container = document.createElement('div');
        container.style.position = 'fixed';
        container.style.zIndex = '10001'; // 确保比父菜单层级高

        // 初步计算位置：位于父项右侧
        const rect = parentLi.getBoundingClientRect();
        container.style.top = `${rect.top}px`;
        container.style.left = `${rect.right}px`;

        // 关键修复：阻止 mousedown 冒泡
        // 防止点击子菜单时触发 BimRightKey 的全局关闭逻辑（因为它认为点击发生在主菜单外部）
        container.addEventListener('mousedown', (e) => e.stopPropagation());

        // 递归创建新的 BimMenu 实例
        const subMenu = new BimMenu({ items: children });
        subMenu.init();
        container.appendChild(subMenu.element);
        document.body.appendChild(container);

        // 保存引用以便后续清理
        this.activeSubMenu = { menu: subMenu, container };

        // 边界检测：如果超出屏幕右侧，则向左展开
        const subRect = container.getBoundingClientRect();
        if (subRect.right > window.innerWidth) {
            container.style.left = `${rect.left - subRect.width}px`;
        }
        // TODO: 垂直方向边界检测
    }

    /**
     * 关闭当前激活的子菜单
     */
    private closeSubMenu(): void {
        if (this.activeSubMenu) {
            this.activeSubMenu.menu.destroy();
            this.activeSubMenu.container.remove();
            this.activeSubMenu = null;
        }
    }
}


