import { Node, Prefab, instantiate } from 'cc';
import { UIBase } from './UIBase';
import { ResMgr } from '../ResMgr/ResMgr';

/**
 * UI管理器
 * 职责:
 * - 管理所有UI的加载、显示、隐藏和销毁
 * - 维护UI缓存,避免重复加载
 * - 管理UI的生命周期
 * - 提供UI更新机制
 */
export class UIMgr {
    private static _instance: UIMgr;
    
    /** 已加载的UI实例缓存 */
    private _uiCache: Map<string, UIBase> = new Map();
    
    /** UI父节点(Canvas) */
    private _uiRoot: Node | null = null;
    
    /** 需要更新的UI列表 */
    private _updateList: UIBase[] = [];
    
    /**
     * 获取单例
     */
    static getInstance(): UIMgr {
        if (!this._instance) {
            this._instance = new UIMgr();
        }
        return this._instance;
    }
    
    /**
     * 设置UI根节点
     * @param root Canvas节点或UI容器节点
     * @example
     * const canvas = find('Canvas');
     * if (canvas) {
     *     UIMgr.getInstance().setUIRoot(canvas);
     * }
     */
    setUIRoot(root: Node): void {
        this._uiRoot = root;
        console.log('[UIMgr] 设置UI根节点');
    }
    
    /**
     * 加载并显示UI
     * @param uiClass UI类
     * @param params 传递给onStart的参数
     * @returns UI实例
     * @example
     * const loginUI = await UIMgr.getInstance().load(UILogin, { username: 'test' });
     */
    async load<T extends UIBase>(
        uiClass: new () => T,
        params?: any
    ): Promise<T> {
        const className = uiClass.name;
        
        // 检查缓存
        let ui = this._uiCache.get(className) as T;
        if (ui) {
            console.log(`[UIMgr] 从缓存加载UI: ${className}`);
            ui.show();
            if (ui.onStart) {
                await ui.onStart(params);
            }
            return ui;
        }
        
        // 创建UI实例
        ui = new uiClass();
        
        // 获取UI资源路径
        const url = ui.onGetUrl();
        if (!url) {
            console.error(`[UIMgr] UI未定义资源路径: ${className}`);
            throw new Error(`UI未定义资源路径: ${className}`);
        }
        
        console.log(`[UIMgr] 开始加载UI: ${className} (${url})`);
        const args = url.split('://')
        const bundleName = args[0];
        const resourcePath = args[1];
        // 通过ResMgr加载预制体
        try {
            const prefab = await ResMgr.getInstance().load<Prefab>(
                bundleName,
                resourcePath,
                Prefab
            );
            
            // 实例化预制体
            const node = instantiate(prefab);
            
            // 添加到UI根节点
            if (this._uiRoot) {
                node.setParent(this._uiRoot);
            } else {
                console.warn(`[UIMgr] UI根节点未设置,UI将无父节点: ${className}`);
            }
            
            // 设置UI节点
            ui.setNode(node);
            
            // 缓存UI
            this._uiCache.set(className, ui);
            
            // 如果UI有onUpdate方法,添加到更新列表
            if (ui.onUpdate) {
                this._updateList.push(ui);
            }
            
            // 调用onStart生命周期
            if (ui.onStart) {
                await ui.onStart(params);
            }
            
            // 显示UI
            ui.show();
            
            console.log(`[UIMgr] UI加载完成: ${className}`);
            return ui;
            
        } catch (error) {
            console.error(`[UIMgr] 加载UI失败: ${className}`, error);
            throw error;
        }
    }
    
