import { world, system, BlockPermutation, ItemStack, EnchantmentType } from "@minecraft/server"
import { ModalFormData, MessageFormData } from "@minecraft/server-ui"
import { ChannelKey } from './channel_key.js';


import * as book from './guide_book.js'
import * as transplanter from './transplanter.js'

import { BlockDispenserComponent } from './block_dispenser.js'
import { EntityBreederComponent } from './breeder.js'
import { BucketRefillerComponent } from './bucket_refiller.js'
import { ConveyorComponent } from './conveyor.js'
import { CustomRepeaterComponent } from './custom_repeater.js'
import { ElevatorControlRailComponent, ElevatorRailComponent, ElevatorFloorComponent } from './elevator.js'
import { EntitySensorComponent } from './entity_sensor.js'
import { EntityTeleporterComponent } from './entity_teleporter.js'
import { FanComponent } from './fan.js'
import { HopperDropperComponent } from './hopper_dropper.js'
import { ItemFilterComponent } from './item_filter.js'
import { ItemMagnetComponent } from './item_magnet.js'
import { ItemTeleporterComponent } from './item_teleporter.js'
import { SawComponent } from './mechanical_saw.js'
import { DrillComponent } from './mechanical_drill.js'
import { RainSensorComponent } from './rain_sensor.js'
import { RedstoneCounterComponent } from './redstone_counter.js'
import { RedstoneLooperComponent } from './redstone_looper.js'
import { RedstoneDisplayComponent } from './redstone_display.js'
import { RedstoneRandomizerComponent } from './redstone_randomizer.js'
import { RemoteControlledRedstoneComponent, RedstoneControllerComponent } from './remote_controlled_redstone.js'
import { SpikeComponent } from './spike.js'
import { WirelessRedstoneComponent } from './wireless_redstone.js'
import { XpTankComponent } from './xp_tank.js'



//Update
import { RedstoneOreDetectorComponent } from './redstone_ore_detector.js'
import { FertilizerComponent } from './fertilizer.js'
import { SuperSmelterComponent } from './super_smelter.js'
import { AutoComposterComponent } from './auto_composter.js'
import { OreRefinerComponent } from './ore_refiner.js'
import { GrinderComponent } from './grinder.js'
import * as harvester from './harvester.js'
import * as portable_dropper from './portable_dropper.js'
import * as portable_block_dispenser from './portable_block_dispenser.js'
import * as portable_magnet from './portable_magnet.js'
import * as portable_drill from './portable_drill.js'
import * as rail_placer from './rail_placer.js'
import * as quarry_machine from './quarry_machine.js'




//console.warn("console loaded")

world.beforeEvents.worldInitialize.subscribe(function (initEvent) {

    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:item_filter', new ItemFilterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:hopper_dropper', new HopperDropperComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:entity_sensor', new EntitySensorComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:custom_repeater', new CustomRepeaterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:redstone_counter', new RedstoneCounterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:redstone_looper', new RedstoneLooperComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:xp_tank', new XpTankComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:redstone_randomizer', new RedstoneRandomizerComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:spike', new SpikeComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:entity_breeder', new EntityBreederComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:item_teleporter', new ItemTeleporterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:conveyor', new ConveyorComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:item_magnet', new ItemMagnetComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:fan', new FanComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:wireless_redstone', new WirelessRedstoneComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:remote_controlled_redstone', new RemoteControlledRedstoneComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:entity_teleporter', new EntityTeleporterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:saw', new SawComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:drill', new DrillComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:block_dispenser', new BlockDispenserComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:bucket_refiller', new BucketRefillerComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:redstone_display', new RedstoneDisplayComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:rain_sensor', new RainSensorComponent());

    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:elevator_rail', new ElevatorRailComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:elevator_control_rail', new ElevatorControlRailComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:elevator_floor', new ElevatorFloorComponent());

    initEvent.itemComponentRegistry.registerCustomComponent('pb_red:redstone_controller', new RedstoneControllerComponent());


    //update
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:redstone_ore_detector', new RedstoneOreDetectorComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:fertilizer', new FertilizerComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:super_smelter', new SuperSmelterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:auto_composter', new AutoComposterComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:ore_refiner', new OreRefinerComponent());
    initEvent.blockComponentRegistry.registerCustomComponent('pb_red:grinder', new GrinderComponent());

});



