import { world, system, ItemStack, EnchantmentType } from "@minecraft/server";

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

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

    if (id === "msft:global_echo_forge") {
        if (!sourceEntity) return;

    }

    if (id === "msft:remove_weapon_echo_forge") {
        if (!sourceEntity) return;

        if (sourceEntity.typeId === "msft:echo_forge") {
            if (!sourceEntity.hasTag("msft:forge_is_shaking")) {
                sourceEntity.triggerEvent("msft:shake_start");
                return;
            }
        }


        let floatingItem = getWeaponFloatingEntity(sourceEntity);
        if (floatingItem) {

            if (sourceEntity.typeId !== floatingItem.typeId) {
                const blockAir = sourceEntity.dimension.getBlock(sourceEntity.location);
                blockAir.setType("minecraft:air");
                sourceEntity.dimension.spawnItem(new ItemStack("msft:echo_forge_spawn_egg", 1), sourceEntity.location);
                sourceEntity.remove();
            }
            floatingItem.getTags().forEach(tag => {
                const item = new ItemStack(tag, 1);
                addAllEnchantments(item, floatingItem);
                floatingItem.dimension.spawnItem(item, floatingItem.location);
                floatingItem.remove();
            });
        } else {
            const blockAir = sourceEntity.dimension.getBlock(sourceEntity.location);
            blockAir.setType("minecraft:air");
            sourceEntity.dimension.spawnItem(new ItemStack("msft:echo_forge_spawn_egg", 1), sourceEntity.location);
            sourceEntity.remove();
        }
    }

    // if (id === "msft:remove_echo_forge") {
    //     if (!sourceEntity) return;

    //     const entity = sourceEntity.dimension.getEntities({
    //         type: "msft:echo_forge",
    //         location: sourceEntity.location,
    //         maxDistance: 5,
    //         closest: 1,
    //     })[0];

    //     if (entity) {
    //         entity.remove();
    //     }
    // }

    if (id === "msft:test") {
        //console.log("testestest");
    }

    if (id === "msft:echo_forge_spawn") {
        const entity = sourceEntity.dimension.getEntities({
            type: "msft:echo_forge",
            location: sourceEntity.location,
            maxDistance: 5,
            closest: 1,
        })[0];
        entity.runCommandAsync("setblock ~ ~ ~ minecraft:barrier");
    }

    if (id === "msft:spawn_weapon_echo_forge") {

        if (!sourceEntity) return;

        let weaponEntity = getWeaponEntity(sourceEntity);

        if (!player) return;
        let selectedSlot = player.selectedSlotIndex;

        let handItem = player.getComponent("inventory").container.getItem(selectedSlot);
        if (!handItem) return;


        if (handItem.typeId === "msft:echo_ingot" && getWeaponFloatingEntity(sourceEntity)) {
            const entityScroll = getWeaponFloatingEntity(sourceEntity);
            const { itemType: itemType } = getInfoScrollWeapon(entityScroll.typeId);

            let item = null;
            switch (itemType) {
                case "boomerang":
                case "shuriken":
                case "sai":
                    item = new ItemStack(`msft:echo_${itemType}_item`, 1);
                    break;

                default:
                    item = new ItemStack(`msft:echo_${itemType}`, 1);
                    break;
            }
            addAllEnchantments(item, entityScroll);
            //console.log(entityScroll.typeId);
            let height = 0.20;

            if (!sourceEntity.hasTag("isUpgrading")) {
                sourceEntity.addTag("isUpgrading");
            } else {
                player.sendMessage("§cYou can't use this item when the echo forge is in use!");
                return;
            }

            if (handItem.amount > 1) {
                handItem.amount -= 1;
                player.getComponent("inventory").container.setItem(selectedSlot, handItem);
            } else {
                player.getComponent("inventory").container.setItem(selectedSlot, undefined);
            }

            const entityForge = sourceEntity.dimension.getEntities({
                type: "msft:echo_forge",
                location: sourceEntity.location,
                maxDistance: 5,
                closest: 1,
            })[0];

            entityForge.setProperty("msft:is_crafting", true);

            system.runTimeout(() => {
                entityScroll.dimension.spawnItem(item, entityScroll.location);
                entityScroll.remove();
                sourceEntity.removeTag("isUpgrading");
                entityForge.setProperty("msft:is_sword_put", false);
                entityForge.setProperty("msft:is_crafting", false);
            }, 70);

            return;
        }
        if (handItem.typeId.includes("netherite")) {
            if (handItem.typeId.includes("netherite_ingot") ||
                handItem.typeId.includes("netherite_hoe") ||
                handItem.typeId.includes("netherite_pickaxe") ||
                handItem.typeId.includes("netherite_shovel")) return;

            if (getWeaponFloatingEntity(sourceEntity)) {
                player.sendMessage("§cThere are already an Item on the Echo Forge!");
                return;
            }
            const { material: material, itemType: itemType } = getInfoWeapon(handItem);
            const weaponModel = weaponEntity.dimension.spawnEntity(`msft:${material}_${itemType}_entity`, weaponEntity.location);

            if (handItem.hasComponent("minecraft:enchantable")) {
                saveEnchantments(handItem, weaponModel);
            }
            weaponModel.addTag(handItem.typeId);
            handItem.amount = 1;
            player.getComponent("inventory").container.setItem(selectedSlot, null);
            weaponModel.setRotation(weaponEntity.getRotation());
            weaponEntity.getComponent("rideable").addRider(weaponModel);
            sourceEntity.setProperty("msft:is_sword_put", true);

            if (handItem.amount > 1) {
                handItem.amount -= 1;
                player.getComponent("inventory").container.setItem(selectedSlot, handItem);
            } else {
                player.getComponent("inventory").container.setItem(selectedSlot, undefined);
            }
        } else {
            player.sendMessage("§cYou must put netherite item!");
        }
    }
});

