import { BlockPermutation, EquipmentSlot, GameMode, ItemStack, world, } from "@minecraft/server";
import { namespace } from "../../../config/_config";
import { getItemInSlot, removeItemFromInventory } from "../../helper/utils";
export class MultiPlacementBlock {
    constructor(config) {
        this.id = config.id;
        this.sound = config.sound;
        this.states = config.states;
    }
    static register(block) {
        MultiPlacementBlock.blocks.push(block);
    }
    static registerBehavior(config) {
        const block = new MultiPlacementBlock(config);
        this.register(block);
    }
    static initialize() {
        world.beforeEvents.worldInitialize.subscribe((event) => {
            event.blockComponentRegistry.registerCustomComponent(`${namespace}:multi_block`, {
                onPlayerInteract: (event) => {
                    this.placeBlock(event);
                },
            });
        });
    }
    // Method that handles the logic when a player interacts with a block to place or update its state
    // Method that handles the logic when a player interacts with a block to place or update its state
    static placeBlock(event) {
        const targetBlock = event.block; // The block the player is interacting with
        let placeBlock = getItemInSlot(event.player, EquipmentSlot.Mainhand); // Get the block/item in the player's main hand
        // Exit early if there's no player, no block, or no item in hand
        if (!event.player || !targetBlock || !placeBlock)
            return;
        // Convert the held item to a block type (remove "_item" if present in the item type ID)
        placeBlock = new ItemStack(placeBlock?.typeId.split("_item")[0]);
        // Check if the player is interacting with a block of the same type they are holding
        if (targetBlock.typeId === placeBlock.typeId) {
            const blockData = MultiPlacementBlock.getBlockByIdentifier(placeBlock.typeId); // Get block data
            if (!blockData)
                return; // Exit if block data is not found
            // Get the current state of the block
            const currentState = parseInt(targetBlock.permutation.getState(`${namespace}:count`));
            const maxState = blockData.states; // Get the maximum number of states for the block
            let nextState = currentState + 1; // Increment the state
            // If the next state exceeds the maximum, exit early (no change)
            if (nextState > maxState) {
                return;
            }
            // Get all current states of the block and copy them into a new object
            const allStates = targetBlock.permutation.getAllStates();
            const direction = targetBlock.permutation.getState("minecraft:cardinal_direction");
            // Prepare the new state data, keeping all existing states and only modifying the count state
            const newStateData = {
                ...allStates,
                [`${namespace}:count`]: nextState,
                ...(direction && { ["minecraft:cardinal_direction"]: direction }), // Preserve direction if present
            };
            // Apply the new state to the block
            targetBlock.setPermutation(BlockPermutation.resolve(`${placeBlock.type.id}`, newStateData));
            // Play a sound when the block's state is updated
            if (blockData.sound) {
                world.playSound(blockData.sound, event.player.location);
            }
            // If the player is not in creative mode, remove one item from their inventory
            if (event.player.getGameMode() !== GameMode.creative) {
                removeItemFromInventory(event.player, placeBlock.typeId);
            }
        }
    }
    // Method to retrieve block data by its identifier
    static getBlockByIdentifier(identifier) {
        return MultiPlacementBlock.blocks.find((block) => block.id === identifier); // Return block data if found
    }
}
MultiPlacementBlock.blocks = [];