const entityTeleporterComponent = new EntityTeleporterComponent();
const itemTeleporterComponent = new ItemTeleporterComponent();
const wirelessRedstoneComponent = new WirelessRedstoneComponent();
const remoteControlledRedstoneComponent = new RemoteControlledRedstoneComponent();
const xpTankComponent = new XpTankComponent()
const entitySensorComponent = new EntitySensorComponent()
const redstoneCounterComponent = new RedstoneCounterComponent()
const customRepeaterComponent = new CustomRepeaterComponent()





world.afterEvents.pistonActivate.subscribe((e) => {
    let blocks = e.piston.getAttachedBlocks()
    let pistonLoc = e.piston.block.location

    blocks.forEach(block => {
        let newBlockLoc = applyOffset(block.location, calculateOffset(pistonLoc, block.location), e.isExpanding)
        let newBlock = e.dimension.getBlock(newBlockLoc)
        system.runTimeout(() => {

            if (newBlock.permutation.matches("pb_red:entity_teleporter")) {
                if (newBlock.permutation.getState('pb_red:powered') === false)
                    return
                const colorChannel = newBlock.permutation.getState('pb_red:color_channel');
                if (colorChannel !== undefined) {
                    entityTeleporterComponent.removeEntityTeleporterData(block, colorChannel);
                    entityTeleporterComponent.updateEntityTeleporterData(newBlock, colorChannel)

                    const blockChannelKey = new ChannelKey(block, null);
                    const newBlockChannelKey = new ChannelKey(newBlock, null);
                    const key = blockChannelKey.getKey(block)
                    newBlockChannelKey.setKey(newBlock, key)
                    blockChannelKey.removeBlockKey()

                    return
                }
            }
            if (newBlock.permutation.matches("pb_red:elevator_control_rail") || newBlock.permutation.matches("pb_red:elevator_rail")) {
                const direction = newBlock.permutation.getState('minecraft:cardinal_direction');
                const elevatorBlock = getBlockInDirection(block, direction);
                const elevatorBlockCenter = { x: elevatorBlock.location.x + 0.5, y: elevatorBlock.location.y + 0.5, z: elevatorBlock.location.z + 0.5 }
                const entity = newBlock.dimension.getEntities({ location: elevatorBlockCenter, maxDistance: 1, type: "pb_red:elevator" })[0]
                if (entity && entity.location.x == elevatorBlockCenter.x && entity.location.z == elevatorBlockCenter.z && (Math.floor(entity.location.y) + 0.5) == elevatorBlockCenter.y) {
                    const isRoom = entity.getProperty("pb_red:is_room")
                    system.runTimeout(() => {
                        const inv = entity.getComponent('inventory').container;
                        const location = { x: entity.location.x, y: entity.location.y + 1, z: entity.location.z };
                        for (let i = 0; i < inv.size; i++) {
                            const item = inv.getItem(i);
                            if (item) entity.dimension.spawnItem(item, location);
                        }
                        entity.remove()
                        system.runTimeout(() => {
                            block.dimension.runCommand(`fill ${elevatorBlockCenter.x - 1} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z - 1} ${elevatorBlockCenter.x + 1} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z + 1} minecraft:air replace`);
                        })
                        if (isRoom)
                            dimension.spawnItem(new ItemStack("pb_red:spawn_elevator_cabin", 1), elevatorBlockCenter);
                        else
                            dimension.spawnItem(new ItemStack("pb_red:spawn_elevator", 1), elevatorBlockCenter);
                        newBlock.dimension.runCommand(`playsound random.break @a ${block.location.x} ${block.location.y} ${block.location.z}`)
                    }, 10)
                }
                return
            }
            if (newBlock.permutation.matches("pb_red:xp_tank")) {
                xpTankComponent.removeDynamicProperties(block);
                newBlock.dimension.runCommandAsync(`setblock ${newBlockLoc.x} ${newBlockLoc.y} ${newBlockLoc.z} air destroy`)
                xpTankComponent.removeDynamicProperties(newBlock);
                return
            }
            if (newBlock.permutation.matches("pb_red:entity_sensor")) {
                entitySensorComponent.removeDynamicProperties(block);
                newBlock.dimension.runCommandAsync(`setblock ${newBlockLoc.x} ${newBlockLoc.y} ${newBlockLoc.z} air destroy`)
                entitySensorComponent.removeDynamicProperties(newBlock);
                return
            }
            if (newBlock.permutation.matches("pb_red:redstone_counter")) {
                redstoneCounterComponent.removeDynamicProperties(block);
                newBlock.dimension.runCommandAsync(`setblock ${newBlockLoc.x} ${newBlockLoc.y} ${newBlockLoc.z} air destroy`)
                redstoneCounterComponent.removeDynamicProperties(newBlock);
                return
            }
            if (newBlock.permutation.matches("pb_red:custom_repeater")) {
                customRepeaterComponent.removeDynamicProperties(block);
                newBlock.dimension.runCommandAsync(`setblock ${newBlockLoc.x} ${newBlockLoc.y} ${newBlockLoc.z} air destroy`)
                customRepeaterComponent.removeDynamicProperties(newBlock);
                return
            }

            // update
            if (newBlock.permutation.matches("pb_red:redstone_ore_detector")) {
                newBlock.dimension.runCommandAsync(`setblock ${newBlockLoc.x} ${newBlockLoc.y} ${newBlockLoc.z} air destroy`)
                return
            }
            //



            const colorChannel = newBlock.permutation.getState('pb_red:color_channel');
            if (colorChannel !== undefined) {

                const blockChannelKey = new ChannelKey(block, null);
                const newBlockChannelKey = new ChannelKey(newBlock, null);
                const key = blockChannelKey.getKey(block)
                newBlockChannelKey.setKey(newBlock, key)
                blockChannelKey.removeBlockKey()

                if (newBlock.permutation.matches("pb_red:item_teleporter")) {
                    itemTeleporterComponent.removeDynamicProperties(block);
                    itemTeleporterComponent.updateDynamicProperties(newBlock, colorChannel, colorChannel, newBlock.permutation.getState('pb_red:tp_in'));
                    return
                }
                if (newBlock.permutation.matches("pb_red:wireless_redstone")) {
                    wirelessRedstoneComponent.removeDynamicProperties(block);
                    wirelessRedstoneComponent.updateWirelessRedstoneData(newBlock, colorChannel, newBlock.permutation.getState('pb_red:is_transmitter'), newBlock.permutation.getState('pb_red:is_transmitter') && newBlock.permutation.getState('pb_red:powered'));
                    return
                }
                if (newBlock.permutation.matches("pb_red:remote_controlled_redstone")) {
                    remoteControlledRedstoneComponent.removeDynamicProperties(block);
                    remoteControlledRedstoneComponent.updateWirelessRedstoneData(newBlock, newBlock.permutation.getState('pb_red:color_channel'), true);
                    return
                }

            }

        }, 3)

    })
})
function calculateOffset(pos1, pos2) {
    const offsetX = pos2.x - pos1.x;
    const offsetY = pos2.y - pos1.y;
    const offsetZ = pos2.z - pos1.z;

    return { offsetX, offsetY, offsetZ };
}
function applyOffset(pos, offset, isExpanding) {
    return {
        x: pos.x + (offset.offsetX != 0 ? (offset.offsetX > 0 ? (isExpanding ? 1 : -1) : (isExpanding ? -1 : 1)) : 0),
        y: pos.y + (offset.offsetY != 0 ? (offset.offsetY > 0 ? (isExpanding ? 1 : -1) : (isExpanding ? -1 : 1)) : 0),
        z: pos.z + (offset.offsetZ != 0 ? (offset.offsetZ > 0 ? (isExpanding ? 1 : -1) : (isExpanding ? -1 : 1)) : 0)
    };
}


