import { Block, BlockPermutation, ItemStack, Player, system, world } from "@minecraft/server";
import { Blocks } from "../data/blocks";
import { LecternRecipes, LecternStateToItem, RecipeItems } from "../data/lectern_recipes";
import { getAllStates, getHeldItem } from "../utils/utils";

world.beforeEvents.playerBreakBlock.subscribe((event) => {
    const { block, player, itemStackAfterBreak } = event;

    if (block) {
        if (block?.typeId == Blocks.cursed_lectern) {
            handleBrokenLectern(block);
        }
    }
});

/**
 *
 * @param {ItemStack} itemStack
 * @returns {boolean}
 */
function isRecipeItem(itemStack) {
    return RecipeItems.get(itemStack.typeId);
}

/**
 *
 * @param {string} state
 */
function getRecipeItemByState(state) {}

/**
 *
 * @param {Player} player
 * @param {Block} block
 * @param {ItemStack} itemStack
 */
export function handleLectern(player, block, itemStack) {
    const cardinal_direction = block.permutation.getState("minecraft:cardinal_direction");
    const item1 = LecternStateToItem.get(block.permutation.getState("ns_rh:item1")).typeId;
    const item2 = LecternStateToItem.get(block.permutation.getState("ns_rh:item2")).typeId;
    const item3 = LecternStateToItem.get(block.permutation.getState("ns_rh:item3")).typeId;
    const item4 = LecternStateToItem.get(block.permutation.getState("ns_rh:item4")).typeId;

    const placedItems = [item1, item2, item3, item4];

    if (!player.isSneaking && itemStack != undefined) {
        if (itemStack.typeId == "ns_rh:grimoire") {
            const magicBookRecipe = LecternRecipes.find((recipe) =>
                recipe.items.every((item) => placedItems.includes(item))
            );

            if (magicBookRecipe) {
                player.dimension.spawnItem(magicBookRecipe.result.item, player.location);

                const newStates = {
                    "minecraft:cardinal_direction": cardinal_direction,
                    "ns_rh:item1": "none",
                    "ns_rh:item2": "none",
                    "ns_rh:item3": "none",
                    "ns_rh:item4": "none",
                };

                block.setPermutation(BlockPermutation.resolve(block.typeId, newStates));
            }
        }
        if (itemStack && isRecipeItem(itemStack)) {
            if (block.permutation.getState(RecipeItems.get(itemStack.typeId).state) == "none") {
                const itemCount = getHeldItem(player).amount;

                if (itemCount > 1) {
                    player.runCommand(
                        `replaceitem entity @s slot.weapon.mainhand 0 ${
                            itemStack.typeId
                        } ${Math.max(1, itemCount - 1)}`
                    );
                } else {
                    player.runCommand(`clear @s ${itemStack.typeId}`);
                }

                const currentStates = JSON.parse(getAllStates(block));

                const recipeData = RecipeItems.get(itemStack.typeId);

                const newStates = {
                    ...currentStates,
                    ...recipeData.states,
                };

                block.setPermutation(BlockPermutation.resolve(block.typeId, newStates));
            }
        }
    } else if (player.isSneaking) {
        for (let item of placedItems) {
            if (item != "none")
                block.dimension.spawnItem(new ItemStack(item, 1), {
                    x: block.location.x,
                    y: block.location.y + 1,
                    z: block.location.z,
                });

            const newStates = {
                "minecraft:cardinal_direction": cardinal_direction,
                "ns_rh:item1": "none",
                "ns_rh:item2": "none",
                "ns_rh:item3": "none",
                "ns_rh:item4": "none",
            };

            block.setPermutation(BlockPermutation.resolve(block.typeId, newStates));
        }
    }
}

/**
 *
 * @param {Block} block
 */
export function handleBrokenLectern(block) {
    const cardinal_direction = block.permutation.getState("minecraft:cardinal_direction");
    const item1 = LecternStateToItem.get(block.permutation.getState("ns_rh:item1")).typeId;
    const item2 = LecternStateToItem.get(block.permutation.getState("ns_rh:item2")).typeId;
    const item3 = LecternStateToItem.get(block.permutation.getState("ns_rh:item3")).typeId;
    const item4 = LecternStateToItem.get(block.permutation.getState("ns_rh:item4")).typeId;

    const { dimension, location } = block;

    const placedItems = [item1, item2, item3, item4];

    for (let item of placedItems) {
        if (item != "none")
            system.runTimeout(() => {
                dimension.spawnItem(new ItemStack(item, 1), {
                    x: location.x,
                    y: location.y + 1,
                    z: location.z,
                });
            }, 0.1 * 20);
    }
}
