import { system, world, } from "@minecraft/server";
import { namespace } from "../../../config/_config";
// DripstoneBlock class to handle custom behavior for placing and destroying dripstone blocks
export class DripstoneBlock {
    constructor() {
        DripstoneBlock.initialize();
    }
    // Method to initialize custom components and event handling for dripstone blocks
    static initialize() {
        world.beforeEvents.worldInitialize.subscribe((event) => {
            event.blockComponentRegistry.registerCustomComponent(`${namespace}:dripstone`, {
                // Handle events before a player places a block
                beforeOnPlayerPlace: (event) => this.handleBeforePlacement(event),
                onPlayerDestroy: (event) => this.handleBlockDestroy(event),
            });
        });
    }
    // Handle logic before a player places a dripstone block
    static handleBeforePlacement(event) {
        const block = event.block; // Block the player is interacting with
        const placeBlock = event.permutationToPlace; // Block being placed
        const face = event.face; // Face of the block being placed (Up/Down)
        const upBlock = block.above(); // Block above the current one
        const downBlock = block.below(); // Block below the current one
        // Handle logic when placing a block on the Up face (top side of the block)
        if (face === "Up") {
            if (downBlock?.typeId === placeBlock.type.id) {
                // Merge the placed block with the block below
                downBlock.setPermutation(downBlock.permutation.withState(`${namespace}:variant`, "merge"));
                // Handle special cases for multi-block structures (e.g., long dripstone)
                if (downBlock.below()?.typeId === placeBlock.type.id) {
                    // Set the block below as the base of the structure
                    downBlock
                        .below()
                        .setPermutation(downBlock.below().permutation.withState(`${namespace}:variant`, "base"));
                    // If there are more blocks below, adjust their states accordingly
                    if (downBlock.below()?.below()?.typeId === placeBlock.type.id) {
                        downBlock
                            .below()
                            ?.setPermutation(downBlock.below().permutation.withState(`${namespace}:variant`, "middle"));
                    }
                    // Handle cases where there are multiple blocks but the bottom one is different
                    if (downBlock.below()?.below()?.typeId === placeBlock.type.id &&
                        downBlock.below()?.below()?.below()?.typeId !== placeBlock.type.id) {
                        downBlock
                            .below()
                            ?.below()
                            ?.setPermutation(downBlock.below().below().permutation.withState(`${namespace}:variant`, "base"));
                    }
                }
            }
        }
        // Handle logic when placing a block on the Down face (bottom side of the block)
        if (face === "Down") {
            if (upBlock?.typeId === placeBlock.type.id) {
                // Merge the placed block with the block above
                upBlock.setPermutation(upBlock.permutation.withState(`${namespace}:variant`, "merge"));
                // Handle cases similar to the "Up" face, but for blocks above
                if (upBlock.above()?.typeId === placeBlock.type.id) {
                    upBlock
                        .above()
                        ?.setPermutation(upBlock.above().permutation.withState(`${namespace}:variant`, "base"));
                    if (upBlock.above()?.above()?.typeId === placeBlock.type.id) {
                        upBlock
                            .above()
                            ?.setPermutation(upBlock.above().permutation.withState(`${namespace}:variant`, "middle"));
                    }
                    if (upBlock.above()?.above()?.typeId === placeBlock.type.id &&
                        upBlock.above()?.above()?.above()?.typeId !== placeBlock.type.id) {
                        upBlock
                            .above()
                            ?.above()
                            ?.setPermutation(upBlock.above().above().permutation.withState(`${namespace}:variant`, "base"));
                    }
                }
            }
        }
        // Additional handling for face-based placement (for both Up and Down cases)
        if (face === "Up" && upBlock?.typeId === placeBlock.type.id) {
            // Set a specific state for "merge_direction" when placing above
            upBlock.setPermutation(upBlock.permutation.withState(`${namespace}:variant`, "merge_direction"));
            event.permutationToPlace = event.permutationToPlace.withState(`${namespace}:variant`, "merge_direction");
        }
        if (face === "Down" && downBlock?.typeId === placeBlock.type.id) {
            // Set a specific state for "merge_direction" when placing below
            downBlock.setPermutation(downBlock.permutation.withState(`${namespace}:variant`, "merge_direction"));
            event.permutationToPlace = event.permutationToPlace.withState(`${namespace}:variant`, "merge_direction");
        }
    }
    // Handle logic when a player destroys a dripstone block
    static handleBlockDestroy(event) {
        const block = event.block; // The block that is being destroyed
        const destroyedBlock = event.destroyedBlockPermutation; // The permutation (state) of the destroyed block
        const upBlock = block.above(); // Block above the destroyed one
        const downBlock = block.below(); // Block below the destroyed one
        // Delay execution to give time for block destruction to propagate
        system.runTimeout(() => {
            // Check if the destroyed block was part of an "up" structure (pointing upwards)
            if (destroyedBlock.getState("minecraft:block_face") === "up") {
                if (downBlock?.typeId === destroyedBlock.type.id &&
                    downBlock?.permutation.getState("minecraft:block_face") === "up") {
                    // Adjust the block below to reflect the change in structure (set it to "tip" variant)
                    downBlock.setPermutation(downBlock.permutation.withState(`${namespace}:variant`, "tip"));
                    // Adjust the block even further down if necessary (merge variant)
                    if (downBlock.below()?.typeId === destroyedBlock.type.id &&
                        downBlock?.permutation.getState("minecraft:block_face") === "up") {
                        downBlock
                            .below()
                            ?.setPermutation(downBlock.below()?.permutation?.withState(`${namespace}:variant`, "merge"));
                    }
                }
            }
            // Check if the destroyed block was part of a "down" structure (pointing downwards)
            if (destroyedBlock.getState("minecraft:block_face") === "down") {
                if (upBlock?.typeId === destroyedBlock.type.id &&
                    upBlock?.permutation.getState("minecraft:block_face") === "down") {
                    // Adjust the block above to reflect the change in structure (set it to "tip" variant)
                    upBlock.setPermutation(upBlock.permutation.withState(`${namespace}:variant`, "tip"));
                    // Adjust the block even further up if necessary (merge variant)
                    if (upBlock.above()?.typeId === destroyedBlock.type.id &&
                        upBlock?.permutation.getState("minecraft:block_face") === "down") {
                        upBlock
                            .above()
                            ?.setPermutation(upBlock.above().permutation.withState(`${namespace}:variant`, "merge"));
                    }
                }
            }
            // Additional logic to handle cases where the block face is "up"
            if (destroyedBlock.getState("minecraft:block_face") === "up" &&
                upBlock?.typeId === destroyedBlock.type.id) {
                if (upBlock?.typeId === destroyedBlock.type.id) {
                    upBlock.setPermutation(upBlock.permutation.withState(`${namespace}:variant`, "tip"));
                }
            }
            // Additional logic to handle cases where the block face is "down"
            if (destroyedBlock.getState("minecraft:block_face") === "down" &&
                downBlock?.typeId === destroyedBlock.type.id) {
                if (downBlock?.typeId === destroyedBlock.type.id) {
                    downBlock.setPermutation(downBlock.permutation.withState(`${namespace}:variant`, "tip"));
                }
            }
        });
    }
}
