// 预加载某个bundle
// 释放某个bundle,并清理相关的UI
// 打开UI前,根据其归属bundle加载后再打开
// 同一个bundle下的图片,预制体,放在一个文件夹下(脚本不可放在bundle下)

import Load from "./Load"

export default class AssetsBundleMgr {

    private static bundleList: { [key: string]: cc.AssetManager.Bundle } = {}

    // //bundle预加载
    // public static preloadBundle(bundleName: string) {
    //     if (this.bundleList[bundleName] != null) {
    //         return
    //     }
    //     cc.assetManager.loadBundle(bundleName, (err, bundle: cc.AssetManager.Bundle) => {
    //         if (err) {
    //             console.warn("bundle预加载失败: " + bundleName)
    //             return
    //         }
    //         this.bundleList[bundleName] = bundle
    //     })
    // }

    /** 获取缓存中的资源 */
    public static get<T extends cc.Asset>(bundleKey: string, path: string, type?: any): T | null {
        if (!cc.assetManager.getBundle(bundleKey)) return null;
        return cc.assetManager.getBundle(bundleKey).get(path, type);
    }

    //加载bundle
    public static loadBundle(bundleName: string, callback = (error, bundle: cc.AssetManager.Bundle) => { }) {
        if (this.bundleList[bundleName] != null) {
            callback(null, this.bundleList[bundleName])
        } else {
            cc.assetManager.loadBundle(bundleName, (err, bundle: cc.AssetManager.Bundle) => {
                if (err) {
                    callback(err, null)
                    return
                }
                this.bundleList[bundleName] = bundle
                callback(null, bundle)
            })
        }
    }
    // 加载bundle中的prefab
    public static loadBundlePrefab(url: string, callback = (error, prefab: cc.Prefab) => { }) {
        let bundleName = url.split("/")[0]
        let realUrl = url.slice(url.indexOf("/") + 1)

        if (this.bundleList[bundleName] != null) {
            this.bundleList[bundleName].load(realUrl, cc.Prefab, (err, prefab: cc.Prefab) => {
                if (err) {
                    callback(err, null)
                    return
                }
                callback(null, prefab)
            })
        } else {
            cc.assetManager.loadBundle(bundleName, (err, bundle: cc.AssetManager.Bundle) => {
                if (err) {
                    callback(err, null)
                    return
                }
                this.bundleList[bundleName] = bundle
                this.bundleList[bundleName].load(realUrl, cc.Prefab, (err, prefab: cc.Prefab) => {
                    if (err) {
                        callback(err, null)
                        return
                    }
                    callback(null, prefab)
                })
            })
        }
    }

    /** 同步加载bundle中的prefab */
    public static async loadAsynBundlePrefab(url: string): Promise<cc.Prefab> {
        return new Promise((resolve, reject) => {
            let bundleName = url.split("/")[0]
            let realUrl = url.slice(url.indexOf("/") + 1)

            if (this.bundleList[bundleName] != null) {
                this.bundleList[bundleName].load(realUrl, cc.Prefab, (err, prefab: cc.Prefab) => {
                    if (err) {
                        reject(null);
                        return
                    }
                    resolve(prefab)
                })
            } else {
                cc.assetManager.loadBundle(bundleName, (err, bundle: cc.AssetManager.Bundle) => {
                    if (err) {
                        reject(null);
                        return
                    }
                    this.bundleList[bundleName] = bundle
                    this.bundleList[bundleName].load(realUrl, cc.Prefab, (err, prefab: cc.Prefab) => {
                        if (err) {
                            reject(null);
                            return
                        }
                        resolve(prefab)
                    })
                })
            }
        });
    }

    // 加载bundle中的资源
    public static loadBundleAsset<T extends cc.Asset>(url: string, T, callback: Function) {
        let bundleName = url.split("/")[0]
        let realUrl = url.slice(url.indexOf("/") + 1)
        cc.assetManager.loadBundle(bundleName, (err, bundle: cc.AssetManager.Bundle) => {
            if (err) {
                callback(err, null)
                return
            }
            this.bundleList[bundleName] = bundle
            this.bundleList[bundleName].load(realUrl, T, (err, asset: T) => {
                if (err) {
                    callback(err, null)
                    return
                }
                callback(null, asset)
            })
        })
    }
    // 加载bundle中的资源文件夹
    public static loadBundleAssetDir(url: string, callback = (error, asset: cc.Asset[]) => { }) {
        let bundleName = url.split("/")[0]
        let realUrl = url.slice(url.indexOf("/") + 1)
        cc.assetManager.loadBundle(bundleName, (err, bundle: cc.AssetManager.Bundle) => {
            if (err) {
                callback(err, null)
                return
            }
            this.bundleList[bundleName] = bundle
            this.bundleList[bundleName].loadDir(realUrl, (err, assets: cc.Asset[]) => {
                if (err) {
                    callback(err, null)
                    return
                }
                callback(null, assets)
            })
        })
    }

    //释放单个bundle
    public static releaseBundle(bundleName: string) {
        if (this.bundleList[bundleName] != null) {
            console.log("releaseBundle:" + bundleName)
            this.bundleList[bundleName].releaseAll()
            Load.clearByBundle(bundleName)
            delete this.bundleList[bundleName]
        }
    }

    //释放所有bundle
    public static releaseAllBundle() {
        for (const bundleName in this.bundleList) {
            console.log("releaseBundle:" + bundleName)
            const element = this.bundleList[bundleName]
            element.releaseAll()
            Load.clearByBundle(bundleName)
        }
        this.bundleList = {}
    }

}
