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



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:arkane_forge_right_arrow") {
        if (!sourceEntity) return;

        const player = sourceEntity.dimension.getEntities({
            type: "minecraft:player",
            location: sourceEntity.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("seal"))
            && !handItem.typeId.includes("base")
        ) {

            if (getScrollEntity(sourceEntity)) return
            if (handItem.getLore().length == 0) {
                return
            }

            const scrollEntity = sourceEntity.dimension.spawnEntity(
                "mf_mg:altar_scroll",
                sourceEntity.location
            );
            let scrollElement = handItem.typeId.split("_")[2];
            scrollEntity.setProperty("mf_mg:element", scrollElement);
            scrollEntity.addTag("mf_mg:forge_scroll")
            handItem.amount = 1
            scrollEntity.getComponent("inventory").container.setItem(0, handItem)

            const scrollAbility = handItem.getLore()[1].replace("-§d", "").replace("§r", "")
            //   console.warn(scrollAbility)
            const scrollPage = getPage(scrollElement, scrollAbility)
            scrollEntity.setProperty("mf_mg:page", scrollPage)

            const forge = sourceEntity.dimension.getEntities({
                type: "mf_mg:forge",
                location: sourceEntity.location,
                maxDistance: 5,
                closest: 1,
            })[0];
            if (forge) {
                scrollEntity.setRotation(forge.getRotation());
                forge.getComponent("rideable").addRider(scrollEntity);
                player.runCommand(`clear @s ${handItem.typeId} 0 1`);
                forge.setProperty("mf_mg:right", true)
                sourceEntity.dimension.playSound("mf_mg:scroll_place", sourceEntity.location, { pitch: 1.0, volume: 1.0, })

            }

        }
    }

    if (id === "mf_mg:arkane_forge_left_arrow") {
        if (!sourceEntity) return;
        const weaponEntity = getWeaponEntity(sourceEntity);

        const player = sourceEntity.dimension.getEntities({
            type: "minecraft:player",
            location: sourceEntity.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("scepter")
            || handItem.typeId.includes("orb")
            || handItem.typeId.includes("tome")
        ) {

            if (getWeaponFloatingEntity(sourceEntity)) return

            const { weapon: weapon, element: element, rarity: rarity, tomeDurability: tomeDurability } = getWeaponInfo(handItem)
            const weaponModel = weaponEntity.dimension.spawnEntity(`mf_mg:weapon_entity_${weapon}_${element}_${rarity}`, weaponEntity.location)
            weaponModel.addTag("mf_mg:is_skeleton_safe")

            handItem.amount = 1
            weaponModel.getComponent("inventory").container.setItem(0, handItem)
            weaponModel.setRotation(weaponEntity.getRotation());
            weaponEntity.getComponent("rideable").addRider(weaponModel);

            player.runCommand(`clear @s ${handItem.typeId} 0 1`);

            const forge = sourceEntity.dimension.getEntities({
                type: "mf_mg:forge",
                location: sourceEntity.location,
                maxDistance: 5,
                closest: 1,
            })[0];
            if (forge)
                forge.setProperty("mf_mg:left", true)

            sourceEntity.dimension.playSound("mf_mg:place_item_1", sourceEntity.location, { pitch: 1.0, volume: 1.0, })

        }

    }

    if (id === "mf_mg:arkane_forge_craft") {
        //   console.warn("craft");
        if (!sourceEntity) return;

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

        const scrollEntity = getScrollEntity(sourceEntity);
        const weaponEntity = getWeaponFloatingEntity(sourceEntity)
        if (!weaponEntity) {
            player.sendMessage("§cYou first need to put a weapon in the forge.")
            return;
        }
        if (!scrollEntity) {
            player.sendMessage("§cYou first need to put a sealed scroll in the forge.")
            return;
        }
        forgeWeapon(sourceEntity, player);
    }

    if (id === "mf_mg:arkane_forge_global") {
        if (!sourceEntity) return;

    }

    if (id === "mf_mg:arkane_forge_spawn") {
        // console.warn("spawn")
        if (!sourceEntity) return;
        sourceEntity.addTag("mf_mg:is_skeleton_safe")
        const DUMMY_IDS = [
            "mf_mg:dummy_forge_right_arrow",
            "mf_mg:dummy_forge_left_arrow",
            "mf_mg:dummy_forge_craft_button",
            "mf_mg:dummy_forge_weapon_entity"
        ];
        // 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:arkane_forge_remove") {
        //    console.warn("remove  ", sourceEntity.typeId)
        if (!sourceEntity) return;

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

        const ENTITY_IDS = [
            "mf_mg:dummy_forge_right_arrow",
            "mf_mg:dummy_forge_left_arrow",
            "mf_mg:dummy_forge_craft_button",
            "mf_mg:dummy_forge_weapon_entity",
            "mf_mg:forge",
            //   "mf_mg:altar_scroll",
        ];
        const dimension = sourceEntity.dimension;

        const scrollEntity = getScrollEntity(sourceEntity);
        if (scrollEntity) {
            const inv = scrollEntity.getComponent('inventory').container;
            for (let i = 0; i < inv.size; i++) {
                const item = inv.getItem(i);
                if (item) {
                    const droppedItem = sourceEntity.dimension.spawnItem(item, scrollEntity.location);
                    droppedItem.applyImpulse(
                        new Vector(
                            scrollEntity.getViewDirection().x * 0.1,
                            0.1,
                            scrollEntity.getViewDirection().z * 0.1
                        )
                    );
                }
            }
            scrollEntity.remove()
        }

        const weaponHolder = getWeaponEntity(sourceEntity)
        weaponHolder.runCommand(`scriptevent mf_mg:arkane_forge_weapon_remove`)

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

        system.runTimeout(() => {
            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();
        }, 3)

    }

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

        //  sourceEntity.setProperty("mf_mg:element", "base")
        const inv = sourceEntity.getComponent('inventory').container;
        for (let i = 0; i < inv.size; i++) {
            const item = inv.getItem(i);
            if (item) {
                const droppedItem = dimension.spawnItem(item, sourceEntity.location);
                droppedItem.applyImpulse(
                    new Vector(
                        sourceEntity.getViewDirection().x * 0.1,
                        0.1,
                        sourceEntity.getViewDirection().z * 0.1
                    )
                );
            }
        }

        const forge = sourceEntity.dimension.getEntities({
            type: "mf_mg:forge",
            location: sourceEntity.location,
            maxDistance: 5,
            closest: 1,
        })[0];
        if (forge)
            forge.setProperty("mf_mg:right", false)

        sourceEntity.remove();

    }

    if (id === "mf_mg:arkane_forge_weapon_remove") {
        // console.warn("remove weapon")
        if (!sourceEntity) return;
        const dimension = sourceEntity.dimension;

        const floatingWeapon = getWeaponFloatingEntity(sourceEntity)
        //  const { weapon, element, rarity } = getWeaponEntityInfo(floatingWeapon)
        if (!floatingWeapon) return

        const inv = floatingWeapon.getComponent('inventory').container;
        for (let i = 0; i < inv.size; i++) {
            const item = inv.getItem(i);
            if (item) {
                const droppedItem = sourceEntity.dimension.spawnItem(item, floatingWeapon.location);
                droppedItem.applyImpulse(
                    new Vector(
                        sourceEntity.getViewDirection().x * 0.2,
                        0.1,
                        sourceEntity.getViewDirection().z * 0.2
                    )
                );
            }
        }

        const forge = sourceEntity.dimension.getEntities({
            type: "mf_mg:forge",
            location: sourceEntity.location,
            maxDistance: 5,
            closest: 1,
        })[0];
        if (forge)
            forge.setProperty("mf_mg:left", false)

        floatingWeapon.remove()
    }
});









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 getWeaponEntity(entity) {
    const weaponEntity = entity.dimension.getEntities({
        type: "mf_mg:dummy_forge_weapon_entity",
        location: entity.location,
        maxDistance: 5,
        closest: 1,
    })[0];
    if (weaponEntity) return weaponEntity;
    return null;
}

