var _a, _b;
import * as mc from "@minecraft/server";
import * as utils from "../utils/index";
import { getDirectionFromRotation } from "../shared/rotation";
const DURATION = 5 * mc.TicksPerSecond;
export async function chestAbility(player) {
    utils.mclog(`chest`);
    player.dimension.spawnEntity("ldz:chest_ability", player.location);
}
class Chest extends utils.Actor {
    constructor() {
        var _c;
        super(...arguments);
        this.spawnTime = (_c = this.getDynamicProperty("ldz:spawn_time")) !== null && _c !== void 0 ? _c : mc.system.currentTick;
    }
    onConstructed() {
        Chest.registry.set(this.id, this);
        if (!this.getDynamicProperty("ldz:spawn_time")) {
            this.setDynamicProperty("ldz:spawn_time", this.spawnTime);
        }
        this.addActorComponent(ChestAttackComponent, {
            cooldown: 20,
        });
        if (!this.transform()) {
            this.soundLoop();
            this.despawnTimer();
        }
    }
    destructor() {
        Chest.registry.delete(this.id);
        super.destructor();
    }
    async despawnTimer() {
        await utils.waitForTicks(DURATION);
        while (this.isValid() && this.getProperty("ldz:has_target")) {
            utils.mclog(`Despawn delayed as chest has target`);
            await utils.waitForTicks(20);
        }
        utils.mclog(`Despawn timer finished and no targets found, despawning in 1 second`);
        await utils.waitForTicks(20);
        if (this.isValid()) {
            this.transform();
        }
    }
    async soundLoop() {
        while (this.isValid()) {
            this.playSoundAt("entity.chest_ability.ambient");
            await utils.waitForTicks(utils.getRandomArrayEntry([40, 80, 120]));
        }
    }
    transform() {
        var _c;
        if (this.spawnTime + DURATION > mc.system.currentTick)
            return false;
        utils.mclog("Transforming into chest", this.ActorId);
        try {
            const block = this.dimension.getBlock(this.location);
            if (block) {
                block.setPermutation(mc.BlockPermutation.resolve("minecraft:chest", { "minecraft:cardinal_direction": getDirectionFromRotation(this.getRotation()) }));
                const sourceInventory = this.Inventory;
                const targetInventory = (_c = block.getComponent("minecraft:inventory")) === null || _c === void 0 ? void 0 : _c.container;
                if (sourceInventory && targetInventory) {
                    for (let i = 0; i < sourceInventory.size; i++) {
                        const item = sourceInventory.getItem(i);
                        targetInventory.setItem(i, item);
                        sourceInventory.setItem(i, undefined);
                    }
                }
                this.dimension.spawnParticle("ldz:spawn_effect_small", this.location);
                this.playSoundAt("random.fizz");
            }
            this.remove();
        }
        catch (error) { }
        return true;
    }
}
_a = Chest;
Chest.registry = new Map();
(() => {
    // Registers the transform event which is broadcast when the chest_ability has no targets
    utils.afterEvents.scriptEventRecieve.subscribe("ldz:chest_transform", event => {
        if (event.sourceEntity) {
            const chest = _a.registry.get(event.sourceEntity.id);
            chest === null || chest === void 0 ? void 0 : chest.transform();
        }
    });
})();
class ChestAttackComponent extends utils.ActorComponent {
    constructor() {
        super(...arguments);
        this.lastAttackTime = mc.system.currentTick;
    }
    get InCooldown() {
        return this.lastAttackTime + this.options.cooldown > mc.system.currentTick;
    }
    onComponentAdded() {
        ChestAttackComponent.registry.set(this.actor.id, this);
    }
    onComponentRemoved() {
        var _c;
        ChestAttackComponent.registry.delete(this.actor.id);
        if (((_c = ChestAttackComponent.listener) === null || _c === void 0 ? void 0 : _c.id) === this.actor.id) {
            ChestAttackComponent.listener = undefined;
        }
    }
    async attack(target) {
        if (this.InCooldown)
            return;
        this.lastAttackTime = mc.system.currentTick;
        const inventory = this.actor.Inventory;
        this.actor.playAnimation("animation.chest_ability.trigger_attack");
        await utils.waitForTicks(0.25 * mc.TicksPerSecond);
        if (this.actor.isValid() && target.isValid() && inventory) {
            // Try getting spawn egg from victim
            const typeId = target.typeId.replace("minecraft:", "") + "_spawn_egg";
            try {
                inventory.addItem(new mc.ItemStack(typeId, 1));
            }
            catch (_error) {
                utils.mcwarn(`${typeId} not a valid spawn egg for ${target.typeId}`, this.id);
            }
        }
        if (target.isValid()) {
            target.dimension.spawnParticle("ldz:spawn_effect_small", target.location);
            target.remove();
        }
    }
}
_b = ChestAttackComponent;
ChestAttackComponent.registry = new Map();
(() => {
    utils.afterEvents.scriptEventRecieve.subscribe("ldz:chest_attack", event => {
        var _c;
        if (event.data === "attacker" && event.sourceEntity) {
            const component = _b.registry.get(event.sourceEntity.id);
            if (component) {
                _b.listener = component;
            }
        }
        else if (event.data === "victim" && event.sourceEntity) {
            if (!((_c = _b.listener) === null || _c === void 0 ? void 0 : _c.actor.isValid())) {
                utils.mcerror(`No listener found for victim`, "ChestAttackComponent");
                return;
            }
            _b.listener.attack(event.sourceEntity);
        }
    });
})();
utils.Actor.makeActors({ type: "ldz:chest_ability" }, Chest);
