import { BlockPermutation, ItemStack, world } from "@minecraft/server";
import { dropItemCenterOfBlock } from "../../utils/item";
import { isPlayerHoldingItem } from "../../utils/inventory";
import { randInt } from "../../utils/number";

const scoreboardName = "settings";
const settingPlayers = {
    blockParticles: "blockParticles",
    ambientFog: "ambientFog",
    islandFog: "islandFog",
    islandClouds: "islandClouds"
};

world.beforeEvents.worldInitialize.subscribe(({ blockComponentRegistry }) => {

    function getSetting(setting) {
        try {
            return world.scoreboard.getObjective(scoreboardName).getScore(setting) === 1;
        } catch {
            return false;
        }
    }

    blockComponentRegistry.registerCustomComponent("gs_ce:plant_shearable", {
        onPlayerDestroy: ({ player, block, dimension, destroyedBlockPermutation }) => {
            if (isPlayerHoldingItem(player, "minecraft:shears")) {
                dropItemCenterOfBlock(dimension, block.location, new ItemStack(destroyedBlockPermutation.type.id.replace("_top", "").replace("_bottom", ""), 1));
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:double_plant_placer", {
        onPlace: ({ block }) => {
            const blockAbove = block.above(1);
            if (blockAbove.typeId !== "minecraft:air") {
                return;
            }
            block.setType(block.typeId + "_bottom");
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:double_plant_bottom", {
        onPlace: ({ block, dimension }) => {
            try {
            if (block.above(1).typeId !== "minecraft:air") {
                const { x, y, z } = block.location;
                dimension.runCommandAsync(`setblock ${x} ${y} ${z} minecraft:air destroy`);
                dropItemCenterOfBlock(dimension, block.location, new ItemStack(block.typeId.replace("_bottom", ""), 1));
                return;
            }
            block.above(1).setType(block.typeId.replace("_bottom", "_top"));
            } catch (ignored) {}
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:double_plant_top", {
        onPlayerDestroy: ({ block, dimension, destroyedBlockPermutation }) => {
            const blockBelow = block.below(1);
            if (destroyedBlockPermutation.type.id.replace("_top", "") === blockBelow.typeId.replace("_bottom", "")) {
                const { x, y, z } = blockBelow.location;
                dimension.runCommandAsync(`setblock ${x} ${y} ${z} minecraft:air destroy`);
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_berry_bush", {
        onPlayerInteract: ({ block, dimension }) => {
            const permutation = block.permutation;
            if (permutation.getState("gs_ce:growth_stage") === 3) {
                dimension.playSound("block.sweet_berry_bush.pick", block.location);
                dropItemCenterOfBlock(dimension, block.location, new ItemStack("gs_ce:white_sweet_berries", randInt(1, 3)));
                block.setPermutation(permutation.withState("gs_ce:growth_stage", 1));
            }
        },
        onRandomTick: ({ block }) => {
            const permutation = block.permutation;
            const growthStage = permutation.getState("gs_ce:growth_stage");
            if (growthStage < 3) {
                block.setPermutation(permutation.withState("gs_ce:growth_stage", growthStage + 1));
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_cave_vines_body", {
        onRandomTick: ({ block }) => {
            const blockPermutation = block.permutation;
            const plantAge = blockPermutation.getState("gs_ce:growing_plant_age");
            if (plantAge < 12) {
                block.setPermutation(blockPermutation.withState("gs_ce:growing_plant_age", plantAge + 1));
                return;
            }
            const blockBelow = block.below(1);
            if (blockBelow.typeId === "minecraft:air") {
                if (Math.random() < 0.5) {
                    block.setPermutation(BlockPermutation.resolve("gs_ce:white_cave_vines", { "gs_ce:has_berries": true }));
                } else {
                    block.setPermutation(BlockPermutation.resolve("gs_ce:white_cave_vines", { "gs_ce:has_berries": false }));
                }

                if (Math.random() < 0.25) {
                    blockBelow.setPermutation(blockPermutation.withState("gs_ce:has_berries", true).withState("gs_ce:growing_plant_age", 0));
                } else {
                    blockBelow.setPermutation(blockPermutation.withState("gs_ce:growing_plant_age", 0));
                }
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_cave_vines", {
        onPlayerInteract: ({ block, dimension }) => {
            if (block.permutation.getState("gs_ce:has_berries")) {
                block.setPermutation(block.permutation.withState("gs_ce:has_berries", false));
                dropItemCenterOfBlock(dimension, block.location, new ItemStack("gs_ce:white_glow_berries", randInt(1, 3)));
            }
        },
        onPlayerDestroy: ({ block, dimension }) => {
            const blockAbove = block.above(1);
            if (blockAbove.typeId === "gs_ce:white_cave_vines") {
                blockAbove.setType("gs_ce:white_cave_vines_body");
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_petals", {
        onPlayerInteract: ({ block, player, dimension }) => {
            const equippableComponent = player.getComponent("minecraft:equippable");
            const item = equippableComponent.getEquipment("Mainhand");
            if (!item || item.typeId !== "gs_ce:white_petals") {
                return;
            }

            const blockPermutation = block.permutation;
            const currentState = blockPermutation.getState("gs_ce:petal_stage");
            if (currentState >= 3) {
                return;
            }

            block.setPermutation(blockPermutation.withState("gs_ce:petal_stage", currentState + 1));
            dimension.playSound("place.moss", block.location);
            if (player.getGameMode() === "creative") return;
            if (item.amount > 1) {
                item.amount--;
                equippableComponent.setEquipment("Mainhand", item);
            } else {
                equippableComponent.setEquipment("Mainhand", undefined);
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:leaf_group", {
        onPlayerInteract: ({ block, player, dimension }) => {
            const equippableComponent = player.getComponent("minecraft:equippable");
            const item = equippableComponent.getEquipment("Mainhand");
            if (!item || item.typeId !== "gs_ce:leaf_group") {
                return;
            }

            const blockPermutation = block.permutation;
            const currentState = blockPermutation.getState("gs_ce:leaf_stage");
            if (currentState >= 2) {
                return;
            }

            block.setPermutation(blockPermutation.withState("gs_ce:leaf_stage", currentState + 1));
            dimension.playSound("place.moss", block.location);
            if (player.getGameMode() === "creative") return;
            if (item.amount > 2) {
                item.amount--;
                equippableComponent.setEquipment("Mainhand", item);
            } else {
                equippableComponent.setEquipment("Mainhand", undefined);
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_small_rocks", {
        onPlayerInteract: ({ block, player, dimension }) => {
            const equippableComponent = player.getComponent("minecraft:equippable");
            const item = equippableComponent.getEquipment("Mainhand");
            if (!item || item.typeId !== "gs_ce:white_small_rocks") {
                return;
            }

            const blockPermutation = block.permutation;
            const currentState = blockPermutation.getState("gs_ce:rock_stage");
            if (currentState >= 2) {
                return;
            }

            block.setPermutation(blockPermutation.withState("gs_ce:rock_stage", currentState + 1));
            dimension.playSound("use.stone", block.location);
            if (player.getGameMode() === "creative") return;
            if (item.amount > 1) {
                item.amount--;
                equippableComponent.setEquipment("Mainhand", item);
            } else {
                equippableComponent.setEquipment("Mainhand", undefined);
            }
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_pumpkin", {
        onPlayerInteract: ({ block, player, dimension, face }) => {
            const equippableComponent = player.getComponent("minecraft:equippable");
            const item = equippableComponent.getEquipment("Mainhand");
            const loot = new ItemStack('gs_ce:white_pumpkin_seeds', 1);
            let anchorLoc = { x: block.location.x + 0.5, y: block.location.y + 0.1, z: block.location.z + 0.5 };
            if (!item || item.typeId !== "minecraft:shears") {
                return;
            }
            let direction = face.toLowerCase();
            const permutation = BlockPermutation.resolve("gs_ce:white_carved_pumpkin", {
                "minecraft:cardinal_direction": direction,
            });
            block.setPermutation(permutation);
            dimension.playSound("pumpkin.carve", anchorLoc);
            dimension.spawnItem(loot, anchorLoc);
        },
    });
    
    
    blockComponentRegistry.registerCustomComponent("gs_ce:white_spore_blossom", {
        onTick: ({ block }) => {
            const blockParticles = getSetting(settingPlayers.blockParticles);
            if (!blockParticles) return;
            let location = block.location
            let anchorLoc = { x: location.x + 0.5, y: location.y, z: location.z + 0.5}
            block.dimension.spawnParticle("gs_ce:white_spore.drip", anchorLoc);
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:glowing_eye_blossom", {
        onTick: ({ block }) => {
            const blockParticles = getSetting(settingPlayers.blockParticles);
            if (!blockParticles) return;
            let location = block.location
            let anchorLoc = { x: location.x + 0.5, y: location.y + 0.1, z: location.z + 0.5}
            block.dimension.spawnParticle("gs_ce:eyeblossom.bloom", anchorLoc);
        },
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_lantern", {
        onTick: ({ block }) => {
            const blockParticles = getSetting(settingPlayers.blockParticles);
            if (!blockParticles) return;
            let location = block.location
            let states = block.permutation.getAllStates()
            let face = states["minecraft:block_face"]
            let anchorLoc = { x: location.x + 0.5, y: location.y, z: location.z + 0.5}
            if (face == "down") {
                anchorLoc = { x: location.x + 0.5, y: location.y + 0.25, z: location.z + 0.5}
            }
            block.dimension.spawnParticle("gs_ce:lantern.bloom.white", anchorLoc);            
        },
        onPlace: ({ block }) => {
            let location = block.location
            try { block.dimension.spawnEntity("gs_ce:white_firefly", location) } catch (ignored) {}
        }
    });
    blockComponentRegistry.registerCustomComponent("gs_ce:white_pumpkin_stem", {
        onRandomTick: ({ block }) => {
            const blockPermutation = block.permutation;
            const plantState = blockPermutation.getState("gs_ce:state");
            if (plantState < 7) {
                block.setPermutation(blockPermutation.withState("gs_ce:state", plantState + 1));
                return;
            }
            if (plantState === 8) {
                const facingDirection = blockPermutation.getState("minecraft:cardinal_direction");
                try {
                    switch (facingDirection) {
                        case "north":
                            if (block.north(1).typeId !== "gs_ce:white_pumpkin") {
                                block.setPermutation(blockPermutation.withState("gs_ce:state", 7));
                            }
                            break;
                        case "east":
                            if (block.east(1).typeId !== "gs_ce:white_pumpkin") {
                                block.setPermutation(blockPermutation.withState("gs_ce:state", 7));
                            }
                            break;
                        case "south":
                            if (block.south(1).typeId !== "gs_ce:white_pumpkin") {
                                block.setPermutation(blockPermutation.withState("gs_ce:state", 7));
                            }
                            break;
                        case "west":
                            if (block.west(1).typeId !== "gs_ce:white_pumpkin") {
                                block.setPermutation(blockPermutation.withState("gs_ce:state", 7));
                            }
                            break;
                    }
                } catch (ignored) {}
                return;
            }

            const setBlockToPumpkin = (pumpkinBlock, facing) => {
                pumpkinBlock.setType("gs_ce:white_pumpkin");
                block.setPermutation(blockPermutation.withState("gs_ce:state", 8).withState("minecraft:cardinal_direction", facing));
            }
            const directions = ["north", "east", "south", "west"];
            let foundPumpkin = false;

            for (const direction of directions) {
                const testBlock = block[direction](1);
                if (testBlock.typeId === "gs_ce:white_pumpkin") {
                    setBlockToPumpkin(testBlock, direction);
                    foundPumpkin = true;
                    break;
                }
            }

            if (!foundPumpkin) {
                for (const direction of directions) {
                    const testBlock = block[direction](1);
                    if (testBlock.typeId === "minecraft:air") {
                        setBlockToPumpkin(testBlock, direction);
                        break;
                    }
                }
            }
        }
    })
});
