var _a;
import * as utils from "../../utils/index";
import { getHeartDataIndexFromName, HEART_DATA, heartItemNamePrefix } from "../../shared/heart_data";
import { crafteePopup, playUnobtainedHeartsMessage } from "../dialogue/craftee_dialogue";
export class HeartInventory extends utils.Actor {
    static addToPlayer(player) {
        if (this.registry.has(player.id))
            return this.registry.get(player.id);
        const entity = player.dimension.spawnEntity('ldz:inventory', player.location);
        if (utils.getScoreAsBool(".var", "PostGame")) {
            entity.nameTag = "heart_sorter.title.post_game";
        }
        else {
            entity.nameTag = "heart_sorter.title";
        }
        return new HeartInventory(entity, player);
    }
    static removeFromPlayer(player) {
        const inventory = this.registry.get(player.id);
        inventory === null || inventory === void 0 ? void 0 : inventory.remove();
    }
    static playerInventoryProcess(player) {
        const inventory = player.Inventory;
        if (inventory) {
            for (let index = 0; index < inventory.size; index++) {
                const item = inventory.getItem(index);
                if (item && item.typeId.includes(heartItemNamePrefix)) {
                    const heartIndex = getHeartDataIndexFromName(item.typeId);
                    if (!utils.getScoreAsBool(player, `Obtained_${heartIndex}`)) {
                        player.setScore(`Obtained_${heartIndex}`, 1);
                        player.playSound("ui.heart.unlock");
                        const hasInventory = this.registry.has(player.id);
                        this.addToPlayer(player).addHeart(heartIndex, index);
                        utils.waitForEvent(1, () => {
                            if (!hasInventory)
                                this.removeFromPlayer(player);
                        });
                        if (heartIndex <= 30) {
                            crafteePopup.addDialogueTag(player, HEART_DATA[heartIndex].displayName);
                            playUnobtainedHeartsMessage(player);
                        }
                    }
                }
            }
        }
        while (player.runCommand('testfor @s[hasitem={item=ldz:heart_sorter,quantity=2..}]').successCount) {
            player.runCommand('clear @s ldz:heart_sorter 0 1');
        }
    }
    constructor(entity, owner) {
        var _b;
        super(entity);
        this.owner = owner;
        HeartInventory.registry.set(owner.id, this);
        (_b = this.getComponent("tameable")) === null || _b === void 0 ? void 0 : _b.tame(owner.UnsafeEntity);
        utils.despawnOnReload(this);
        this.teleportToOwner();
        this.loadInventory();
        this.saveInventory();
    }
    destructor() {
        HeartInventory.registry.delete(this.owner.id);
        super.destructor();
    }
    async teleportToOwner() {
        while (this.isValid() && this.owner.isValid()) {
            this.teleport(this.owner.getHeadLocation(), { dimension: this.owner.dimension });
            await utils.waitForTicks(1);
        }
    }
    loadInventory() {
        const inventory = this.Inventory;
        if (inventory) {
            for (let index = 0; index < inventory.size; index++) {
                const score = this.owner.getScore(`Slot_${index}`);
                if (score > 0) {
                    inventory.setItem(index, HEART_DATA[score].Item);
                }
            }
        }
    }
    async saveInventory() {
        var _b;
        while (this.isValid() && this.owner.isValid()) {
            const inventory = this.Inventory;
            if (inventory) {
                for (let index = 0; index < inventory.size; index++) {
                    const item = inventory.getItem(index);
                    // If item is not a valid heart, give it to the owner
                    if (item && !item.typeId.includes(heartItemNamePrefix)) {
                        inventory.setItem(index);
                        (_b = this.owner.Inventory) === null || _b === void 0 ? void 0 : _b.addItem(item);
                    }
                    const heartIndex = getHeartDataIndexFromName(item === null || item === void 0 ? void 0 : item.typeId);
                    this.owner.setScore(`Slot_${index}`, heartIndex);
                }
            }
            await utils.waitForTicks(9);
        }
    }
    addHeart(heartIndex, fromIndex) {
        const inventory = this.Inventory;
        const ownerInventory = this.owner.Inventory;
        if (inventory && ownerInventory) {
            for (let index = 0; index < inventory.size; index++) {
                const score = this.owner.getScore(`Slot_${index}`);
                if (score <= 0) {
                    ownerInventory.setItem(fromIndex);
                    this.owner.setScore(`Slot_${index}`, heartIndex);
                    inventory.setItem(index, HEART_DATA[heartIndex].Item);
                    return;
                }
            }
        }
    }
}
_a = HeartInventory;
HeartInventory.registry = new Map();
(() => {
    utils.afterEvents.scriptEventRecieve.subscribe("ldz:add_inventory", event => {
        var _b;
        const player = (_b = event.sourceEntity) === null || _b === void 0 ? void 0 : _b.getPlayer();
        if (player) {
            _a.addToPlayer(player);
        }
    });
    utils.afterEvents.scriptEventRecieve.subscribe("ldz:remove_inventory", event => {
        var _b;
        const player = (_b = event.sourceEntity) === null || _b === void 0 ? void 0 : _b.getPlayer();
        if (player) {
            _a.removeFromPlayer(player);
        }
    });
    utils.waitForLoopEvent(10, () => {
        utils.getAllPlayersSafe().forEach(player => {
            if (player.isValid()) {
                _a.playerInventoryProcess(player);
            }
        });
    });
})();
