import { world } from "@minecraft/server";
import { namespace } from "../../../config/_config";
export class DecayBlock {
    constructor({ id, lootTable, validBlocks, radius, }) {
        this.id = id;
        this.lootTable = lootTable;
        this.validBlocks = validBlocks;
        this.radius = radius;
    }
    static registerBehavior(config) {
        const block = new DecayBlock(config);
        this.register(block);
    }
    // Method to register a DecayBlock
    static register(block) {
        DecayBlock.blocks.push(block);
    }
    // Method to initialize and register custom components for leaves block decay behavior
    static initialize() {
        world.beforeEvents.worldInitialize.subscribe((event) => {
            // Register a custom component for leaves blocks
            event.blockComponentRegistry.registerCustomComponent(`${namespace}:leaves_block`, {
                beforeOnPlayerPlace: (event) => {
                    // Mark the block as player-placed using a custom state
                    event.permutationToPlace = event.permutationToPlace.withState(`${namespace}:player_placed`, true);
                },
                // Event handler for the random tick (natural decay of leaves)
                onRandomTick: (event) => DecayBlock.handleRandomTick(event),
            });
        });
    }
    // Method to check if a block is within a spherical radius from a center point
    static isWithinSphere(blockLocation, center, radius) {
        const dx = blockLocation.x - center.x;
        const dy = blockLocation.y - center.y;
        const dz = blockLocation.z - center.z;
        const distanceSquared = dx * dx + dy * dy + dz * dz; // Calculate the squared distance
        return distanceSquared <= radius * radius; // Return true if within the radius
    }
    // Placeholder method to return the block location (could be expanded for more complex logic)
    static getMaterial(blockLocation) {
        return blockLocation;
    }
    // Method to get the list of valid log blocks for a given DecayBlock (leaves)
    static getValidLogBlocks(leavesBlock) {
        return leavesBlock?.validBlocks || []; // Return valid blocks or an empty array if none exist
    }
    // Method to find nearby log blocks within a certain radius of the decaying block
    static findNearbyLog(event, validLogBlocks, radius) {
        const location = event.block.location; // Get the block's current location
        // Loop through all block positions within the given radius
        for (let xOffset = -radius; xOffset <= radius; xOffset++) {
            for (let yOffset = -radius; yOffset <= radius; yOffset++) {
                for (let zOffset = -radius; zOffset <= radius; zOffset++) {
                    const blockLocation = {
                        x: location.x + xOffset,
                        y: location.y + yOffset,
                        z: location.z + zOffset,
                    };
                    // Check if the block location is within the sphere radius
                    if (DecayBlock.isWithinSphere(blockLocation, location, radius)) {
                        // Get the block at the calculated location
                        const block = event.block.dimension.getBlock(DecayBlock.getMaterial(blockLocation));
                        if (block === undefined)
                            continue; // Skip if no block is found
                        // Return true if the block is a valid log block
                        if (validLogBlocks.includes(block.typeId)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false; // No valid log blocks found within the radius
    }
    // Method to handle the random tick event for decay (triggered periodically for blocks)
    static handleRandomTick(event) {
        // Find the corresponding DecayBlock for the current block type
        const leavesBlock = DecayBlock.blocks.find((block) => block.id === event.block.typeId);
        // Get the valid log blocks and decay radius for the current leaves block
        const validLogBlocks = DecayBlock.getValidLogBlocks(leavesBlock);
        const radius = leavesBlock?.radius || 4; // Default radius is 4 if not defined
        // Check if there are no nearby logs and the block was not placed by a player
        if (!DecayBlock.findNearbyLog(event, validLogBlocks, radius) &&
            event.block.permutation.getState(`${namespace}:player_placed`) === false) {
            // If no logs are nearby, decay the block (turn it into air)
            event.block.setType("air");
            // If the block has a loot table, spawn the loot at the block's location
            if (leavesBlock) {
                event.block.dimension.runCommand(`loot spawn ${event.block.location.x} ${event.block.location.y} ${event.block.location.z} loot "${leavesBlock.lootTable}"`);
            }
        }
    }
}
// Array to store all registered DecayBlock instances
DecayBlock.blocks = [];
