import * as mc from "@minecraft/server";
import * as utils from "../utils/index";
import { WornHat } from "./worn_hat";
import { PlayerCompanion } from "../playerCompanion/index";
export class HatWearer {
    get Entity() {
        return this.entity;
    }
    get HatId() {
        var _a, _b;
        if (this.Entity.typeId === "minecraft:player") {
            return (_b = (_a = this.Entity.Equipment) === null || _a === void 0 ? void 0 : _a.getEquipment(mc.EquipmentSlot.Head)) === null || _b === void 0 ? void 0 : _b.typeId;
        }
        else {
            const npc = PlayerCompanion.getNPC(this.Entity.id);
            return npc === null || npc === void 0 ? void 0 : npc.Hat;
        }
    }
    constructor(entity) {
        this.destructEvent = this.destructor.bind(this);
        if (HatWearer.wearerList[entity.id] !== undefined) {
            throw `${entity.id} already a hat wearer`;
        }
        utils.mclog(`Initialized Hat Wearer`);
        this.entity = new utils.SafetyCheckedEntity(entity);
        this.isValid = true;
        HatWearer.wearerList[entity.id] = this;
        mc.world.afterEvents.entityRemove.subscribe(this.destructEvent);
        this.hatCheckLoop();
        if (this.Entity.typeId === "minecraft:player")
            this.hatLoreLoop();
    }
    destructor(event) {
        var _a;
        if (event.removedEntityId === this.entity.id) {
            utils.mclog("Removed Hat Wearer");
            this.isValid = false;
            (_a = this.currentHat) === null || _a === void 0 ? void 0 : _a.onUnequip();
            this.currentHat = undefined;
            delete HatWearer.wearerList[this.entity.id];
            mc.world.afterEvents.entityRemove.unsubscribe(this.destructEvent);
        }
    }
    hatLoreLoop() {
        const inventory = this.Entity.Inventory;
        if (!inventory)
            return;
        utils.waitForLoopEvent(40, () => {
            var _a, _b;
            if (!this.Entity.isValid())
                return true;
            for (let index = 0; index < inventory.size; index++) {
                const item = inventory.getItem(index);
                if ((item === null || item === void 0 ? void 0 : item.typeId.startsWith("ldz_crcomp:hat")) && !item.getLore().length) {
                    item.setLore(WornHat.LoreTable[item.typeId]);
                    inventory.setItem(index, item);
                }
            }
            const headItem = (_a = this.Entity.Equipment) === null || _a === void 0 ? void 0 : _a.getEquipment(mc.EquipmentSlot.Head);
            if ((headItem === null || headItem === void 0 ? void 0 : headItem.typeId.startsWith("ldz_crcomp:hat")) && !headItem.getLore().length) {
                headItem.setLore(WornHat.LoreTable[headItem.typeId]);
                (_b = this.Entity.Equipment) === null || _b === void 0 ? void 0 : _b.setEquipment(mc.EquipmentSlot.Head, headItem);
            }
            return !this.Entity.isValid();
        });
    }
    async hatCheckLoop() {
        var _a;
        while (this.Entity.isValid() && this.isValid) {
            const hatId = this.HatId;
            if (hatId === null || hatId === void 0 ? void 0 : hatId.startsWith("ldz_crcomp:hat")) {
                if (((_a = this.currentHat) === null || _a === void 0 ? void 0 : _a.hatTypeId) === hatId) {
                    await utils.waitForTicks(20);
                    continue;
                }
                ;
                if (this.currentHat) {
                    utils.mclog(`Unequipping ${this.currentHat.hatTypeId}`);
                    await this.currentHat.onUnequip();
                }
                const hatType = WornHat.HatTable[hatId];
                if (hatType) {
                    this.currentHat = new hatType(this);
                    utils.mclog(`Equipping ${this.currentHat.hatTypeId}`);
                    this.currentHat.onEquip();
                }
                else {
                    this.currentHat = undefined;
                }
            }
            if (hatId === undefined && this.currentHat) {
                utils.mclog(`Unequipping ${this.currentHat.hatTypeId}`);
                await this.currentHat.onUnequip();
                this.currentHat = undefined;
            }
            await utils.waitForTicks(10);
        }
    }
    static async instantiateHatWearer(query) {
        await utils.waitForWorldLoad();
        mc.world.afterEvents.entitySpawn.subscribe(event => {
            if (event.entity.isValid() && event.entity.matches(query)) {
                try {
                    new HatWearer(event.entity);
                }
                catch (error) { }
            }
        });
        mc.world.afterEvents.entityLoad.subscribe(event => {
            if (event.entity.isValid() && event.entity.matches(query)) {
                try {
                    new HatWearer(event.entity);
                }
                catch (error) { }
            }
        });
        mc.world.afterEvents.playerSpawn.subscribe(event => {
            try {
                new HatWearer(event.player);
            }
            catch (error) { }
        });
        try {
            utils.overworld.getEntities(query).forEach(entity => new HatWearer(entity));
            utils.nether.getEntities(query).forEach(entity => new HatWearer(entity));
            utils.end.getEntities(query).forEach(entity => new HatWearer(entity));
        }
        catch (error) { }
    }
}
HatWearer.wearerList = {};
HatWearer.instantiateHatWearer({ type: "ldz_crcomp:craftee" });
HatWearer.instantiateHatWearer({ type: "minecraft:player" });
