import { Asset, assetManager, ImageAsset, SpriteFrame, Texture2D, _decorator } from 'cc';
import { DEV } from 'cc/env';
import { AutoBind } from '../common/AutoBind';
import { StringUtil } from '../util/StringUtil';
import { LoadQueue } from './LoadQueue';
import { resLoader } from './ResLoader';
const { ccclass, menu, property } = _decorator;

@ccclass('ResKeeper')
@menu('私有组件/ResKeeper')
export class ResKeeper extends AutoBind {
    @property({ displayName: "启用分帧加载", tooltip: DEV && "该组件加载资源是否使用分帧加载" })
    private frame_load = false;
    @property({ displayName: "加载优先级", slide: true, max: 10, min: 0, step: 1, visible() { return this.frame_load == true; }, tooltip: DEV && "分帧加载优先级,优先级越大越先加载" })
    private load_priority = 0;

    // private _net_cache = new Map<string, SpriteFrame>();
    private _res_cache = new Map<string, Asset>();
    private _uuid_sign = StringUtil.getUUID(12);
    private _uuid_idx = 0;

    protected onDestroy() {
        this.release();
    }

    /**
     * 在当前资源缓存中清理一个缓存(主要用于一个组件加载多个资源但只使用其中一个,这个时候就可以调用释放前面的特定资源)
     * @param uuid 缓存ID
     */
    
    // protected releaseCache(uuid: string) {
    //     if (uuid && uuid != "" && this._res_cache.has(uuid)) {
    //         let res = this._res_cache.get(uuid);
    //         res?.decRef();
    //         res = null;
    //         this._res_cache.delete(uuid);
    //         uuid = "";
    //     }
    // }

    /**
     * 在该节点上添加一个资源,该资源将随父节点销毁自动销毁,如果父节点被销毁,则销毁资源
     * @param bundle 包名
     * @param url 路径
     * @param type 类型
     * @param completed 加载成功后回调
     */
    protected load(bundle: string, url: string, type: typeof Asset, completed: (res: Asset, uuid?: string) => void) {
        let callback = (error: Error, res: Asset) => {
            if (error) {
                console.error(error);
            } else {
                if (this.isValid) {
                    let uuid = this._addResCache(res);
                    completed && completed(res, uuid);
                } else {
                    // resLoader.release(url, bundle);
                }
            }
        };
        if (this.frame_load) {
            LoadQueue.pushLoad(this.load_priority, bundle, url, type, callback, this);
        } else {
            resLoader.load(bundle, url, type, callback);
        }
    }

    /**
     * 在该节点上添加一个网络图片,该资源将随父节点销毁自动销毁,如果父节点被销毁,则销毁资源
     * @param url 路径
     * @param completed 加载成功后回调
     */
    // protected loadAvatar(url: string, completed: (res: SpriteFrame) => void) {
    //     let callback = (error: Error, image: ImageAsset) => {
    //         if (error) {
    //             console.error(error);
    //         } else {
    //             if (this.isValid) {
    //                 this._addResCache(image);
    //                 let frame = this._net_cache.get(url);
    //                 if (frame) {
    //                     frame.addRef();
    //                     completed && completed(frame);
    //                 } else {
    //                     let texture = new Texture2D();
    //                     texture.image = image;
    //                     let frame = new SpriteFrame();
    //                     frame.texture = texture;
    //                     this._net_cache.set(url, frame);
    //                     frame.addRef();
    //                     completed && completed(frame);
    //                 }
    //             }
    //         }
    //     };
    //     if (url.indexOf(".png") == -1) {
    //         assetManager.loadRemote<ImageAsset>(url, { ext: '.png' }, callback);
    //     } else {
    //         assetManager.loadRemote<ImageAsset>(url, callback);
    //     }
    // }

    private _addResCache(res: Asset) {
        ++this._uuid_idx;
        let uuid = this.node.uuid + "_<" + this._uuid_sign + ">_[" + this._uuid_idx + "]";
        res.addRef();
        this._res_cache.set(uuid, res);
        return uuid;
    }

    release() {
        // this._net_cache.forEach((frame, url) => {
        //     if (frame.isValid) {
        //         const tmp_frame = frame;
        //         frame.decRef(false);
        //         frame = null;
        //         if (tmp_frame.refCount <= 0) {
        //             let texture = tmp_frame.texture as Texture2D;
        //             if (tmp_frame.packable) {
        //                 texture = tmp_frame.original?._texture as Texture2D;
        //             }
        //             if (texture) {
        //                 texture.image?.decRef();
        //                 texture.image = null;
        //                 texture.destroy();
        //             }
        //             tmp_frame.destroy();
        //         }
        //     }
        // });
        // this._net_cache.clear();
        this._res_cache.forEach((res) => {
            res?.decRef();
            res = null;
        });
        this._res_cache.clear();
    }
}