import { world, BlockPermutation, system } from "@minecraft/server"
import { Vector } from './vector.js';
import { ChannelKey } from './channel_key.js';


export class WirelessRedstoneComponent {
    constructor() {
        this.onTick = this.onTick.bind(this);
        this.onPlayerInteract = this.onPlayerInteract.bind(this);


        this.COLOR_DYE_LIST = [
            "minecraft:black_dye",
            "minecraft:blue_dye",
            "minecraft:brown_dye",
            "minecraft:cyan_dye",
            "minecraft:gray_dye",
            "minecraft:green_dye",
            "minecraft:light_blue_dye",
            "minecraft:light_gray_dye",
            "minecraft:lime_dye",
            "minecraft:magenta_dye",
            "minecraft:orange_dye",
            "minecraft:pink_dye",
            "minecraft:purple_dye",
            "minecraft:red_dye",
            "minecraft:white_dye",
            "minecraft:yellow_dye"
        ];
        this.REDSTONE_POWER_BLOCKS = [
            { id: "minecraft:redstone_wire", state: "redstone_signal" },
            { id: "minecraft:powered_repeater", state: "minecraft:cardinal_direction" },
            { id: "minecraft:unpowered_repeater", state: "minecraft:cardinal_direction" }
        ];
    }

    getWirelessRedstoneData() {
        return JSON.parse(world.getDynamicProperty("pb_red:wireless_redstone_data") || "{}");
    }

    setWirelessRedstoneData(data) {
        world.setDynamicProperty("pb_red:wireless_redstone_data", JSON.stringify(data));
    }

    updateWirelessRedstoneData(block, colorChannel, isTransmitter, hasPower) {
        const locationStr = `${block.location.x},${block.location.y},${block.location.z}`;
        let data = this.getWirelessRedstoneData();
        const key = `${colorChannel}:${isTransmitter ? 'transmitter' : 'receiver'}`;

        if (!data[key]) {
            data[key] = [];
        }

        if (isTransmitter) {
            if (hasPower) {
                if (!data[key].includes(locationStr)) {
                    data[key].push(locationStr);
                }
            } else {
                data[key] = data[key].filter(loc => loc !== locationStr);
            }
        } else {
            data[key] = data[key].filter(loc => loc !== locationStr);
            if (!data[key].includes(locationStr)) {
                data[key].push(locationStr);
            }
        }

        this.setWirelessRedstoneData(data);
    }
    onPlayerInteract(e) {
        const block = e.block;
        const player = e.player;
        let selectedSlot = player.selectedSlotIndex;
        let handItem = player.getComponent("inventory").container.getItem(selectedSlot);

        if (this.COLOR_DYE_LIST.includes(handItem?.typeId)) {
            let colorChannel = this.COLOR_DYE_LIST.indexOf(handItem.typeId);
            block.setPermutation(block.permutation.withState('pb_red:powered', false));
            block.setPermutation(block.permutation.withState('pb_red:color_channel', colorChannel));
            this.removeDynamicProperties(block)
            player.runCommand(`clear @s ${handItem.typeId} 0 1`);
            block.dimension.runCommand(`playsound sign.ink_sac.use @a ${block.location.x} ${block.location.y} ${block.location.z}`)
            // console.warn("channel set to : " + colorChannel);
        } else {

            if (handItem?.typeId == "pb_red:redstone_wrench") {

                block.dimension.runCommand(`playsound random.click @a ${block.location.x} ${block.location.y} ${block.location.z}`)

                const channelKey = new ChannelKey(block, null);
                channelKey.openUI(player)

                return;

            } else {
                block.dimension.runCommand(`playsound vr.stutterturn @a ${block.location.x} ${block.location.y} ${block.location.z}`)
                if (block.permutation.getState('pb_red:is_transmitter') === true) {
                    this.updateWirelessRedstoneData(block, block.permutation.getState('pb_red:color_channel'), true, false); // Clear transmitter state
                    block.setPermutation(block.permutation.withState('pb_red:powered', false));
                    block.setPermutation(block.permutation.withState('pb_red:is_transmitter', false));
                } else {
                    block.setPermutation(block.permutation.withState('pb_red:powered', false));
                    block.setPermutation(block.permutation.withState('pb_red:is_transmitter', true));
                }
            }
        }

        this.updateWirelessRedstoneData(block, block.permutation.getState('pb_red:color_channel'), block.permutation.getState('pb_red:is_transmitter'), block.permutation.getState('pb_red:is_transmitter') && block.permutation.getState('pb_red:powered'));
    }