world.beforeEvents.playerBreakBlock.subscribe((e) => {
    const block = e.block;
    const dimension = e.dimension;
    const Blocks_To_Check = [
        "pb_red:entity_teleporter",
        "pb_red:item_teleporter",
        "pb_red:xp_tank",
        "pb_red:entity_sensor",
        "pb_red:redstone_counter",
        "pb_red:custom_repeater",
        "pb_red:wireless_redstone",
        "pb_red:remote_controlled_redstone",
        "pb_red:drill",
        "pb_red:saw",
        "pb_red:elevator_rail",
        "pb_red:elevator_control_rail",
        //update
        "pb_red:fertilizer",

    ]

    if (!Blocks_To_Check.some(blockId => block.permutation.matches(blockId))) return

    if (block.permutation.matches("pb_red:entity_teleporter")) { // && block.permutation.getState('pb_red:powered') === true
        const colorChannel = block.permutation.getState('pb_red:color_channel');
        if (colorChannel !== undefined) {
            entityTeleporterComponent.removeEntityTeleporterData(block, colorChannel);

            const blockChannelKey = new ChannelKey(block, null);
            blockChannelKey.removeBlockKey()
        }
    }

    if (block.permutation.matches("pb_red:item_teleporter")) {
        const colorChannel = block.permutation.getState('pb_red:color_channel');
        // console.warn(colorChannel)
        if (colorChannel !== undefined) {
            itemTeleporterComponent.removeDynamicProperties(block);

            const blockChannelKey = new ChannelKey(block, null);
            blockChannelKey.removeBlockKey()
        }
    }

    if (block.permutation.matches("pb_red:xp_tank")) {
        xpTankComponent.removeDynamicProperties(block);
    }

    if (block.permutation.matches("pb_red:entity_sensor")) {
        entitySensorComponent.removeDynamicProperties(block);
    }

    if (block.permutation.matches("pb_red:redstone_counter")) {
        redstoneCounterComponent.removeDynamicProperties(block);
    }

    if (block.permutation.matches("pb_red:drill")) {
        if (e.player.getGameMode() == "creative") return
        const efficiency = block.permutation.getState('pb_red:efficiency')
        const fortune = block.permutation.getState('pb_red:fortune')
        const silkTouch = block.permutation.getState('pb_red:silk_touch')

        system.runTimeout(() => {
            if (efficiency > 0)
                dimension.runCommand(`loot spawn ${block.location.x} ${block.location.y} ${block.location.z} loot "pb/redstone/upgrade/efficiency_${efficiency}"`)
            if (fortune > 0)
                dimension.runCommand(`loot spawn ${block.location.x} ${block.location.y} ${block.location.z} loot "pb/redstone/upgrade/fortune_${fortune}"`)
            if (silkTouch > 0)
                dimension.runCommand(`loot spawn ${block.location.x} ${block.location.y} ${block.location.z} loot "pb/redstone/upgrade/silk_touch"`)
        })
    }

    if (block.permutation.matches("pb_red:saw")) {
        if (e.player.getGameMode() == "creative") return
        const silkTouch = block.permutation.getState('pb_red:silk_touch')

        system.runTimeout(() => {
            if (silkTouch)
                dimension.runCommand(`loot spawn ${block.location.x} ${block.location.y} ${block.location.z} loot "pb/redstone/upgrade/silk_touch"`)
        })
    }

    if (block.permutation.matches("pb_red:custom_repeater")) {
        customRepeaterComponent.removeDynamicProperties(block);
    }

    if (block.permutation.matches("pb_red:wireless_redstone")) {
        const colorChannel = block.permutation.getState('pb_red:color_channel');
        // console.warn(colorChannel)
        if (colorChannel !== undefined) {
            wirelessRedstoneComponent.removeDynamicProperties(block)

            const blockChannelKey = new ChannelKey(block, null);
            blockChannelKey.removeBlockKey()
        }
    }

    if (block.permutation.matches("pb_red:remote_controlled_redstone")) {
        const colorChannel = block.permutation.getState('pb_red:color_channel');
        // console.warn(colorChannel)
        if (colorChannel !== undefined) {
            remoteControlledRedstoneComponent.removeDynamicProperties(block)

            const blockChannelKey = new ChannelKey(block, null);
            blockChannelKey.removeBlockKey()
        }
    }

    //update
    if (block.permutation.matches("pb_red:fertilizer")) {
        if (e.player.getGameMode() == "creative") return
        const level = block.permutation.getState('pb_red:level')
        if (level == 1) return

        system.runTimeout(() => {
            dimension.spawnItem(new ItemStack("minecraft:bone_block", level == 2 ? 16 : 48), block.location);
        })
    }
    //


    if (block.permutation.matches("pb_red:elevator_rail") || block.permutation.matches("pb_red:elevator_control_rail")) {
        const direction = block.permutation.getState('minecraft:cardinal_direction');
        const elevatorBlock = getBlockInDirection(block, direction);
        const elevatorBlockCenter = { x: elevatorBlock.location.x + 0.5, y: elevatorBlock.location.y + 0.5, z: elevatorBlock.location.z + 0.5 }
        const entity = block.dimension.getEntities({ location: elevatorBlockCenter, maxDistance: 1, type: "pb_red:elevator" })[0]
        if (entity && entity.location.x == elevatorBlockCenter.x && entity.location.z == elevatorBlockCenter.z && (Math.floor(entity.location.y) + 0.5) == elevatorBlockCenter.y) {
            const isRoom = entity.getProperty("pb_red:is_room")
            system.runTimeout(() => {
                const inv = entity.getComponent('inventory').container;
                const location = { x: entity.location.x, y: entity.location.y + 1, z: entity.location.z };
                for (let i = 0; i < inv.size; i++) {
                    const item = inv.getItem(i);
                    if (item) entity.dimension.spawnItem(item, location);
                }
                entity.remove()
                system.runTimeout(() => {
                    block.dimension.runCommand(`fill ${elevatorBlockCenter.x - 1} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z - 1} ${elevatorBlockCenter.x + 1} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z + 1} minecraft:air replace`);
                })
                if (isRoom)
                    dimension.spawnItem(new ItemStack("pb_red:spawn_elevator_cabin", 1), elevatorBlockCenter);
                else
                    dimension.spawnItem(new ItemStack("pb_red:spawn_elevator", 1), elevatorBlockCenter);
                dimension.runCommand(`playsound random.break @a ${block.location.x} ${block.location.y} ${block.location.z}`)
            }, 10)
        }
    }
});

