import { _decorator, Node, Prefab, instantiate, error } from 'cc';
import { BaseView, ViewConfig, ViewOptions } from './BaseView';
const { ccclass } = _decorator;

/**
 * 已注册的页面配置映射
 */
interface RegisteredView {
    config: ViewConfig;
}

/**
 * 页面管理器
 * 单例模式，统一管理页面的注册、打开、关闭、返回等操作
 */
@ccclass('ViewManager')
export class ViewManager {
    /** 单例实例 */
    private static _instance: ViewManager | null = null;

    /** 获取单例 */
    public static get instance(): ViewManager {
        if (!ViewManager._instance) {
            ViewManager._instance = new ViewManager();
        }
        return ViewManager._instance;
    }

    /** 页面容器节点 */
    private _container: Node | null = null;

    /** 已注册的页面配置 */
    private _registeredViews: Map<string, RegisteredView> = new Map();

    /** 页面栈 */
    private _viewStack: BaseView[] = [];

    /** 页面实例缓存（用于缓存模式的页面） */
    private _viewCache: Map<string, BaseView> = new Map();

    /**
     * 初始化管理器
     * @param container 页面容器节点（通常是 Canvas）
     */
    init(container: Node): void {
        this._container = container;
    }

    /**
     * 获取当前容器
     */
    getContainer(): Node | null {
        return this._container;
    }

    /**
     * 注册页面
     * @param viewId 页面唯一标识
     * @param config 页面配置
     */
    register(viewId: string, config: ViewConfig): void {
        if (this._registeredViews.has(viewId)) {
            error(`ViewManager: 页面 "${viewId}" 已注册`);
            return;
        }

        this._registeredViews.set(viewId, {
            config: {
                cache: true,  // 默认缓存
                zIndex: 0,    // 默认层级
                ...config
            }
        });
    }

    /**
     * 批量注册页面
     * @param views 页面配置映射
     */
    registerAll(views: Record<string, ViewConfig>): void {
        for (const [viewId, config] of Object.entries(views)) {
            this.register(viewId, config);
        }
    }

    /**
     * 打开页面
     * @param viewId 页面唯一标识
     * @param options 打开选项
     */
    open(viewId: string, options?: ViewOptions): void {
        if (!this._container) {
            const err = new Error('ViewManager: 未初始化，请先调用 init()');
            options?.onError?.(err);
            return;
        }

        const registered = this._registeredViews.get(viewId);
        if (!registered) {
            const err = new Error(`ViewManager: 页面 "${viewId}" 未注册`);
            options?.onError?.(err);
            return;
        }

        // 检查是否有缓存的实例
        const cachedView = this._viewCache.get(viewId);
        if (cachedView && cachedView.node.isValid) {
            this._showView(cachedView, options);
            return;
        }

        // 直接使用预制体引用实例化
        this._instantiateView(viewId, registered.config.prefab, options);
    }

    /**
     * 实例化视图
     */
    private _instantiateView(viewId: string, prefab: Prefab, options?: ViewOptions): void {
        if (!this._container) return;

        const registered = this._registeredViews.get(viewId);
        if (!registered) return;

        const node = instantiate(prefab);
        const view = node.getComponent(BaseView);

        if (!view) {
            error(`ViewManager: 预制体 "${viewId}" 缺少 BaseView 组件`);
            node.destroy();
            options?.onError?.(new Error('缺少 BaseView 组件'));
            return;
        }

        // 设置视图属性
        view.viewId = viewId;
        view.config = registered.config;
        view.setParams(options?.params);

        // 设置层级
        node.setSiblingIndex(registered.config.zIndex || 0);

        // 添加到容器
        this._container.addChild(node);

        // 调用加载回调
        view.onViewLoad();

        // 缓存视图实例
        if (registered.config.cache) {
            this._viewCache.set(viewId, view);
        }

        // 显示视图
        this._showView(view, options);
    }

