import { BlockPermutation, world,system } from "@minecraft/server";
import Timer from "../timer/timerClass";

system.beforeEvents.startup.subscribe((initEvent) => {
    initEvent.blockComponentRegistry.registerCustomComponent("rustic:door_components", {
        beforeOnPlayerPlace: e => {
            const { player, block, face, permutationToPlace, dimension } = e;
            if((!block.above().isAir && !block.above().isLiquid) || block.above().hasTag("rustic:isSolid")){
                e.cancel = true
                return;
            }

            const permDirection = permutationToPlace.getState("minecraft:cardinal_direction");

            let isDouble = false

            let directions = [
                { dir: () => block.north(), growStage: 8 },
                { dir: () => block.east(), growStage: 5 },
                { dir: () => block.south(), growStage: 7 },
                { dir: () => block.west(), growStage: 6 }
            ];
                
            directions.sort(() => Math.random() - 0.5);
            
                
            for (let direction of directions) {
                if (direction.dir().hasTag("door")){
                    if (direction.dir().permutation.getState("minecraft:cardinal_direction") == permDirection && direction.dir().permutation.getState("r:double") != true) {
                        isDouble = true
                        break;
                    }
                }
                
            }   
            system.run(() => {block.above().setPermutation(BlockPermutation.resolve(permutationToPlace.type.id,{"minecraft:cardinal_direction":permDirection,"r:type":'upper',"r:double":isDouble}))})
            e.permutationToPlace = permutationToPlace.withState('r:double', isDouble);
            // Your code here
        },
        onPlayerInteract: (event) => {
            const { player, block, dimension, face, faceLocation } = event;
            const isBottom = block.permutation.getState("r:type") == 'bottom' ? true : false
            const interact = block.permutation.getState("r:interact")
            const soundId = !interact == true ? "open.wooden_door" : "close.wooden_door"

            block.setPermutation(block.permutation.withState("r:interact",!interact))

            player.dimension.runCommand(`playsound ${soundId} @a ${block.x} ${block.y} ${block.z}`)

            if(isBottom){
                block.above().setPermutation(block.above().permutation.withState("r:interact",!interact))
            }
            else block.below().setPermutation(block.below().permutation.withState("r:interact",!interact))
            
        },
    });
});

world.beforeEvents.playerBreakBlock.subscribe(eventData => {
    const block = eventData.block;

    if (!block.hasTag("door"))return;

    const typePerm = block.permutation.getState("r:type")

    system.run( () => {
        if (typePerm == "bottom")
            block.above().setType("minecraft:air");
        else{
            block.below().setType("minecraft:air");
        }
    })
})

world.afterEvents.pressurePlatePush.subscribe(eventData => {
    const block = eventData.block;

    ["north", "east", "south", "west"].forEach(direction => {
        handleDoorInteraction(() => block[direction](), true);
    });


})

world.afterEvents.pressurePlatePop.subscribe(eventData => {
    const block = eventData.block;

    ["north", "east", "south", "west"].forEach(direction => {
        handleDoorInteraction(() => block[direction](), false);
    });

})

world.afterEvents.buttonPush.subscribe(eventData => {
    const block = eventData.block;

    handleButtonDoorInteraction(block,true);

    let timer = Timer.set(1, "seconds");

    let intervalId = system.runInterval(() => {
        let isExpired = Timer.hasExpired(timer);     

        if (isExpired) {
            handleButtonDoorInteraction(block,false);
            system.clearRun(intervalId);
        }
    }, 15);

})

world.afterEvents.leverAction.subscribe(eventData => {
    const block = eventData.block;
    const leverToggle = block.permutation.getState("open_bit")

    handleButtonDoorInteraction(block,leverToggle);

})

world.afterEvents.playerBreakBlock.subscribe(eventData => {
    const block = eventData.block;
    const brokenBlock = eventData.brokenBlockPermutation
    if (brokenBlock.type.id == "minecraft:lever"){
        const leverToggle = brokenBlock.getState("open_bit")
        if (leverToggle == true)handleButtonDoorInteraction(block,!leverToggle);
        
    }

})



export function handleDoorInteraction(directionFunc, shouldOpen) {
    const adjacentBlock = directionFunc();
    
    if (adjacentBlock.hasTag("door")) {
        const interact = adjacentBlock.permutation.getState("r:interact");
        const isBottom = adjacentBlock.permutation.getState("r:type") === "bottom";
        const soundId = shouldOpen ? "open.wooden_door" : "close.wooden_door";
        
        if (interact !== shouldOpen) {
            const targetBlock = isBottom ? adjacentBlock.above() : adjacentBlock.below();
            
            adjacentBlock.setPermutation(adjacentBlock.permutation.withState("r:interact", shouldOpen));
            targetBlock.setPermutation(targetBlock.permutation.withState("r:interact", shouldOpen));

            adjacentBlock.dimension.runCommand(`playsound ${soundId} @a ${adjacentBlock.x} ${adjacentBlock.y} ${adjacentBlock.z}`);
        }
    }
}

export function handleButtonDoorInteraction(block,shouldOpen) {
    const corners = {
        northeast: () => block.north().east(),
        northwest: () => block.north().west(),
        southeast: () => block.south().east(),
        southwest: () => block.south().west()
    };
    
    ["north", "east", "south", "west"].forEach(direction => {
        handleDoorInteraction(() => block[direction](), shouldOpen);
    });

    Object.values(corners).forEach(cornerFunc => {
        handleDoorInteraction(cornerFunc, shouldOpen);
    });
}

