//special thanks to ZoMb1eRaBb1tT for the corrupted used for this leaf decay. 

import { world, BlockPermutation } from '@minecraft/server';

// Allowed and leaf blocks combined into sets for quick lookups
const allowedBlocksSet = new Set([
    'lv_zo:corrupted_log', 'lv_zo:corrupted_log_stripped', 'minecraft:oak_log', 'minecraft:oak_log_stripped', 'minecraft:spruce_log', 'minecraft:spruce_log_stripped', 'minecraft:dark_oak_log', 'minecraft:dark_oak_log_stripped', 'minecraft:pale_oak_log', 'minecraft:pale_oak_log_stripped', 'minecraft:cherry_log', 'minecraft:cherry_log_stripped', 'minecraft:birch_log', 'minecraft:birch_log_stripped', 'minecraft:jungle_log', 'minecraft:jungle_log_stripped', 'minecraft:acacia_log', 'minecraft:acacia_log_stripped'
]);

const leafBlocksSet = new Set([
    'lv_zo:corrupted_leaves'
]);

// Check if an allowed block is nearby within a 6-block radius
function isWithinRadiusOfAllowedBlock(block, maxDistance) {
    try {
        const { x: startX, y: startY, z: startZ } = block.location;
        for (let x = startX - maxDistance; x <= startX + maxDistance; x++) {
            for (let y = startY - maxDistance; y <= startY + maxDistance; y++) {
                for (let z = startZ - maxDistance; z <= startZ + maxDistance; z++) {
                    const currentBlock = block.dimension.getBlock({ x, y, z });
                    if (currentBlock && allowedBlocksSet.has(currentBlock.typeId)) {
                        const distance = Math.sqrt(Math.pow(x - startX, 2) + Math.pow(y - startY, 2) + Math.pow(z - startZ, 2));
                        if (distance <= maxDistance) return true;
                    }
                }
            }
        }
        return false;
    } catch (error) {

        return false;
    }

}

// Recalculate persistence for a block based on nearby allowed blocks
function recalculatePersistence(block) {
    const persistent = isWithinRadiusOfAllowedBlock(block, 6);
    const currentStates = block.permutation.getAllStates();
    const newStates = { ...currentStates, 'lv_zo:persist': persistent };
    const newPermutation = BlockPermutation.resolve(block.typeId, newStates);
    block.setPermutation(newPermutation);

    if (!persistent && !block.permutation.getState('lv_zo:placed')) {
        const { x, y, z } = block.location;
        try {
            drop_leaf_loot(block);
            block.dimension.runCommand(`/setblock ${x} ${y} ${z} air destroy`);
        } catch (error) {
            console.error("Failed to set block to air:", error);
        }
    }
}

function drop_leaf_loot(block) {
    //let num = Math.round(Math.random() * 2)
    let num = 0
    if (num < 1) {
        let num = Math.round(Math.random() * 4)
        const { x, y, z } = block.location;
        if (block.typeId == "lv_zo:corrupted_leaves") {
            block.dimension.runCommand(`/loot spawn ${x} ${y} ${z} loot "plants/trees/corrupted/corrupted_leaves"`);
        }
    }
}


// Register custom component for leaf decay
world.beforeEvents.worldInitialize.subscribe(eventData => {
    eventData.blockComponentRegistry.registerCustomComponent('lv_zo:leaf_decay', {
        onRandomTick: (e) => {
            const { block } = e;
            if (leafBlocksSet.has(block.typeId)) recalculatePersistence(block);
        }
    });
});

// Handle player breaking blocks
world.afterEvents.playerBreakBlock.subscribe(eventData => {
    const { block } = eventData;
    if (allowedBlocksSet.has(block.typeId) || leafBlocksSet.has(block.typeId)) {
        recalculatePersistence(block);
    }
});

// Handle player placing blocks
world.afterEvents.playerPlaceBlock.subscribe(eventData => {
    const { block } = eventData;
    if (leafBlocksSet.has(block.typeId) && !block.permutation.getState('lv_zo:placed')) {
        const currentStates = block.permutation.getAllStates();
        const newStates = { ...currentStates, 'lv_zo:placed': true };
        const newPermutation = BlockPermutation.resolve(block.typeId, newStates);
        block.setPermutation(newPermutation);
    }
});