import { BlockPermutation, EquipmentSlot, ItemStack, world, } from "@minecraft/server";
import { namespace } from "../../../config/_config";
import { decreaseItemAmountInHand, getItemInSlot } from "../../helper/utils";
import { MultiPlacementBlock } from "./multiPlacementBlock";
// Define the BoneMealBlock class to handle custom bone-meal related functionality.
export class BoneMealBlock {
    constructor() {
        BoneMealBlock.initialize();
    }
    // This static method initializes the BoneMealBlock and registers a custom component.
    static initialize() {
        world.beforeEvents.worldInitialize.subscribe((event) => {
            event.blockComponentRegistry.registerCustomComponent(`${namespace}:bone_mealable`, {
                onPlayerInteract: (event) => {
                    this.dropLoot(event);
                },
            });
        });
    }
    // This static method handles the logic for applying bone meal to a block and dropping loot.
    static dropLoot(event) {
        const block = event.block; // Get the block being interacted with
        // Check if the player is holding bone meal in their main hand
        if (getItemInSlot(event.player, EquipmentSlot.Mainhand)?.typeId !== "minecraft:bone_meal")
            return; // Exit early if the player isn't holding bone meal
        if (!block)
            return; // Exit if there's no block
        // Retrieve information about the block's type, if it's a multi-placement block
        const multiBlock = MultiPlacementBlock.getBlockByIdentifier(block.typeId);
        // Define the location where effects (particles, sounds) will spawn
        const location = {
            x: block.location.x + 0.5,
            y: block.location.y + 0.5,
            z: block.location.z + 0.5,
        };
        // Decrease the amount of bone meal in the player's hand by 1
        decreaseItemAmountInHand(event.player, 1, true);
        // If the block is a multi-placement block, handle bone meal interaction
        if (multiBlock) {
            // Get the current state (progress) of the block
            const currentState = block.permutation.getState(`${namespace}:count`);
            const maxState = multiBlock.states; // Get the maximum state the block can reach
            // If the block isn't at its maximum state, increase its state by 1
            if (currentState < maxState) {
                const allStates = block.permutation.getAllStates(); // Get all current states of the block
                // Set a new permutation for the block, preserving other states but increasing the `count` state
                block.setPermutation(BlockPermutation.resolve(block.typeId, {
                    ...allStates,
                    [`${namespace}:count`]: currentState + 1, // Increment the `count` state
                }));
                // Spawn growth particles and play a sound to indicate the use of bone meal
                block.dimension.spawnParticle("minecraft:crop_growth_emitter", location);
                block.dimension.playSound("item.bone_meal.use", location);
                return; // Exit early after successfully increasing the state
            }
        }
        // Default behavior if the block can't be bone-mealed further: drop an item of the block's type
        const loot = new ItemStack(block.typeId); // Create an item stack of the block's type
        // Spawn the item, particles, and play the sound
        block.dimension.spawnItem(loot, location);
        block.dimension.spawnParticle("minecraft:crop_growth_emitter", location);
        block.dimension.playSound("item.bone_meal.use", location);
    }
}