function getWeaponFloatingEntity(entity) {
    const weaponEntity = entity.dimension.getEntities({
        location: entity.location,
        maxDistance: 5
    }).filter(entity => (entity.typeId.includes("scepter") || entity.typeId.includes("tome") || entity.typeId.includes("orb")))[0]

    if (weaponEntity) return weaponEntity;
    return null;
}

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

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

function getWeaponInfo(item) {
    const itemParts = item.typeId.split("_")
    const element = itemParts[2]
    const rarity = itemParts[3]
    const tomeDurability = itemParts[4] ?? null
    const weapon = itemParts[1].split(":")[1]

    return { weapon: weapon, element: element, rarity: rarity, tomeDurability: tomeDurability }

}

function getWeaponEntityInfo(entity) {
    const itemParts = entity.typeId.split("_")
    const element = itemParts[4]
    const rarity = itemParts[5]
    const weapon = itemParts[3]

    return { weapon: weapon, element: element, rarity: rarity }

}


function forgeWeapon(entity, player) {

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

    const floatingWeapon = getWeaponFloatingEntity(entity)
    let weaponItem = null

    const inv = floatingWeapon.getComponent('inventory').container;
    for (let i = 0; i < inv.size; i++) {
        const item = inv.getItem(i);
        if (item) {
            weaponItem = item
        }
    }

    const { weapon, element, rarity, tomeDurability } = getWeaponInfo(weaponItem)

    if (element !== "base" && scrollElement !== element) {
        player.sendMessage(`§cYou can't add a §9${scrollElement}§c ability on a §9${element}§c ${weapon}`)
        scrollEntity.dimension.playSound("mf_mg:wrong", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

        return;
    }

    const itemLore = weaponItem.getLore()

    let maxAbility = 1
    if (weapon == "orb") maxAbility = 2
    if (weapon == "scepter") maxAbility = 4

    if (itemLore.length - 1 >= maxAbility) {
        player.sendMessage(`§cYou can only have §b${maxAbility}§c ${ability == 1 ? "ability" : "abilities"} on your §b${weapon}§r`)
        scrollEntity.dimension.playSound("mf_mg:wrong", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

        return
    }

    const abilities = [];
    for (const line of itemLore) {
        if (line.startsWith("§l§eAbility")) continue;
        abilities.push(line.replace("-§d§l", "").replace("§r", ""));
    }
    if (abilities.includes(ability)) {
        player.sendMessage(`§cThis ability is already on this ${weapon}`)
        scrollEntity.dimension.playSound("mf_mg:wrong", scrollEntity.location, { pitch: 1.0, volume: 1.0, })

        return
    }

    let newLore = (["§l§eAbility:", `-§d§l${ability}§r`])
    if (itemLore.length > 0) {
        (itemLore.push(`-§d§l${ability}§r`))
        newLore = itemLore
    }

    if (element == "base") {
        weaponItem = new ItemStack(`mf_mg:${weapon}_${scrollElement}_${rarity}${tomeDurability ? `_${tomeDurability}` : ""}`, 1)
    }
    weaponItem.setLore(newLore)

    const droppedItem = entity.dimension.spawnItem(weaponItem, floatingWeapon.location);
    droppedItem.applyImpulse(
        new Vector(
            entity.getViewDirection().x * 0.2,
            0.1,
            entity.getViewDirection().z * 0.2
        )
    );

    const forge = entity.dimension.getEntities({
        type: "mf_mg:forge",
        location: entity.location,
        maxDistance: 5,
        closest: 1,
    })[0];
    if (forge) {
        forge.setProperty("mf_mg:left", false)
        forge.setProperty("mf_mg:right", false)
    }

    floatingWeapon.dimension.playSound("mf_mg:evolve_item", floatingWeapon.location, { pitch: 1.0, volume: 1.0, })

    floatingWeapon.remove()
    scrollEntity.remove()

}