    /**
     * 卸载UI
     * @param uiClass UI类或类名
     * @example
     * UIMgr.getInstance().unload(UILogin);
     * // 或
     * UIMgr.getInstance().unload('UILogin');
     */
    unload(uiClass: (new () => UIBase) | string): void {
        const className = typeof uiClass === 'string' 
            ? uiClass 
            : uiClass.name;
        
        const ui = this._uiCache.get(className);
        if (!ui) {
            console.warn(`[UIMgr] UI未加载,无法卸载: ${className}`);
            return;
        }
        
        console.log(`[UIMgr] 卸载UI: ${className}`);
        
        // 调用onEnd生命周期
        if (ui.onEnd) {
            ui.onEnd();
        }
        
        // 从更新列表移除
        const index = this._updateList.indexOf(ui);
        if (index !== -1) {
            this._updateList.splice(index, 1);
        }
        
        // 销毁节点
        const node = ui.getNode();
        if (node && node.isValid) {
            node.destroy();
        }
        
        // 从缓存移除
        this._uiCache.delete(className);
        
        // 释放资源
        const url = ui.onGetUrl();
        if (url) {
            ResMgr.getInstance().release('resources', url);
        }
    }
    
    /**
     * 获取已加载的UI实例
     * @param uiClass UI类或类名
     * @returns UI实例,如果未加载则返回null
     * @example
     * const loginUI = UIMgr.getInstance().get(UILogin);
     * if (loginUI) {
     *     loginUI.show();
     * }
     */
    get<T extends UIBase>(uiClass: (new () => T) | string): T | null {
        const className = typeof uiClass === 'string' 
            ? uiClass 
            : uiClass.name;
        
        return (this._uiCache.get(className) as T) || null;
    }
    
    /**
     * 检查UI是否已加载
     * @param uiClass UI类或类名
     * @returns true表示已加载,false表示未加载
     * @example
     * if (UIMgr.getInstance().has(UILogin)) {
     *     console.log('登录UI已加载');
     * }
     */
    has(uiClass: (new () => UIBase) | string): boolean {
        const className = typeof uiClass === 'string' 
            ? uiClass 
            : uiClass.name;
        
        return this._uiCache.has(className);
    }
    
    /**
     * 更新所有需要更新的UI
     * 应在主循环中每帧调用
     * @param dt 距离上一帧的时间(秒)
     * @example
     * // 在主场景的update方法中调用
     * update(dt: number) {
     *     UIMgr.getInstance().update(dt);
     * }
     */
    update(dt: number): void {
        for (const ui of this._updateList) {
            if (ui.isShowing() && ui.onUpdate) {
                ui.onUpdate(dt);
            }
        }
    }
    
    /**
     * 卸载所有UI
     * @example
     * // 在场景切换或退出游戏时调用
     * UIMgr.getInstance().unloadAll();
     */
    unloadAll(): void {
        console.log(`[UIMgr] 卸载所有UI`);
        
        const classNames = Array.from(this._uiCache.keys());
        for (const className of classNames) {
            this.unload(className);
        }
    }
    
    /**
     * 获取当前已加载UI的数量
     * @returns UI数量
     */
    getUICount(): number {
        return this._uiCache.size;
    }
    
    /**
     * 显示指定UI(不重新加载)
     * @param uiClass UI类或类名
     * @example
     * UIMgr.getInstance().show(UILogin);
     */
    show(uiClass: (new () => UIBase) | string): void {
        const className = typeof uiClass === 'string' 
            ? uiClass 
            : uiClass.name;
        
        const ui = this._uiCache.get(className);
        if (ui) {
            ui.show();
        } else {
            console.warn(`[UIMgr] UI未加载,无法显示: ${className}`);
        }
    }
    
    /**
     * 隐藏指定UI(不卸载)
     * @param uiClass UI类或类名
     * @example
     * UIMgr.getInstance().hide(UILogin);
     */
    hide(uiClass: (new () => UIBase) | string): void {
        const className = typeof uiClass === 'string' 
            ? uiClass 
            : uiClass.name;
        
        const ui = this._uiCache.get(className);
        if (ui) {
            ui.hide();
        } else {
            console.warn(`[UIMgr] UI未加载,无法隐藏: ${className}`);
        }
    }
}