function getBlockInDirection(block, direction) {
    switch (direction) {
        case 'north':
            return block.south(2);
        case 'south':
            return block.north(2);
        case 'east':
            return block.west(2);
        case 'west':
            return block.east(2);
    }
}




world.afterEvents.playerSpawn.subscribe((event) => {
    const { initialSpawn, player } = event
    if (!initialSpawn) return;

    system.runTimeout(() => {
        for (const entity of player.dimension.getEntities()) {
            const breedCooldownTag = entity.getTags().find(tag => tag.startsWith('breed_cooldown:'));
            const milkCooldownTag = entity.getTags().find(tag => tag.startsWith('pb_red_milk_cooldown:'));
            if (breedCooldownTag) {
                entity.removeTag(breedCooldownTag);
            }
            if (milkCooldownTag) {
                entity.removeTag(milkCooldownTag);
            }

        }
    }, 4 * 20)

})



let isRaining = false
world.afterEvents.weatherChange.subscribe((event) => {
    const { dimension, newWeather, previousWeather } = event

    if ((newWeather == "Rain" || newWeather == "Thunder")) {
        isRaining = true
        // console.warn("RAIn")
    }
    else {
        isRaining = false
        // console.warn("CLEAR")
    }
})





system.afterEvents.scriptEventReceive.subscribe((data) => {
    const { id, sourceEntity } = data;

    if (id === 'pb_red:remove_drill_entity') {
        if (sourceEntity)
            sourceEntity.remove()
    }

    if (id === 'pb_red:remove_elevator_platform') {
        if (sourceEntity) {
            sourceEntity.addTag("pb_red:elevator_is_beeing_destroyed")
            const entity = sourceEntity
            const dimension = sourceEntity.dimension
            const elevatorBlock = entity.dimension.getBlock(entity.location);
            const elevatorBlockCenter = { x: elevatorBlock.location.x + 0.5, y: elevatorBlock.location.y + 0.5, z: elevatorBlock.location.z + 0.5 }
            const inv = entity.getComponent('inventory').container;
            const isRoom = sourceEntity.getProperty("pb_red:is_room")
            const location = { x: entity.location.x, y: entity.location.y + 1, z: entity.location.z };
            for (let i = 0; i < inv.size; i++) {
                const item = inv.getItem(i);
                if (item) entity.dimension.spawnItem(item, location);
            }
            entity.remove()
            system.runTimeout(() => {
                dimension.runCommand(`fill ${elevatorBlockCenter.x - 1} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z - 1} ${elevatorBlockCenter.x + 1} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z + 1} minecraft:air replace pb_red:elevator_floor`);
            })
            if (isRoom)
                dimension.spawnItem(new ItemStack("pb_red:spawn_elevator_cabin", 1), elevatorBlockCenter);
            else
                dimension.spawnItem(new ItemStack("pb_red:spawn_elevator", 1), elevatorBlockCenter);
            dimension.runCommand(`playsound random.break @a ${elevatorBlockCenter.x} ${elevatorBlockCenter.y} ${elevatorBlockCenter.z}`)
        }

    }
})


