import EMeshType from "./enum/EMeshType.js"
import Logger from "./Logger.js"

const logger = new Logger('XAvatarComopnent')

export default class XAvatarComopnent {
    constructor() {
        E(this, "resourceIdList", []);
        E(this, "skeleton");
        E(this, "extraProp");
        E(this, "extras", []);
        E(this, "body")
    }
    addBodyComp(e, t) {
        // console.error(this, e, t)
        return !e.rootNode || t.root.getChildMeshes().length === 0 ? (t.isRender = !1,
        !1) : (this.body = t,
        this.body.root.parent = e.rootNode,
        t.isRender = !0,
        this.body.root.getChildMeshes()[0] && (this.body.root.getChildMeshes()[0].xtype = EMeshType.XAvatar,
        this.body.root.getChildMeshes()[0].xid = e.id),
        this.skeleton = t.skeleton,
        !0)
    }
    addClothesComp(e, t) {
        // console.error(t.root.name)
        // console.error(this, e, t)
        return !e.rootNode || !this.skeleton || !t.root ? (t.isRender = !1,
        !1) : (t.root.xtype = EMeshType.XAvatar,
        t.root.xid = e.id,
        t.isRender = !0,
        t.root.parent = e.rootNode.getChildMeshes()[0],
        this.resourceIdList.push(t),
        t.root.skeleton = this.skeleton,
        t.root.getChildMeshes().forEach(r=>{
            r.skeleton = this.skeleton
        }
        ),
        !0)
    }
    clearClothesComp(e) {
        e.root.getChildMeshes().forEach(t=>{
            t.skeleton = null,
            t.dispose(),
            t.xid = void 0
        }
        ),
        e.root.dispose(),
        this.resourceIdList = this.resourceIdList.filter(t=>t.uId != e.uId)
    }
    clearAllClothesComps() {
        this.resourceIdList.forEach(e=>{
            var t;
            e.root.parent = null,
            e.root._parentContainer.xReferenceCount && (e.root._parentContainer.xReferenceCount--,
            e.root._parentContainer = null),
            e.isRender = !1,
            e.isSelected = !1,
            e.root.getChildMeshes().forEach(r=>{
                r.skeleton = null,
                r.dispose()
            }
            ),
            (t = e.root.skeleton) == null || t.dispose(),
            e.root.dispose()
        }
        ),
        this.resourceIdList = []
    }
    dispose(e) {
        this.body ? (this.body.root._parentContainer.xReferenceCount && (this.body.root._parentContainer.xReferenceCount--,
        this.body.root._parentContainer = null),
        this.clearAllClothesComps(),
        this.body.isRender = !1,
        this.body.skeleton.dispose(),
        this.body.skeleton = null,
        this.body.root.dispose(),
        this.body = void 0,
        this.skeleton && (this.skeleton.dispose(),
        this.skeleton = void 0)) : logger.warn("[Engine] no body to dispose")
    }
    changeClothesComp(e, t, r, n, o) {
        return new Promise(a=>{
            if (r === "pendant" || this.resourceIdList.some(s=>s.name === t))
                return a();
            if (e.isHide || !e.isRender)
                o.concat(r).forEach(l=>{
                    e.clothesList = e.clothesList.filter(c=>c.type != l);
                    const u = {
                        type: r,
                        id: t,
                        url: n,
                        lod: 0
                    };
                    e.clothesList.push(u)
                }
                ),
                a();
            else {
                const s = o.concat(r);
                e.avatarManager.loadDecoration(r, t, 0).then(l=>{
                    if (l) {
                        e.attachDecoration(l);
                        const u = {
                            type: r,
                            id: t,
                            url: n
                        };
                        e.clothesList.push(u),
                        l.root.setEnabled(!0),
                        s.forEach(c=>{
                            const h = this.resourceIdList.filter(f=>f.type === c);
                            if (h.length > 1) {
                                const f = h.filter(d=>d.name === t);
                                if (f.length > 1)
                                    for (let d = 1; d < f.length; ++d) {
                                        e.detachDecoration(f[d]),
                                        e.clothesList = e.clothesList.filter(g=>g.id != f[d].name);
                                        const _ = {
                                            type: r,
                                            id: t,
                                            url: n
                                        };
                                        e.clothesList.push(_)
                                    }
                            }
                            h[0] && h[0].name != t && this._readyToDetach(e, r) && (e.detachDecoration(h[0]),
                            e.clothesList = e.clothesList.filter(f=>f.id != h[0].name))
                        }
                        )
                    }
                    return a()
                }
                )
            }
        }
        )
    }
    _readyToDetach(e, t) {
        return !((t == "clothes" || t == "pants") && e.clothesList.filter(n=>n.type === "suit").length == 1 && (!e.clothesList.some(n=>n.type === "pants") || !e.clothesList.some(n=>n.type === "clothes")))
    }
    addDecoComp(e, t, r, n, o) {
        if (e.isRender) {
            const a = e.avatarManager.extraComps.get(t)
              , s = a == null ? void 0 : a.clone(t, void 0);
            if (!a) {
                logger.error("\u6CA1\u6709\u5BF9\u5E94\u7684\u7EC4\u4EF6");
                return
            }
            this.extras.push(s);
            const l = this.skeleton.bones.find(u=>u.name === r);
            s.position = n,
            s.rotation = o,
            s.attachToBone(l, e.rootNode.getChildMeshes()[0])
        }
    }
    showExtra(e) {
        this.extras.forEach(t=>{
            t.name.indexOf(e) > 0 && t.setEnabled(!0)
        }
        )
    }
    hideExtra(e) {
        this.extras.forEach(t=>{
            t.name.indexOf(e) > 0 && t.setEnabled(!1)
        }
        )
    }
    disposeExtra() {
        this.extras.forEach(e=>{
            e.dispose()
        }
        ),
        this.extras = []
    }
}
