import {
    world,
    system,
    ItemStack,
    BlockPermutation
} from "@minecraft/server";
import {
    Vector
} from "./vector.js";
import {
    ActionFormData
} from "@minecraft/server-ui";


const MAX_SCROLL_PAGES = [{
    element: "fire",
    maxPage: 11,
},
{
    element: "water",
    maxPage: 10,
},
{
    element: "wind",
    maxPage: 9,
},
{
    element: "nature",
    maxPage: 7,
},
{
    element: "dark",
    maxPage: 9,
},
{
    element: "light",
    maxPage: 8,
},
];

const ABILITY_PAGE = [
    { element: "fire", page: 1, ability: "Tornado", xp: 10, lapis: 5 },
    { element: "fire", page: 2, ability: "Balling", xp: 8, lapis: 5 },
    { element: "fire", page: 3, ability: "Shield", xp: 8, lapis: 4 },
    { element: "fire", page: 4, ability: "Geyser", xp: 12, lapis: 5 },
    { element: "fire", page: 5, ability: "Afterlife", xp: 18, lapis: 8 },
    { element: "fire", page: 6, ability: "Fury", xp: 15, lapis: 7 },
    { element: "fire", page: 7, ability: "Power Ring", xp: 10, lapis: 3 },
    { element: "fire", page: 8, ability: "Rifle", xp: 8, lapis: 4 },
    { element: "fire", page: 9, ability: "Blaster", xp: 25, lapis: 10 },
    { element: "fire", page: 10, ability: "Lifesteal", xp: 14, lapis: 5 },
    { element: "fire", page: 11, ability: "Wall", xp: 8, lapis: 3 },
    //    { element: "fire", page: 13, ability: "Wings", xp: 8, lapis: 3 },
    { element: "water", page: 1, ability: "Afterlife", xp: 18, lapis: 8 },
    { element: "water", page: 2, ability: "Tornado", xp: 10, lapis: 5 },
    { element: "water", page: 3, ability: "Balling", xp: 8, lapis: 5 },
    { element: "water", page: 4, ability: "Shield", xp: 8, lapis: 4 },
    { element: "water", page: 5, ability: "Geyser", xp: 13, lapis: 5 },
    { element: "water", page: 6, ability: "Fury", xp: 15, lapis: 7 },
    { element: "water", page: 7, ability: "Power Ring", xp: 11, lapis: 3 },
    { element: "water", page: 8, ability: "Rifle", xp: 8, lapis: 4 },
    { element: "water", page: 9, ability: "Blaster", xp: 25, lapis: 10 },
    { element: "water", page: 10, ability: "Wall", xp: 8, lapis: 3 },
    // { element: "water", page: 10, ability: "Wings", xp: 8, lapis: 3 },
    { element: "wind", page: 1, ability: "Tornado", xp: 11, lapis: 5 },
    { element: "wind", page: 2, ability: "Shield", xp: 8, lapis: 4 },
    { element: "wind", page: 3, ability: "Geyser", xp: 12, lapis: 5 },
    { element: "wind", page: 4, ability: "Afterlife", xp: 18, lapis: 8 },
    { element: "wind", page: 5, ability: "Fury", xp: 15, lapis: 7 },
    { element: "wind", page: 6, ability: "Power Ring", xp: 9, lapis: 3 },
    { element: "wind", page: 7, ability: "Rifle", xp: 9, lapis: 4 },
    { element: "wind", page: 8, ability: "Blaster", xp: 27, lapis: 10 },
    { element: "wind", page: 9, ability: "Wall", xp: 8, lapis: 3 },
    //   { element: "wind", page: 8, ability: "Wings", xp: 8, lapis: 3 },
    { element: "nature", page: 1, ability: "Balling", xp: 10, lapis: 5 },
    { element: "nature", page: 2, ability: "Geyser", xp: 18, lapis: 8 },
    { element: "nature", page: 3, ability: "Afterlife", xp: 18, lapis: 8 },
    { element: "nature", page: 4, ability: "Power Ring", xp: 10, lapis: 3 },
    { element: "nature", page: 5, ability: "Rifle", xp: 8, lapis: 4 },
    { element: "nature", page: 6, ability: "Lifesteal", xp: 14, lapis: 5 },
    { element: "nature", page: 7, ability: "Wall", xp: 8, lapis: 3 },
    //  { element: "nature", page: 6, ability: "Wings", xp: 8, lapis: 3 },
    { element: "dark", page: 1, ability: "Lumus", xp: 7, lapis: 5 },
    { element: "dark", page: 2, ability: "Shield", xp: 8, lapis: 4 },
    { element: "dark", page: 3, ability: "Afterlife", xp: 20, lapis: 8 },
    { element: "dark", page: 4, ability: "Power Ring", xp: 10, lapis: 3 },
    { element: "dark", page: 5, ability: "Rifle", xp: 10, lapis: 4 },
    { element: "dark", page: 6, ability: "Blaster", xp: 30, lapis: 10 },
    { element: "dark", page: 7, ability: "Life Steal", xp: 7, lapis: 5 },
    { element: "dark", page: 8, ability: "War Fog", xp: 15, lapis: 5 },
    { element: "dark", page: 9, ability: "Wall", xp: 8, lapis: 3 },
    // { element: "dark", page: 8, ability: "Wings", xp: 8, lapis: 3 },
    { element: "light", page: 1, ability: "Lumus", xp: 6, lapis: 3 },
    { element: "light", page: 2, ability: "Afterlife", xp: 18, lapis: 8 },
    { element: "light", page: 3, ability: "Power Ring", xp: 10, lapis: 3 },
    { element: "light", page: 4, ability: "Rifle", xp: 8, lapis: 4 },
    { element: "light", page: 5, ability: "Blaster", xp: 25, lapis: 10 },
    { element: "light", page: 6, ability: "Lifesteal", xp: 14, lapis: 5 },
    { element: "light", page: 7, ability: "War Fog", xp: 15, lapis: 5 },
    { element: "light", page: 8, ability: "Wall", xp: 8, lapis: 3 }
    //  { element: "light", page: 7, ability: "Wings", xp: 8, lapis: 3 },
];




