import { BimComponent } from '../core/component';
import { BimEngine } from '../bim-engine';
import { BimRightKey } from '../components/right-key';
import { BimMenu } from '../components/menu';
import { MenuItemConfig } from '../components/menu/item';

/**
 * 右键菜单管理器 (RightKeyManager)
 * 负责协调右键交互流程：
 * 1. 监听 Canvas/容器的 contextmenu 事件
 * 2. 通过注册的处理器 (Handler) 获取需要显示的菜单项
 * 3. 实例化 Menu 组件并装载到 RightKey 容器中显示
 */
export class RightKeyManager extends BimComponent {
    private container: HTMLElement;
    private rightKeyPanel: BimRightKey;

    // 存储注册的上下文处理器
    // 每个处理器接收鼠标事件，返回一组菜单项（如果没有对应菜单则返回 null）
    private contextHandlers: Array<(e: MouseEvent) => MenuItemConfig[] | null> = [];

    constructor(engine: BimEngine, container: HTMLElement) {
        super(engine);
        this.container = container;

        // 初始化右键容器，设置极高的层级以覆盖所有 UI
        // 将事件监听和触发逻辑下放给 BimRightKey 组件
        this.rightKeyPanel = new BimRightKey({
            zIndex: 9000,
            container: this.container,
            onContext: this.handleContextMenu
        });
        this.rightKeyPanel.init();
    }

    public destroy(): void {
        this.rightKeyPanel.destroy();
    }

    /**
     * 注册上下文菜单处理器
     * @param handler 处理函数，接收鼠标事件，返回菜单项数组
     */
    public registerHandler(handler: (e: MouseEvent) => MenuItemConfig[] | null): void {
        this.contextHandlers.push(handler);
    }

    /**
     * 手动显示菜单
     * 允许外部直接调用以显示特定的菜单，不一定依赖右键事件
     * @param x 屏幕 X 坐标
     * @param y 屏幕 Y 坐标
     * @param items 菜单项列表
     * @param groupOrder 可选的分组顺序
     */
    public showMenu(x: number, y: number, items: MenuItemConfig[], groupOrder?: string[]): void {
        if (!items || items.length === 0) return;

        // 1. 创建菜单内容组件
        const menu = new BimMenu({ items, groupOrder });
        menu.init(); // 必须初始化以生成 DOM

        // 2. 将菜单挂载到右键容器
        this.rightKeyPanel.mount(menu);

        // 3. 显示容器
        this.rightKeyPanel.show(x, y);
    }

    /**
     * 隐藏右键菜单
     */
    public hide(): void {
        this.rightKeyPanel.hide();
    }

    /**
     * 处理右键点击事件
     * 由 BimRightKey 组件在检测到有效右键点击时调用
     */
    private handleContextMenu = (e: MouseEvent): void => {
        // 1. 确定上下文项
        // 遍历所有注册的处理器，找到第一个返回非空结果的处理器
        // 这种责任链模式允许插件优先处理特定对象的右键
        let items: MenuItemConfig[] | null = null;
        for (const handler of this.contextHandlers) {
            const result = handler(e);
            if (result && result.length > 0) {
                if (!items) items = [];
                items = items.concat(result);
            }
        }

        // 2. 如果有菜单项，则显示
        if (items && items.length > 0) {
            this.showMenu(e.clientX, e.clientY, items);
        } else {
            // 如果没有任何内容，则关闭可能存在的菜单
            this.hide();
        }
    };
}