world.afterEvents.itemUse.subscribe((e) => {
    const { itemStack, source: player } = e

    if (itemStack.typeId == "pb_red:redstone_wrench") {

        const ray = getRaycastedBlockInfo(player);
        if (!ray) return;
        const block = ray.block

        if (![
            "minecraft:piston",
            "minecraft:sticky_piston",
            "minecraft:observer",
            "pb_red:block_dispenser",
            "minecraft:redstone_wire",
        ].includes(block.typeId)) return

        if (block.typeId == "minecraft:redstone_wire") {
            player.sendMessage(`redstone power: §c${block.permutation.getState("redstone_signal")}`)
            block.dimension.runCommand(`playsound random.click @a ${block.location.x} ${block.location.y} ${block.location.z}`)
        }

        const AllStates = [
            { state: "minecraft:cardinal_direction", values: ["north", "east", "south", "west"] },
            { state: "minecraft:facing_direction", values: ["north", "east", "south", "west", "up", "down"] },
            { state: "weirdo_direction", values: [0, 2, 1, 3] },
            { state: "direction", values: [0, 2, 1, 3] },
            { state: "facing_direction", values: [0, 1, 2, 3, 4, 5] },
            { state: "rail_direction", values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] },
            { state: "ground_sign_direction", values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15] },
            { state: "pillar_axis", values: ["x", "y", "z"] },
            { state: "lever_direction", values: ["down_east_west", "down_north_south", "east", "north", "south", "up_east_west", "up_north_south", "west"] },
        ]

        AllStates.some((stateObj) => {
            const currentState = block.permutation.getState(stateObj.state);

            if (currentState !== undefined && currentState !== null) {
                const stateValues = stateObj.values;
                const currentStateIndex = stateValues.indexOf(currentState);
                const nextState = currentStateIndex >= stateValues.length - 1 ? stateValues[0] : stateValues[currentStateIndex + 1];

                block.setPermutation(block.permutation.withState(stateObj.state, nextState));
                block.dimension.runCommand(`playsound vr.stutterturn @a ${block.location.x} ${block.location.y} ${block.location.z}`)

                return true;
            }
            return false;
        });

    }

})