system.afterEvents.scriptEventReceive.subscribe((data) => {
    const {
        id,
        sourceEntity,
        message
    } = data;

    if (id === "mf_mg:spell_altar_right_arrow") {
        //   console.warn("right");

        if (!sourceEntity) return;
        const scrollEntity = getScrollEntity(sourceEntity);
        if (!scrollEntity) {
            placeScrollEntity(sourceEntity);
            return;
        }

        const scrollElement = scrollEntity.getProperty("mf_mg:element");
        const currentPage = scrollEntity.getProperty("mf_mg:page");


        scrollEntity.setProperty("mf_mg:turn", "right");
        system.runTimeout(() => {
            scrollEntity.setProperty("mf_mg:turn", "none");
            scrollEntity.setProperty(
                "mf_mg:page",
                currentPage >= getMaxPageByElement(scrollElement) ? 1 : currentPage + 1
            );

            sourceEntity.dimension.playSound("item.book.page_turn", sourceEntity.location, { pitch: 1.0, volume: 5.0, })
        }, 10)

        sourceEntity.dimension.playSound("random.click", sourceEntity.location, { pitch: 1.0, volume: 1.0, })
        //   sourceEntity.dimension.playSound("item.book.page_turn", sourceEntity.location, { pitch: 1.0, volume: 5.0, })
    }

    if (id === "mf_mg:spell_altar_left_arrow") {
        //   console.warn("left");

        if (!sourceEntity) return;
        const scrollEntity = getScrollEntity(sourceEntity);
        if (!scrollEntity) {
            placeScrollEntity(sourceEntity);
            return;
        }

        const scrollElement = scrollEntity.getProperty("mf_mg:element");
        const currentPage = scrollEntity.getProperty("mf_mg:page");

        scrollEntity.setProperty("mf_mg:turn", "right");
        system.runTimeout(() => {
            scrollEntity.setProperty("mf_mg:turn", "none");
            scrollEntity.setProperty(
                "mf_mg:page",
                currentPage <= 1 ? getMaxPageByElement(scrollElement) : currentPage - 1
            );
            sourceEntity.dimension.playSound("item.book.page_turn", sourceEntity.location, { pitch: 1.0, volume: 5.0, })
        }, 10)
        sourceEntity.dimension.playSound("random.click", sourceEntity.location, { pitch: 1.0, volume: 1.0, })
        //  sourceEntity.dimension.playSound("item.book.page_turn", sourceEntity.location, { pitch: 1.0, volume: 5.0, })

    }

    if (id === "mf_mg:spell_altar_craft") {
        //   console.warn("craft");
        if (!sourceEntity) return;
        const scrollEntity = getScrollEntity(sourceEntity);
        if (!scrollEntity) {
            placeScrollEntity(sourceEntity);
            return;
        }
        craftSealedScroll(sourceEntity);
    }

    if (id === "mf_mg:spell_altar_global") {
        if (!sourceEntity) return;
        const scrollEntity = getScrollEntity(sourceEntity);
        if (!scrollEntity) {
            placeScrollEntity(sourceEntity);
            return;
        }
    }

    if (id === "mf_mg:spell_altar_spawn") {
        //    console.warn("spawn")
        if (!sourceEntity) return;
        sourceEntity.addTag("mf_mg:is_skeleton_safe")
        const DUMMY_IDS = [
            "mf_mg:dummy_altar_right_arrow",
            "mf_mg:dummy_altar_left_arrow",
            "mf_mg:dummy_altar_craft_button",
        ];
        // place all dummy
        for (const dummyId of DUMMY_IDS) {
            const dummyEntity = sourceEntity.dimension.spawnEntity(
                dummyId,
                sourceEntity.location
            );
            dummyEntity.setRotation(sourceEntity.getRotation());
            sourceEntity.getComponent("rideable").addRider(dummyEntity);
        }
        sourceEntity.dimension.playSound("mf_mg:altar_place", sourceEntity.location, { pitch: 1.0, volume: 1.0, })

    }

    if (id === "mf_mg:spell_altar_remove") {
        //   console.warn("remove  ", sourceEntity.typeId)
        if (!sourceEntity) return;

        const altar = sourceEntity.dimension.getEntities({
            type: "mf_mg:altar",
            location: sourceEntity.location,
            maxDistance: 5,
            closest: 1,
        })[0];
        if (!altar.hasTag("mf_mg:altar_is_shaking")) {
            altar.triggerEvent("mf_mg:shake_start");
            return;
        }

        const ENTITY_IDS = [
            "mf_mg:dummy_altar_right_arrow",
            "mf_mg:dummy_altar_left_arrow",
            "mf_mg:dummy_altar_craft_button",
            "mf_mg:altar",
            "mf_mg:altar_scroll",
        ];
        const dimension = sourceEntity.dimension;

        const scrollEntity = getScrollEntity(sourceEntity);
        if (scrollEntity) {
            const scrollElement = scrollEntity.getProperty("mf_mg:element");
            if (scrollElement !== "base") {
                dimension.spawnItem(
                    new ItemStack(`mf_mg:scroll_${scrollElement}_normal`, 1),
                    sourceEntity.location
                );
            }
        }

        dimension.spawnItem(
            new ItemStack(`mf_mg:altar_spawn_egg`, 1),
            sourceEntity.location
        );

        for (const dummyId of ENTITY_IDS) {
            const entity = dimension.getEntities({
                type: dummyId,
                location: sourceEntity.location,
                maxDistance: 5,
                closest: 1,
            })[0];
            if (entity && entity.typeId !== sourceEntity.typeId) {
                entity.remove();
            }
        }
        if (sourceEntity) sourceEntity.remove();
    }

    if (id === "mf_mg:spell_altar_scroll_remove") {
        if (!sourceEntity) return;
        const dimension = sourceEntity.dimension;

        const scrollElement = sourceEntity.getProperty("mf_mg:element");
        if (scrollElement !== "base") {
            const itementity = dimension.spawnItem(
                new ItemStack(`mf_mg:scroll_${scrollElement}_normal`, 1),
                sourceEntity.location
            );
            itementity.applyImpulse(
                new Vector(
                    sourceEntity.getViewDirection().x * 0.2,
                    0.1,
                    sourceEntity.getViewDirection().z * 0.2
                )
            );
        }

        sourceEntity.remove();
    }
});

