import { system, ItemDurabilityComponent, GameMode, ItemEnchantableComponent } from '@minecraft/server';
import { BlockManager } from '../block/manager';
import { ItemManager } from '../item/manager';
export class treecapitatorManager {
    static logIDs = [
        "minecraft:oak_log",
        "minecraft:spruce_log",
        "minecraft:acacia_log",
        "minecraft:jungle_log",
        "minecraft:dark_oak_log",
        "minecraft:cherry_log",
        "minecraft:birch_log",
        "minecraft:mangrove_log",
        "minecraft:crimson_stem",
        "minecraft:warped_stem",
        "minecraft:oak_wood",
        "minecraft:spruce_wood",
        "minecraft:acacia_wood",
        "minecraft:jungle_wood",
        "minecraft:dark_oak_wood",
        "minecraft:cherry_wood",
        "minecraft:birch_wood",
        "minecraft:mangrove_wood",
        "minecraft:crimson_hyphae",
        "minecraft:warped_hyphae",
        "minecraft:pale_oak_log",
        "minecraft:pale_oak_wood",
        "minecraft:brown_mushroom_block",
        "minecraft:red_mushroom_block"
    ];
    static start(player, brokenBlock, item, mainhand) {
        const durComp = item.getComponent(ItemDurabilityComponent.componentId);
        if (!durComp)
            return;
        const typeId = brokenBlock.typeId;
        const enchComp = item.getComponent(ItemEnchantableComponent.componentId);
        let unbreakingLevel = undefined;
        let silkTouched = false;
        if (enchComp) {
            if (enchComp.hasEnchantment("unbreaking")) {
                unbreakingLevel = enchComp.getEnchantment("unbreaking").level;
            }
            silkTouched = enchComp.hasEnchantment("silk_touch");
        }
        const initialLoc = brokenBlock.location;
        let blockAmount = 0;
        let leafAmount = 0;
        function getBlocks(block) {
            if (!player || !player.isValid())
                return;
            if (mainhand.getItem()?.typeId !== item.typeId)
                return;
            if (blockAmount >= treecapitatorManager.limit)
                return;
            const typeId = block.typeId;
            typeId.includes("leaves") ? leafAmount++ : blockAmount++;
            BlockManager.destroyBlock(block.dimension, block.location);
            if (player.getGameMode() != GameMode.creative && !typeId.includes("leaves") && ItemManager.reduceDurability(unbreakingLevel)) {
                if (durComp.damage + 1 >= durComp.maxDurability) {
                    player.dimension.playSound("random.break", player.location);
                    mainhand.setItem(undefined);
                }
                else {
                    durComp.damage++;
                    mainhand.setItem(item);
                }
            }
            system.runTimeout(() => {
                if (!block || !block.isValid())
                    return;
                for (const otherblock of BlockManager.getBlocksAround(block)) {
                    const loc = otherblock?.location;
                    if (otherblock && loc !== undefined && !(loc.x === initialLoc.x && loc.y === initialLoc.y && loc.z === initialLoc.z) && (otherblock.typeId == typeId || (treecapitatorManager.logIDs.includes(typeId) && otherblock?.typeId.includes("leaves")))) {
                        if (!otherblock.typeId.includes("leaves") || leafAmount < treecapitatorManager.leafLimit)
                            getBlocks(otherblock);
                    }
                }
            }, 1);
        }
        system.run(() => {
            BlockManager.getBlocksAround(brokenBlock).forEach((block) => {
                if (block?.typeId === typeId || (this.logIDs.includes(typeId) && block?.typeId.includes("leaves")))
                    getBlocks(block);
            });
        });
        // [] []
    }
    static startNoLeaves(player, brokenBlock, item, mainhand) {
        const durComp = item.getComponent(ItemDurabilityComponent.componentId);
        if (!durComp)
            return;
        const typeId = brokenBlock.typeId;
        const enchComp = item.getComponent(ItemEnchantableComponent.componentId);
        let unbreakingLevel = undefined;
        let silkTouched = false;
        if (enchComp) {
            if (enchComp.hasEnchantment("unbreaking")) {
                unbreakingLevel = enchComp.getEnchantment("unbreaking").level;
            }
            silkTouched = enchComp.hasEnchantment("silk_touch");
        }
        const initialLoc = brokenBlock.location;
        let blockAmount = 0;
        let leafAmount = 0;
        function getBlocks(block) {
            if (!player || !player.isValid())
                return;
            if (mainhand.getItem()?.typeId !== item.typeId)
                return;
            if (blockAmount >= treecapitatorManager.limit)
                return;
            const typeId = block.typeId;
            BlockManager.destroyBlock(block.dimension, block.location);
            if (player.getGameMode() != GameMode.creative && ItemManager.reduceDurability(unbreakingLevel)) {
                if (durComp.damage + 1 >= durComp.maxDurability) {
                    player.dimension.playSound("random.break", player.location);
                    mainhand.setItem(undefined);
                }
                else {
                    durComp.damage++;
                    mainhand.setItem(item);
                }
            }
            system.runTimeout(() => {
                if (!block || !block.isValid())
                    return;
                for (const otherblock of BlockManager.getBlocksAround(block)) {
                    const loc = otherblock?.location;
                    if (otherblock && loc !== undefined && !(loc.x === initialLoc.x && loc.y === initialLoc.y && loc.z === initialLoc.z) && (otherblock.typeId == typeId))
                        getBlocks(otherblock);
                }
            }, 1);
        }
        system.run(() => {
            BlockManager.getBlocksAround(brokenBlock).forEach((block) => {
                if (block?.typeId === typeId)
                    getBlocks(block);
            });
        });
        // [] []
    }
    static limit = 2048;
    static leafLimit = 320;
    static isDenied(blockLoc, deniedLists) {
        for (const list of deniedLists) {
            for (const loc of list) {
                if (blockLoc.x == loc.x && blockLoc.y == loc.y && blockLoc.z == loc.z)
                    return true;
            }
        }
        return false;
    }
}