function getRaycastedBlockInfo(player) {
    return player.getBlockFromViewDirection({
        maxDistance: 10,
        includeLiquidBlocks: false,
        includePassableBlocks: true
    });
}



world.beforeEvents.playerInteractWithEntity.subscribe((e) => {
    const { target, player, itemStack } = e

    const bannedList = [
        "pb_red:drill_entity",
        "pb_red:xp_tank_updater_dummy",
        "pb_red:rail_placer_seat",
    ]

    let selectedSlot = player.selectedSlotIndex;
    let handItem = player.getComponent("inventory").container.getItem(selectedSlot);

    if (handItem)
        if (handItem.typeId == "pb_red:redstone_wrench" || handItem.typeId.includes('enchanted_book')) return

    if (target.typeId.startsWith("pb_red:") && !bannedList.includes(target.typeId)) {
        if (target.typeId == "pb_red:elevator" && !player.isSneaking) return

        if (target.typeId == "pb_red:transplanter" || target.typeId == "pb_red:harvester") {
            system.runTimeout(() => {
                player.playSound("random.enderchestopen", { volume: 0.5 })
            })
            return
        }

        if (target.typeId == "pb_red:rail_placer_furnace") {
            system.runTimeout(() => {
                player.playSound("block.furnace.lit", { volume: 0.5 })
            })
            return
        }

        system.runTimeout(() => {

            player.playSound("random.chestopen", { volume: 0.5 })
        })

    }

})