function getMaxPageByElement(element) {
    const entry = MAX_SCROLL_PAGES.find((item) => item.element === element);
    return entry ? entry.maxPage : null;
}

function placeScrollEntity(entity) {
    const player = entity.dimension.getEntities({
        type: "minecraft:player",
        location: entity.location,
        maxDistance: 10,
        closest: 1,
    })[0];
    if (!player) return;
    let selectedSlot = player.selectedSlotIndex;
    let handItem = player
        .getComponent("inventory")
        .container.getItem(selectedSlot);

    if (!handItem) return;
    if (
        handItem.typeId.includes("scroll_") &&
        handItem.typeId.includes("_normal") &&
        !handItem.typeId.includes("base")
    ) {
        const scrollEntity = entity.dimension.spawnEntity(
            "mf_mg:altar_scroll",
            entity.location
        );
        let scrollElement = handItem.typeId.split("_")[2];
        scrollEntity.setProperty("mf_mg:element", scrollElement);
        scrollEntity.addTag(`mf_mg:altar_scroll_of:${entity.id}`);

        const altar = entity.dimension.getEntities({
            type: "mf_mg:altar",
            location: entity.location,
            maxDistance: 5,
            closest: 1,
        })[0];
        if (altar) {
            scrollEntity.setRotation(altar.getRotation());
            altar.getComponent("rideable").addRider(scrollEntity);
            player.runCommand(`clear @s ${handItem.typeId} 0 1`);

            player.dimension.playSound("mf_mg:place_scroll", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

        }
    }
}

function getScrollEntity(entity) {
    const scrollEntity = entity.dimension.getEntities({
        type: "mf_mg:altar_scroll",
        location: entity.location,
        maxDistance: 5,
        closest: 1,
    })[0];
    if (scrollEntity) return scrollEntity;
    return null;
}

function craftSealedScroll(entity) {
    // en focntion du lapis et xp (+ launch anims)

    const scrollEntity = getScrollEntity(entity);
    const currentPage = scrollEntity.getProperty("mf_mg:page");
    const scrollElement = scrollEntity.getProperty("mf_mg:element");
    const needed_lapis = getLapis(scrollElement, currentPage);
    const needed_xp = getXP(scrollElement, currentPage);
    const ability = getAbility(scrollElement, currentPage);

    const player = entity.dimension.getEntities({
        type: "minecraft:player",
        location: entity.location,
        maxDistance: 10,
        closest: 1,
    })[0];

    const removeItems = checkAndRemoveItems(
        player,
        "minecraft:lapis_lazuli",
        needed_lapis,
        false
    );

    // check for xp
    if (player.level < needed_xp) {
        player.sendMessage("§cNot enough XP! Need §9" + needed_xp + "§c levels.");
        scrollEntity.dimension.playSound("mf_mg:wrong", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

        return;
    }

    // check for lapis
    if (!removeItems) {
        player.sendMessage(
            "§cNot enough lapis! Need §9" + needed_lapis + "§c lapis."
        );
        scrollEntity.dimension.playSound("mf_mg:wrong", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

        return;
    }

    player.addLevels(-needed_xp);
    checkAndRemoveItems(player, "minecraft:lapis_lazuli", needed_lapis, true);

    const sealedScroll = new ItemStack(`mf_mg:scroll_${scrollElement}_seal`, 1);
    sealedScroll.setLore(["§l§eAbility:", `-§d${ability}`]);

    const sealedScrollEntity = entity.dimension.spawnItem(
        sealedScroll,
        scrollEntity.location
    );
    sealedScrollEntity.applyImpulse(
        new Vector(
            scrollEntity.getViewDirection().x * 0.2,
            0.1,
            scrollEntity.getViewDirection().z * 0.2
        )
    );

    scrollEntity.dimension.playSound("random.click", scrollEntity.location, { pitch: 1.0, volume: 1.0, })
    scrollEntity.dimension.playSound("mf_mg:upgrade", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

    scrollEntity.remove();
}

function getXP(element, page) {
    const entry = ABILITY_PAGE.find(
        (item) => item.element === element && item.page === page
    );
    return entry ? entry.xp : null;
}

function getLapis(element, page) {
    const entry = ABILITY_PAGE.find(
        (item) => item.element === element && item.page === page
    );
    return entry ? entry.lapis : null;
}

function getAbility(element, page) {
    const entry = ABILITY_PAGE.find(
        (item) => item.element === element && item.page === page
    );
    return entry ? entry.ability : null;
}

function checkAndRemoveItems(player, itemId, requiredAmount, removeItem) {
    const inventory = player.getComponent("inventory").container;
    let totalAmount = 0;
    let slotsToUpdate = [];

    // Iterate through the player's inventory to count items and track their slots
    for (let i = 0; i < inventory.size; i++) {
        const item = inventory.getItem(i);
        if (item && item.typeId === itemId) {
            totalAmount += item.amount;
            slotsToUpdate.push({
                slot: i,
                item,
            });
            if (totalAmount >= requiredAmount) break;
        }
    }

    // Check if the player has enough items
    if (totalAmount >= requiredAmount) {
        if (removeItem) {
            let amountToRemove = requiredAmount;

            // Remove the required amount of items from the inventory
            slotsToUpdate.forEach(({
                slot,
                item
            }) => {
                if (amountToRemove > 0) {
                    if (item.amount > amountToRemove) {
                        item.amount -= amountToRemove;
                        inventory.setItem(slot, item);
                        amountToRemove = 0;
                    } else {
                        amountToRemove -= item.amount;
                        inventory.setItem(slot, null); // Clear the slot if all items are removed
                    }
                }
            });
        }

        return true; // Successfully removed the required items
    } else {
        return false; // Not enough items
    }
}






