import { _decorator, Component, instantiate, Node, Prefab, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

/**
 * 对象池管理器
 * 功能：
 * 1. 管理游戏对象的复用
 * 2. 减少频繁创建/销毁对象的性能开销
 * 3. 支持Prefab和Node两种类型的对象池
 */
@ccclass('PoolManager')
export class PoolManager extends Component {
    // 对象池存储（改为更准确的名称）
    private static _objectPools = new Map<string, Node[]>();

    /**
     * 从对象池获取节点（支持Prefab或Node）
     * @param prefab - Prefab资源或节点模板
     * @param parent - 可选父节点
     * @returns 可复用的节点实例
     */
    public static getNode(prefab: Prefab | Node, parent?: Node): Node {
        const poolKey = prefab instanceof Prefab ? prefab.data.name : prefab.name;
        let node: Node = null;
        //从对象池获取可用节点
        const pool = this._objectPools.get(poolKey);
        if(pool?.length > 0) {
            node = pool.pop();
        }else {
            node = instantiate(prefab) as Node;
        }
        //初始化节点状态
        if (node) {
            node.active = true;
            node.position = Vec3.ZERO;
            if(parent) {
                node.setParent(parent);
            }
        }
        return node;
    }

    /**
     * 通过名称从对象池获取节点
     * @param poolKey - 对象池键名
     * @param parent - 可选父节点
     * @returns 可复用的节点实例（如果没有则返回null）
     */
    public static getName(poolKey: string, parent?: Node): Node | null {
        const pool = this._objectPools.get(poolKey);
        const node = pool?.pop();
        if(node) {
            node.active = true;
            if(parent){
               node.setParent(parent);
            }
        }
        return node ?? null;
    }

    /**
     * 将节点回收到对象池
     * @param node - 要回收的节点
     */
    public static putNode(node: Node): void {
        if (!node?.isValid || !node) return;
        const poolKey = node.name;
        //清理节点状态
        node.removeFromParent();
        node.active = false;
        //存入对象池
        if(poolKey) {
            if(!this._objectPools.has(poolKey)) {
                this._objectPools.set(poolKey, []);
            }
            this._objectPools.get(poolKey).push(node);
        }else{//没有有效名称的节点直接销毁
            node.destroy();
        }
    }

    /**
     * 获取指定对象池的大小
     * @param poolKey - 对象池键名
     * @returns 对象池中可用节点的数量
     */
    public static getPoolSize(poolKey: string): number {
        return this._objectPools.get(poolKey)?.length ?? 0;
    }

    /**
     * 清空指定对象池
     * @param poolKey - 要清空的对象池键名
     */
    public static clearPool(poolKey: string): void {
        const pool = this._objectPools.get(poolKey);
        if (pool) {
            pool.forEach(node => node.destroy());
            this._objectPools.delete(poolKey);
        }
    }

    /**
     * 清空所有对象池
     */
    public static clearAll(): void {
        this._objectPools.forEach((pool, key) => {
            pool.forEach(node => node.destroy());
        });
        this._objectPools.clear();
    }
}