import { world, BlockPermutation } from "@minecraft/server"
import { ModalFormData, ActionFormData } from "@minecraft/server-ui"
import { showArea } from './particle_area_marker.js'





export class EntitySensorComponent {
    constructor() {
        this.onTick = this.onTick.bind(this);
        this.onPlayerInteract = this.onPlayerInteract.bind(this);
        this.lastState = false
        this.ALL_ID_LIST = [
            "No Filter | Every Type",
            "player",
            "creeper",
            "zombie",
            "skeleton",
            "spider",
            "enderman",
            "villager",
            "witch",
            "iron_golem",
            "wolf",
            "ocelot",
            "cow",
            "pig",
            "sheep",
            "chicken",
            "horse",
            "cat",
            "bee",
            "dolphin",
            "panda",
            "fox",
            "polar_bear",
            "phantom",
            "slime",
            "magma_cube",
            "ghast",
            "blaze",
            "wither_skeleton",
            "piglin",
            "hoglin",
            "stray",
            "husk",
            "drowned",
            "phantom",
            "ravager",
            "pillager",
            "vindicator",
            "evocation_illager",
            "vex",
            "shulker",
            "guardian",
            "elder_guardian",
            "ender_dragon",
            "wither",
            "bat",
            "cave_spider",
            "cod",
            "donkey",
            "fox",
            "goat",
            "glow_squid",
            "llama",
            "mooshroom",
            "mule",
            "parrot",
            "pufferfish",
            "rabbit",
            "salmon",
            "silverfish",
            "skeleton_horse",
            "snow_golem",
            "squid",
            "strider",
            "tropicalfish",
            "turtle",
            "wandering_trader",
            "zombie_horse",
            "zombie_villager",
            "zoglin",


            "armor_stand",
            "arrow",
            "boat",
            "minecart",
            "chest_minecart",
            "hopper_minecart",
            "furnace_minecart",
            "command_block_minecart",
            "end_crystal",
            "falling_block",
            "fireball",
            "fireworks_rocket",
            "fishing_hook",
            "item",
            "leash_knot",
            "lightning_bolt",
            "snowball",
            "splash_potion",
            "tnt",
            "tnt_minecart",
            "trident",
            "xp_bottle",
            "xp_orb",
            "ender_pearl",
            "shulker_bullet",
            "npc"
        ];
        this.DYNAMIC_PROPERTY_NAME = "pb_red:entity_sensor_data";
        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" }
        ];

    }

    getFrontandBack(direction, block) {
        let frontBlock, backBlock, leftBlock, rightBlock;
        switch (direction) {
            case 'north':
                frontBlock = block.north();
                backBlock = block.south();
                rightBlock = block.east();
                leftBlock = block.west();
                break;
            case 'south':
                frontBlock = block.south();
                backBlock = block.north();
                rightBlock = block.west();
                leftBlock = block.east();
                break;
            case 'east':
                frontBlock = block.east();
                backBlock = block.west();
                rightBlock = block.south();
                leftBlock = block.north();
                break;
            case 'west':
                frontBlock = block.west();
                backBlock = block.east();
                rightBlock = block.north();
                leftBlock = block.south();
                break;
        }
        return { frontBlock, backBlock, leftBlock, rightBlock };
    }
    getCounterData() {
        return JSON.parse(world.getDynamicProperty(this.DYNAMIC_PROPERTY_NAME) || "[]");
    }

    setCounterData(data) {
        world.setDynamicProperty(this.DYNAMIC_PROPERTY_NAME, JSON.stringify(data));
    }

    updateCounterData(block) {
        const locationStr = `${block.location.x},${block.location.y},${block.location.z}`;
        let data = this.getCounterData();
        let counter = data.find(counter => counter.loc === locationStr);

        if (!counter) {
            counter = { loc: locationStr, id: null, name: null, radius: 1 };
            data.push(counter);
        }

        this.setCounterData(data);
    }

    onPlayerInteract(e) {
        const block = e.block;
        const pos = block.location
        const player = e.player;

        let selectedSlot = player.selectedSlotIndex;
        let handItem = player.getComponent("inventory").container.getItem(selectedSlot);
        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}`)
                }
            });
            return;
        }


        this.updateCounterData(block)

        const locationStr = `${block.location.x},${block.location.y},${block.location.z}`;
        let data = this.getCounterData();
        let counter = data.find(counter => counter.loc === locationStr);
        block.dimension.runCommand(`playsound random.click @a ${block.location.x} ${block.location.y} ${block.location.z}`)




        const EntitySensorMainGUI = new ActionFormData()
        EntitySensorMainGUI.title("Entity Sensor")
        EntitySensorMainGUI.body("select the filter: ")
        EntitySensorMainGUI.button("Filter Type")
        EntitySensorMainGUI.button("Filter Name")
        EntitySensorMainGUI.show(player).then((selec) => {
            if (selec.canceled) {
                return;
            }
            switch (selec.selection) {
                case 0:

                    const EntitySensorTypeGUI = new ModalFormData()
                    EntitySensorTypeGUI.title("Entity Sensor")
                    EntitySensorTypeGUI.dropdown("Type Filter:", this.ALL_ID_LIST, counter.id ? this.ALL_ID_LIST.indexOf(counter.id.replace("minecraft:", "")) : 0)
                    EntitySensorTypeGUI.slider("Detection Radius", 1, 25, 1, counter.radius)
                    EntitySensorTypeGUI.show(player).then((selec) => {
                        if (selec.canceled) {
                            return;
                        }
                        if (selec.formValues[0] !== 0)
                            counter.id = `minecraft:${this.ALL_ID_LIST[selec.formValues[0]]}`;
                        else
                            counter.id = null
                        counter.radius = selec.formValues[1]
                        this.setCounterData(data);
                        showArea({ x: pos.x + 0.5, y: pos.y + 0.5, z: pos.z + 0.5 }, block.dimension, 5, counter.radius)
                    });
                    break;
                case 1:

                    const EntitySensorNameGUI = new ModalFormData()
                    EntitySensorNameGUI.title("Entity Sensor")
                    EntitySensorNameGUI.textField("Name Filter:", "Name of the entity", counter.name ? counter.name : "")
                    EntitySensorNameGUI.slider("Detection Radius", 1, 25, 1, counter.radius)
                    EntitySensorNameGUI.show(player).then((selec) => {
                        if (selec.canceled) {
                            return;
                        }
                        if (selec.formValues[0])
                            counter.name = selec.formValues[0];
                        else
                            counter.name = null
                        counter.radius = selec.formValues[1]
                        this.setCounterData(data);
                        showArea({ x: pos.x + 0.5, y: pos.y + 0.5, z: pos.z + 0.5 }, block.dimension, 5, counter.radius)
                    });

                    break;
            }
        })
    }

    removeDynamicProperties(block) {
        const locationStr = `${block.location.x},${block.location.y},${block.location.z}`;
        let data = this.getCounterData();
        data = data.filter(counter => counter.loc !== locationStr);
        this.setCounterData(data);
    }

    onTick(e) {
        const { block } = e;
        let direction = block.permutation.getState('minecraft:cardinal_direction');
        const { frontBlock, backBlock, leftBlock, rightBlock } = this.getFrontandBack(direction, block);
        const directionList = ["north", "east", "south", "west"];
        this.updateCounterData(block)
        const locationStr = `${block.location.x},${block.location.y},${block.location.z}`;
        let data = this.getCounterData();
        let counter = data.find(counter => counter.loc === locationStr);
        if (!counter) return
        const filters = { location: block.location, maxDistance: counter.radius, type: counter.id, name: counter.name }
        const entity = block.dimension.getEntities(filters)[0]
        this.lastState = block.permutation.getState('pb_red:powered')
        if (entity) {
            if (!block.permutation.matches("pb_red:entity_sensor")) return
            block.setPermutation(block.permutation.withState('pb_red:powered', true));
            if (frontBlock.permutation.matches("minecraft:unpowered_repeater") && frontBlock.permutation.getState("minecraft:cardinal_direction") === directionList[(directionList.indexOf(direction) - 2 + directionList.length) % directionList.length]) {
                frontBlock.setPermutation(BlockPermutation.resolve("minecraft:powered_repeater", { 'minecraft:cardinal_direction': directionList[(directionList.indexOf(direction) - 2 + directionList.length) % directionList.length] }));
            }
            if (this.lastState == false)
                block.dimension.runCommand(`playsound beacon.activate @a ${block.location.x} ${block.location.y} ${block.location.z}`)
        } else {
            if (!block.permutation.matches("pb_red:entity_sensor")) return
            block.setPermutation(block.permutation.withState('pb_red:powered', false));
            if (this.lastState == true)
                block.dimension.runCommand(`playsound beacon.deactivate @a ${block.location.x} ${block.location.y} ${block.location.z}`)
        }
    }

}