function saveEnchantments(item, entity) {
    const enchantList = item.getComponent("enchantable").getEnchantments();
    let enchantData = [];
    for (const enchant of enchantList) {
        enchantData.push({
            id: enchant.type.id,
            level: enchant.level
        });
    }
    entity.setDynamicProperty("enchantments", JSON.stringify(enchantData));
}

function addAllEnchantments(item, entity) {

    let enchantData = entity.getDynamicProperty("enchantments");
    if (!enchantData) return;
    let enchantments = JSON.parse(enchantData);

    if (!Array.isArray(enchantments)) {
        return;
    }

    if (item.hasComponent("minecraft:enchantable")) {
        const enchantComponent = item.getComponent("minecraft:enchantable");

        for (const enchant of enchantments) {
            //console.log(enchant.id, enchant.level);
            enchantComponent.addEnchantment({
                type: new EnchantmentType(enchant.id),
                level: enchant.level
            });
        }
    }
}

function getWeaponEntity(entity) {
    const weaponEntity = entity.dimension.getEntities({
        type: "msft:echo_forge",
        location: entity.location,
        maxDistance: 1.5,
        closest: 1,
    })[0];
    if (weaponEntity) return weaponEntity;
    return null;
}

function getWeaponFloatingEntity(entity) {
    const weaponEntity = entity.dimension.getEntities({
        location: entity.location,
        maxDistance: 1.5
    }).filter(entity => entity.typeId.includes("netherite"))[0];
    if (weaponEntity) return weaponEntity;
    return null;
}

function getInfoWeapon(item) {
    const itemPart = item.typeId.split("_");

    const material = itemPart[0].split(":")[1];
    const itemType = itemPart[1];

    return { material: material, itemType: itemType }
}

function getInfoScrollWeapon(item) {
    const itemPart = item.split("_");

    const material = itemPart[0].split(":")[1];
    const itemType = itemPart[1];

    return { material: material, itemType: itemType }
}