import * as mc from "@minecraft/server";
import { GlobalNamespace, SafetyCheckedEntity, waitForEvent, waitForLoopEvent, waitForTicks } from "../../utils/index";
import { Task } from "../../npc/tasks/task";
import { MoveToTargetTask } from "../../npc/tasks/moveToTarget";
export class MineVirtualBlockTask extends Task {
    constructor() {
        super(...arguments);
        this.cleanupBlock = true;
    }
    async performTask() {
        var _a;
        this.npc.Entity.addTag("mining");
        let virtualBlock = this.getVirtualBlock();
        if ((await new MoveToTargetTask(this.npc, Object.assign({ location: this.options.locationData.navigationLocation }, MOVE_TO_TARGET_DEFAULTS), this).start()).outcome !== "succeeded") {
            return { outcome: "failed" };
        }
        this.npc.Entity.playAnimation(virtualBlock.virtualBlockData.toolAnim);
        this.npc.Entity.teleport(this.options.locationData.navigationLocation, { facingLocation: this.options.locationData.interactLocation });
        await waitForTicks(10);
        waitForLoopEvent(5, () => {
            if (this.npc.Entity.location.distance(this.options.locationData.navigationLocation) > 0.5 || this.npc.Entity.location.distance(this.npc.Owner.location) > 15) {
                this.abort();
                return true;
            }
            return false;
        }, this.id);
        await this.mineVirtualBlock(virtualBlock.virtualBlockEntity, virtualBlock.virtualBlockData);
        while (true) {
            this.shouldAbort();
            if (!((_a = this.npc.Entity.dimension.getBlock(this.options.locationData.interactLocation)) === null || _a === void 0 ? void 0 : _a.matches("minecraft:air"))) {
                this.abort();
                this.cleanupBlock = false;
                break;
            }
            ;
            virtualBlock = this.getVirtualBlock();
            await this.mineVirtualBlock(virtualBlock.virtualBlockEntity, virtualBlock.virtualBlockData);
        }
        this.npc.Entity.removeTag("mining");
        return { outcome: "succeeded" };
    }
    async cleanupTask() {
        var _a;
        if (((_a = this.virtualBlockEntity) === null || _a === void 0 ? void 0 : _a.isValid()) && this.cleanupBlock) {
            this.npc.Entity.runCommand(`setblock ${this.virtualBlockEntity.location.down()} minecraft:air`);
            this.virtualBlockEntity.triggerEvent("despawn");
        }
        this.cleanupBlock = true;
        this.npc.Entity.removeTag("mining");
        this.npc.Entity.playAnimation("equip_null");
        await waitForTicks(0);
    }
    getVirtualBlock() {
        const virtualBlockData = this.getVirtualBlockData();
        const virtualBlockEntity = new SafetyCheckedEntity(this.npc.Entity.dimension.spawnEntity(this.options.virtualBlockTypeId, this.options.locationData.interactLocation.up()));
        this.virtualBlockEntity = virtualBlockEntity;
        virtualBlockEntity.setProperty("texture_index", virtualBlockData.textureIndex);
        waitForEvent(8, () => virtualBlockEntity.runCommand("setblock ~ ~-1 ~ ldz_crcomp:craftee_block"), this.id);
        return { virtualBlockData, virtualBlockEntity };
    }
    getVirtualBlockData() {
        const blockTable = BLOCK_DATA_TABLES[this.options.blockType];
        let totalWeight = 0;
        let lootItem = blockTable[0];
        for (const loot of blockTable) {
            let random = Math.random() * (totalWeight + loot.weight);
            if (random >= totalWeight) {
                lootItem = loot;
            }
            totalWeight += loot.weight;
        }
        return lootItem;
    }
    async mineVirtualBlock(virtualBlockEntity, virtualBlockData) {
        var _a;
        this.npc.Entity.addTag("mining");
        await waitForTicks(20, this.id);
        this.shouldAbort();
        this.npc.Entity.playAnimation(virtualBlockData.interactAnim, { blendOutTime: 0.1 });
        for (let second = 0; second <= 9; second++) {
            mc.world.playSound(`hit.${virtualBlockData.soundEffect}`, virtualBlockEntity.location, { volume: 0.25 });
            await waitForTicks(virtualBlockData.mineTime / 9, this.id);
            this.shouldAbort();
            virtualBlockEntity.triggerEvent("add_destroy");
        }
        this.npc.Entity.dimension.spawnParticle(GlobalNamespace.Namespace + virtualBlockData.particleName, virtualBlockEntity.location.add({ x: 0, y: 0.5, z: 0 }));
        this.npc.Entity.dimension.spawnParticle(GlobalNamespace.Namespace + virtualBlockData.particleName.replace('loot', 'block_destruct'), virtualBlockEntity.location);
        this.npc.Entity.runCommand(`playsound random.pop @a[r=16] ${virtualBlockEntity.location}`);
        this.npc.Entity.runCommand(`playsound dig.${virtualBlockData.soundEffect} @a[r=16] ${virtualBlockEntity.location}`);
        this.npc.Entity.runCommand(`setblock ${virtualBlockEntity.location.down()} minecraft:air`);
        this.npc.broadcastEvent(virtualBlockData.stat);
        virtualBlockEntity.triggerEvent("despawn");
        (_a = this.npc.VirtualInventory) === null || _a === void 0 ? void 0 : _a.addItems({ [virtualBlockData.lootItem]: 1 });
        await waitForTicks(20, this.id);
    }
}
const BLOCK_DATA_TABLES = {
    stone: [
        { lootItem: "minecraft:cobblestone", weight: 20, mineTime: 35, particleName: "loot_cobblestone", textureIndex: 0, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.cobblestone" },
        { lootItem: "minecraft:coal", weight: 15, mineTime: 35, particleName: "loot_coal", textureIndex: 1, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.coal" },
        { lootItem: "minecraft:raw_copper", weight: 10, mineTime: 35, particleName: "loot_raw_copper", textureIndex: 2, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.copper" },
        { lootItem: "minecraft:raw_iron", weight: 10, mineTime: 35, particleName: "loot_raw_iron", textureIndex: 3, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.iron" },
        { lootItem: "minecraft:raw_gold", weight: 5, mineTime: 35, particleName: "loot_raw_gold", textureIndex: 4, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.gold" },
        { lootItem: "minecraft:redstone", weight: 5, mineTime: 35, particleName: "loot_redstone_dust", textureIndex: 5, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.redstone" },
        { lootItem: "minecraft:lapis_lazuli", weight: 5, mineTime: 35, particleName: "loot_dye_powder_blue", textureIndex: 6, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.lapis" },
        { lootItem: "minecraft:emerald", weight: 3, mineTime: 35, particleName: "loot_emerald", textureIndex: 7, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.emerald" },
        { lootItem: "minecraft:diamond", weight: 1, mineTime: 35, particleName: "loot_diamond", textureIndex: 8, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.diamond" },
    ],
    andesite: [
        { lootItem: "minecraft:andesite", weight: 20, mineTime: 35, particleName: "loot_andesite", textureIndex: 36, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.andesite" },
    ],
    diorite: [
        { lootItem: "minecraft:diorite", weight: 20, mineTime: 35, particleName: "loot_diorite", textureIndex: 37, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.diorite" },
    ],
    granite: [
        { lootItem: "minecraft:granite", weight: 20, mineTime: 35, particleName: "loot_granite", textureIndex: 38, interactAnim: "mine", soundEffect: "stone", toolAnim: "equip_pickaxe", stat: "mined.granite" },
    ],
    deepslate: [
        { lootItem: "minecraft:cobbled_deepslate", weight: 20, mineTime: 35, particleName: "loot_deepslate", textureIndex: 9, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.deepslate" },
        { lootItem: "minecraft:coal", weight: 15, mineTime: 35, particleName: "loot_coal", textureIndex: 10, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.coal" },
        { lootItem: "minecraft:raw_copper", weight: 10, mineTime: 35, particleName: "loot_raw_copper", textureIndex: 11, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.copper" },
        { lootItem: "minecraft:raw_iron", weight: 10, mineTime: 35, particleName: "loot_raw_iron", textureIndex: 12, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.iron" },
        { lootItem: "minecraft:raw_gold", weight: 5, mineTime: 35, particleName: "loot_raw_gold", textureIndex: 13, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.gold" },
        { lootItem: "minecraft:redstone", weight: 5, mineTime: 35, particleName: "loot_redstone_dust", textureIndex: 14, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.redstone" },
        { lootItem: "minecraft:lapis_lazuli", weight: 5, mineTime: 35, particleName: "loot_dye_powder_blue", textureIndex: 15, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.lapis" },
        { lootItem: "minecraft:emerald", weight: 3, mineTime: 35, particleName: "loot_emerald", textureIndex: 16, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.emerald" },
        { lootItem: "minecraft:diamond", weight: 1, mineTime: 35, particleName: "loot_diamond", textureIndex: 17, interactAnim: "mine", soundEffect: "deepslate", toolAnim: "equip_pickaxe", stat: "mined.diamond" },
    ],
    dirt: [
        { lootItem: "minecraft:dirt", weight: 20, mineTime: 35, particleName: "loot_dirt", textureIndex: 18, interactAnim: "dig", soundEffect: "grass", toolAnim: "equip_shovel", stat: "mined.dirt" },
        { lootItem: "minecraft:gravel", weight: 10, mineTime: 35, particleName: "loot_gravel", textureIndex: 20, interactAnim: "dig", soundEffect: "gravel", toolAnim: "equip_shovel", stat: "mined.gravel" },
        { lootItem: "minecraft:flint", weight: 5, mineTime: 35, particleName: "loot_flint", textureIndex: 20, interactAnim: "dig", soundEffect: "gravel", toolAnim: "equip_shovel", stat: "mined.gravel" },
    ],
    sand: [
        { lootItem: "minecraft:sand", weight: 20, mineTime: 35, particleName: "loot_sand", textureIndex: 19, interactAnim: "dig", soundEffect: "sand", toolAnim: "equip_shovel", stat: "mined.sand" },
    ],
    soul_sand: [
        { lootItem: "minecraft:soul_sand", weight: 20, mineTime: 35, particleName: "loot_soul_sand", textureIndex: 21, interactAnim: "dig", soundEffect: "soul_sand", toolAnim: "equip_shovel", stat: "mined.soul_sand" },
        { lootItem: "minecraft:soul_soil", weight: 20, mineTime: 35, particleName: "loot_soul_soil", textureIndex: 21, interactAnim: "dig", soundEffect: "soul_soil", toolAnim: "equip_shovel", stat: "mined.soul_soil" },
    ],
    oak: [
        { lootItem: "minecraft:oak_log", weight: 20, mineTime: 35, particleName: "loot_log_oak", textureIndex: 22, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.oak_log" },
    ],
    acacia: [
        { lootItem: "minecraft:acacia_log", weight: 20, mineTime: 35, particleName: "loot_log_acacia", textureIndex: 29, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.acacia_log" },
    ],
    birch: [
        { lootItem: "minecraft:birch_log", weight: 20, mineTime: 35, particleName: "loot_log_birch", textureIndex: 30, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.birch_log" },
    ],
    cherry: [
        { lootItem: "minecraft:cherry_log", weight: 20, mineTime: 35, particleName: "loot_log_cherry", textureIndex: 31, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.cherry_log" },
    ],
    dark_oak: [
        { lootItem: "minecraft:dark_oak_log", weight: 20, mineTime: 35, particleName: "loot_log_dark_oak", textureIndex: 32, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.dark_oak_log" },
    ],
    jungle: [
        { lootItem: "minecraft:jungle_log", weight: 20, mineTime: 35, particleName: "loot_log_jungle", textureIndex: 33, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.jungle_log" },
    ],
    mangrove: [
        { lootItem: "minecraft:mangrove_log", weight: 20, mineTime: 35, particleName: "loot_log_mangrove", textureIndex: 34, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.mangrove_log" },
    ],
    spruce: [
        { lootItem: "minecraft:spruce_log", weight: 20, mineTime: 35, particleName: "loot_log_spruce", textureIndex: 35, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.spruce_log" },
    ],
    pale_oak: [
        { lootItem: "minecraft:pale_oak_log", weight: 20, mineTime: 35, particleName: "loot_log_pale_oak", textureIndex: 39, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.pale_oak_log" },
    ],
    crimson_log: [
        { lootItem: "minecraft:crimson_stem", weight: 20, mineTime: 35, particleName: "loot_crimson_log_side", textureIndex: 23, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.crimson_stem" },
    ],
    warped_stem: [
        { lootItem: "minecraft:warped_stem", weight: 20, mineTime: 35, particleName: "loot_warped_stem_side", textureIndex: 24, interactAnim: "chop", soundEffect: "wood", toolAnim: "equip_axe", stat: "mined.warped_stem" },
    ],
    netherrack: [
        { lootItem: "minecraft:netherrack", weight: 20, mineTime: 35, particleName: "loot_netherrack", textureIndex: 25, interactAnim: "mine", soundEffect: "netherrack", toolAnim: "equip_pickaxe", stat: "mined.netherrack" },
        { lootItem: "minecraft:gold_nugget", weight: 5, mineTime: 35, particleName: "loot_gold_nugget", textureIndex: 26, interactAnim: "mine", soundEffect: "netherrack", toolAnim: "equip_pickaxe", stat: "mined.nether_gold" },
        { lootItem: "minecraft:quartz", weight: 10, mineTime: 35, particleName: "loot_quartz", textureIndex: 27, interactAnim: "mine", soundEffect: "netherrack", toolAnim: "equip_pickaxe", stat: "mined.quartz" },
        { lootItem: "minecraft:netherite_scrap", weight: 0.1, mineTime: 35, particleName: "loot_netherite_scrap", textureIndex: 28, interactAnim: "mine", soundEffect: "ancient_debris", toolAnim: "equip_pickaxe", stat: "mined.ancient_debris" },
    ],
};
const MOVE_TO_TARGET_DEFAULTS = { startNavEvent: "start_goal_nav_node", endNavEvent: "end_goal_nav_node", navTargetTypeId: "ldz_crcomp:nav_node", stopDistance: 1 };