    /**
     * 显示视图
     */
    private _showView(view: BaseView, options?: ViewOptions): void {
        // 隐藏当前页面
        const currentView = this.getCurrentView();
        if (currentView && currentView !== view) {
            currentView._doHide();
        }

        // 设置参数
        if (options?.params !== undefined) {
            view.setParams(options?.params);
        }

        // 入栈
        if (!this._viewStack.includes(view)) {
            this._viewStack.push(view);
        }

        // 显示
        view._doShow();

        // 回调
        options?.onComplete?.(view);
    }

    /**
     * 关闭当前页面
     * @param options 关闭选项
     */
    close(options?: { destroy?: boolean }): void {
        const currentView = this._viewStack.pop();
        if (!currentView) return;

        const shouldDestroy = options?.destroy ?? !currentView.config?.cache;
        this._hideAndDestroyView(currentView, shouldDestroy);

        // 显示上一页
        const prevView = this.getCurrentView();
        if (prevView) {
            prevView._doShow();
        }
    }

    /**
     * 返回上一页（close 的别名）
     */
    back(): void {
        this.close();
    }

    /**
     * 替换当前页面
     * @param viewId 新页面标识
     * @param options 打开选项
     */
    replace(viewId: string, options?: ViewOptions): void {
        const currentView = this.getCurrentView();
        if (currentView) {
            this._viewStack.pop();
            const shouldDestroy = !currentView.config?.cache;
            this._hideAndDestroyView(currentView, shouldDestroy);
        }

        this.open(viewId, options);
    }

    /**
     * 隐藏并销毁视图（内部方法）
     */
    private _hideAndDestroyView(view: BaseView, shouldDestroy: boolean): void {
        view._doHide();
        if (shouldDestroy) {
            this._viewCache.delete(view.viewId);
            view._doDestroy();
        }
    }

    /**
     * 获取当前页面
     */
    getCurrentView(): BaseView | null {
        return this._viewStack.length > 0
            ? this._viewStack[this._viewStack.length - 1]
            : null;
    }

    /**
     * 获取页面栈
     */
    getViewStack(): BaseView[] {
        return [...this._viewStack];
    }

    /**
     * 清空所有页面
     */
    clearAll(): void {
        // 从栈顶开始销毁
        while (this._viewStack.length > 0) {
            const view = this._viewStack.pop()!;
            const shouldDestroy = !view.config?.cache;
            this._hideAndDestroyView(view, shouldDestroy);
        }

        // 销毁缓存的页面
        for (const view of this._viewCache.values()) {
            if (view.node.isValid) {
                view._doDestroy();
            }
        }

        this._viewCache.clear();
    }

    /**
     * 预加载页面预制体（主包资源已随游戏加载，此方法仅为兼容性保留）
     * @param viewId 页面标识
     * @param onProgress 进度回调
     * @param onComplete 完成回调
     */
    preload(viewId: string, onProgress?: (progress: number) => void, onComplete?: () => void): void {
        const registered = this._registeredViews.get(viewId);
        if (!registered) {
            error(`ViewManager: 页面 "${viewId}" 未注册`);
            onComplete?.();
            return;
        }

        // 主包资源已加载，直接回调
        onProgress?.(1);
        onComplete?.();
    }

    /**
     * 批量预加载页面
     * @param viewIds 页面标识数组
     * @param onProgress 总进度回调 (0-1)
     * @param onComplete 完成回调
     */
    preloadAll(viewIds: string[], onProgress?: (progress: number) => void, onComplete?: () => void): void {
        if (viewIds.length === 0) {
            onProgress?.(1);
            onComplete?.();
            return;
        }

        let completed = 0;
        const total = viewIds.length;

        for (const viewId of viewIds) {
            this.preload(viewId, () => {
                completed++;
                onProgress?.(completed / total);
                if (completed === total) {
                    onComplete?.();
                }
            });
        }
    }
}
