import { _decorator, Director, director, instantiate, Node, NodePool, Prefab } from 'cc';
const { ccclass, property } = _decorator;

export class PoolManager {
    private static _instance: PoolManager = new PoolManager();
    private constructor() { }
    public static get _ins() {
        return this._instance;
    }

    private prefabMap: Map<string, Prefab> = new Map();

    private poolDic: Map<string, NodePool> = new Map();

    /**
     * 初始化
     * @param resArr 预制体数组
     * 如无出现BUG无须主动调用
     */
    init(prefabs: Prefab[]) {
        if (!prefabs || prefabs.length === 0) return;

        // 清空之前的记录
        this.prefabMap.clear();

        // 使用 Map 存储，提高查询效率
        prefabs.forEach(prefab => {
            if (prefab && prefab.name) {
                this.prefabMap.set(prefab.name, prefab);
            }
        });
    }

    /**
     * 根据名称获取预制体
     * @param url 预制体的res/Prefab/的路径 或者 resArr拖动的名字
     */
    getNode(url: string) {
        let prefab: Prefab = null;
        if (this.prefabMap.has(url)) {
            prefab = this.prefabMap.get(url);
        }

        if (!prefab) {
            if (this.poolDic.has(url)) {
                if (this.poolDic.get(url).size() > 0) {
                    const node = this.poolDic.get(url).get();
                    return node;
                } else {
                    const node = new Node(url);
                    return node;
                }
            } else {
                this.poolDic.set(url, new NodePool(url));
                const node = new Node(url);
                return node;
            }

        } else {
            if (!this.poolDic.has(url)) {
                const node = instantiate(prefab);
                this.poolDic.set(url, new NodePool(url));
                console.warn("First Init Pool: " + url);
                return node;
            } else {
                const Pool = this.poolDic.get(url);
                if (Pool.size() > 0) {
                    const node = Pool.get();
                    return node;
                } else {
                    const node = instantiate(prefab);
                    return node;
                }
            }
        }
    }

    /**
     * 回收节点
     * @param node 节点
     * @param isRigiBody 是否是刚体
     */
    recycleNode(node: Node, isRigiBody: boolean = false) {
        const url = node.name;
        if (isRigiBody) {
            if (this.poolDic.has(url)) {
                director.once(Director.EVENT_AFTER_PHYSICS, () => {
                    this.poolDic.get(url).put(node);
                })
            } else {
                this.poolDic.set(url, new NodePool(url));
                director.once(Director.EVENT_AFTER_PHYSICS, () => {
                    this.poolDic.get(url).put(node);
                })
            }
        } else {
            if (this.poolDic.has(url)) {
                this.poolDic.get(url).put(node);
            } else {
                this.poolDic.set(url, new NodePool(url));
                this.poolDic.get(url).put(node);
            }
        }
    }


    /**
     * 清空所有节点池
     */
    clearAllPool() {
        for (let pool of this.poolDic.values()) {
            pool.clear();
        }
        this.poolDic.clear();
    }

    /**
     * 获取节点池字典
     */
    getPoolDic() {
        return this.poolDic;
    }

}


