
export class BlockDispenserComponent {
    constructor() {
        this.onTick = this.onTick.bind(this);
        this.onPlayerInteract = this.onPlayerInteract.bind(this);
        this.REDSTONE_POWER_BLOCKS = [
            { id: "minecraft:redstone_wire", state: "redstone_signal" },
            { id: "minecraft:powered_comparator", state: "minecraft:cardinal_direction" },
            { id: "minecraft:powered_repeater", state: "minecraft:cardinal_direction" },
            { id: "minecraft:redstone_torch", state: "torch_facing_direction" },
            { id: "minecraft:observer", state: "minecraft:facing_direction" },
            { id: "minecraft:lever", state: "open_bit" },
            { id: "minecraft:lever", state: "open_bit" },
            { id: "_button", state: "button_pressed_bit" },
            { id: "_pressure_plate", state: "redstone_signal" },
            { id: "minecraft:redstone_block", state: null },
        ];
    }

    onPlayerInteract(e) {
        const block = e.block;

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

        if (handItem) {
            if (handItem.typeId == "pb_red:redstone_wrench") {
                const AllStates = [
                    { state: "minecraft:cardinal_direction", values: ["north", "east", "south", "west"] },
                    { state: "minecraft:facing_direction", values: ["north", "east", "south", "west", "up", "down"] }
                ]

                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}`)
                    }
                });
            }
        }
    }

    getOppositeDirection(direction) {
        switch (direction) {
            case 'north':
                return 'south';
            case 'south':
                return 'north';
            case 'east':
                return 'west';
            case 'west':
                return 'east';
            case 'up':
                return 'down';
            case 'down':
                return 'up';
        }
    }

    getFrontBlock(direction, block) {
        switch (direction) {
            case 'north':
                return block.north();
            case 'south':
                return block.south();
            case 'east':
                return block.east();
            case 'west':
                return block.west();
            case 'up':
                return block.above();
            case 'down':
                return block.below();
        }
    }

    onTick(e) {
        const block = e.block;
        let direction = this.getOppositeDirection(block.permutation.getState('minecraft:facing_direction'));
        const chestAbove = block.above();
        const chestInBack = this.getFrontBlock(this.getOppositeDirection(direction), block);

        if (!chestAbove || !block || !chestInBack) return;

        let frontBlock = this.getFrontBlock(direction, block);

        if (frontBlock?.permutation.matches("minecraft:air") || !frontBlock) {

            if (!this.hasRedstonePower(block, direction)) return;

            let itemToDispense = this.getItemFromInventory(chestInBack);
            if (!itemToDispense) itemToDispense = this.getItemFromInventory(chestAbove);

            if (itemToDispense) {
                if (frontBlock.permutation.matches("minecraft:air") || !frontBlock) {
                    try {
                        frontBlock.setType(itemToDispense.item.typeId);
                        block.dimension.runCommand(`playsound place.calcite @a ${block.location.x} ${block.location.y} ${block.location.z}`)
                    } catch {
                        //  console.warn("Not a block");
                        itemToDispense.item.amount = 1
                        block.dimension.spawnItem(itemToDispense.item, { x: frontBlock.location.x + 0.5, y: frontBlock.location.y - 0.1, z: frontBlock.location.z + 0.5 })
                        block.dimension.runCommand(`playsound random.pop @a ${block.location.x} ${block.location.y} ${block.location.z} 0.5`)
                    }
                }
            }
        }
    }

    hasRedstonePower(block, direction) {
        const north = block.north();
        const east = block.east();
        const south = block.south();
        const west = block.west();
        const above = block.above();
        const below = block.below();

        const adjacentBlocks = [north, east, south, west, above, below];
        const directionList = ["north", "east", "south", "west", "up", "down"];

        return adjacentBlocks.some((adjacentBlock, index) => {
            if (!adjacentBlock) return false;

            const redstoneBlock = this.REDSTONE_POWER_BLOCKS.find(({ id }) => adjacentBlock.typeId.includes(id));
            if (!redstoneBlock) return false;

            const { id, state } = redstoneBlock;
            if (id === "minecraft:redstone_block") return true;

            if (id === "minecraft:redstone_wire") {
                let redstonePowerState = adjacentBlock.permutation.getState(state);
                return redstonePowerState > 0;
            }

            if (id === "minecraft:powered_comparator" || id === "minecraft:powered_repeater") {
                return adjacentBlock.permutation.getState(state) === directionList[index];
            }

            if (id === "minecraft:redstone_torch") {
                return adjacentBlock.permutation.getState(state) !== this.getOppositeDirection(directionList[index]) && index !== 4;
            }

            if (id === "minecraft:observer") {
                return adjacentBlock.permutation.getState(state) == directionList[index] && adjacentBlock.permutation.getState("powered_bit") == true;
            }

            if (id === "minecraft:lever") {
                return adjacentBlock.permutation.getState(state) == true;
            }

            if (id === "_button") {
                return adjacentBlock.permutation.getState(state) == true;
            }

            if (id === "_pressure_plate") {
                return adjacentBlock.permutation.getState(state) > 0;
            }

            return false;
        });
    }

    getItemFromInventory(containerBlock, containerType, slotsCount) {
        if (!this.isValidContainer(containerBlock)) return null;

        let inventory = containerBlock?.getComponent("minecraft:inventory")?.container;
        if (!inventory) return;
        for (let slot = 0; slot < inventory.size; slot++) {
            let item = inventory.getItem(slot);
            if (item) {
                let itemAmount = item.amount;

                if (itemAmount <= 1) {
                    inventory.setItem(slot, null);
                } else {
                    item.amount = itemAmount - 1
                    inventory.setItem(slot, item);
                }

                return { item: item, slot: slot };
            }
        }
        return null;
    }

    isValidContainer(block) {
        if (!block) return;
        const validContainers = [
            "minecraft:chest",
            "minecraft:hopper",
            "minecraft:barrel",
            "minecraft:dropper",
            "minecraft:dispenser",
            "minecraft:trapped_chest",
            //shulker box
            "minecraft:undyed_shulker_box",
            "minecraft:black_shulker_box",
            "minecraft:blue_shulker_box",
            "minecraft:brown_shulker_box",
            "minecraft:cyan_shulker_box",
            "minecraft:gray_shulker_box",
            "minecraft:green_shulker_box",
            "minecraft:light_blue_shulker_box",
            "minecraft:light_gray_shulker_box",
            "minecraft:lime_shulker_box",
            "minecraft:magenta_shulker_box",
            "minecraft:orange_shulker_box",
            "minecraft:pink_shulker_box",
            "minecraft:purple_shulker_box",
            "minecraft:red_shulker_box",
            "minecraft:white_shulker_box",
            "minecraft:yellow_shulker_box",


        ];
        return validContainers.includes(block.typeId);
    }
}