    removeDynamicProperties(block) {
        const locationStr = `${block.location.x},${block.location.y},${block.location.z}`;
        let data = this.getWirelessRedstoneData();

        for (let key in data) {
            data[key] = data[key].filter(loc => loc !== locationStr);
        }

        this.setWirelessRedstoneData(data);
    }

    getFrontandBack(direction, block) {
        let backBlock;
        switch (direction) {
            case 'north':
                backBlock = block.south();
                break;
            case 'south':
                backBlock = block.north();
                break;
            case 'east':
                backBlock = block.west();
                break;
            case 'west':
                backBlock = block.east();
                break;
        }
        return { backBlock };
    }

    onTick(e) {
        const block = e.block;
        const colorChannel = block.permutation.getState('pb_red:color_channel');
        const isTransmitter = block.permutation.getState('pb_red:is_transmitter');

        let direction = block.permutation.getState('minecraft:cardinal_direction');
        const { backBlock } = this.getFrontandBack(direction, block);
        const directionList = ["north", "east", "south", "west"];

        if (isTransmitter) {
            if (!backBlock) return
            let redstonePower = 0;
            const redstoneBlock = this.REDSTONE_POWER_BLOCKS.find(({ id }) => backBlock.permutation.matches(id));
            if (!redstoneBlock) {
                this.updateWirelessRedstoneData(block, colorChannel, true, false);
                block.setPermutation(block.permutation.withState('pb_red:powered', false));
                return
            }
            const { id, state } = redstoneBlock;
            if (id === "minecraft:redstone_wire") {
                redstonePower = backBlock.permutation.getState(state);
            } else if (id === "minecraft:powered_repeater") {
                if (backBlock.permutation.getState(state) === directionList[(directionList.indexOf(direction) - 2 + directionList.length) % directionList.length]) {
                    redstonePower = 15;
                }
            }
            block.setPermutation(block.permutation.withState('pb_red:powered', redstonePower > 0));
            this.updateWirelessRedstoneData(block, colorChannel, true, redstonePower > 0);
        } else {
            let data = this.getWirelessRedstoneData();
            const key = `${colorChannel}:transmitter`;

            if (!data[key]) return
            // Verify channel keys for all potential transmitter
            const validTransmitters = data[key].filter(targetLocationStr => {
                const [targetX, targetY, targetZ] = targetLocationStr.split(',');
                const targetXNum = parseFloat(targetX);
                const targetYNum = parseFloat(targetY);
                const targetZNum = parseFloat(targetZ);
                const targetLoc = new Vector(targetXNum, targetYNum, targetZNum);

                const targetBlock = ChannelKey.constructBlock(targetLoc, "minecraft:overworld");
                const channelKey = new ChannelKey(block, targetBlock);

                return channelKey.channelConfirmed();
            });
            //  console.warn(validTransmitters.length)

            if (validTransmitters.length > 0) {
                block.setPermutation(block.permutation.withState('pb_red:powered', true));
                if (backBlock.permutation.matches("minecraft:unpowered_repeater") && backBlock.permutation.getState("minecraft:cardinal_direction") === direction) {
                    backBlock.setPermutation(BlockPermutation.resolve("minecraft:powered_repeater", { 'minecraft:cardinal_direction': direction }));
                }
            } else {
                if (block.permutation.matches("pb_red:wireless_redstone"))
                    block.setPermutation(block.permutation.withState('pb_red:powered', false));
            }
        }
    }
}
