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





const RARITIES = [
    "common",
    "rare",
    "epic",
    "legendary",
]
const RARITY_COLOR = [
    "§2",
    "§9",
    "§d",
    "§6",
]
const REQUIRED_DIAMONDS = [
    1,
    3,
    5,
    null,
]



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


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

        let availableDiamonds = 0;
        for (const aboveEntity of sourceEntity.dimension.getEntities({
            location: sourceEntity.location,
            maxDistance: 1,
            type: "minecraft:item"
        })) {
            let aboveItem = aboveEntity.getComponent('minecraft:item').itemStack;
            if (aboveItem.typeId == "minecraft:diamond") {
                availableDiamonds += aboveItem.amount;
                aboveEntity.remove();
            }
        }
        if (availableDiamonds == 0) return;

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

        const rarityNB = RARITIES.indexOf(rarity) + 1;
        const rarityColor = RARITY_COLOR[rarityNB - 1];
        const requiredDiamond = REQUIRED_DIAMONDS[rarityNB - 1];
        let currentDiamonds = sourceEntity.getDynamicProperty("mf_mg:fountain_sensor_diamonds") ?? 0;

        // Calcule combien de diamants on peut prendre
        const diamondToTake = Math.min(availableDiamonds, requiredDiamond - currentDiamonds);
        const remainingDiamonds = availableDiamonds - diamondToTake;

        // Actualise la propriété dynamique
        currentDiamonds += diamondToTake;
        sourceEntity.setDynamicProperty("mf_mg:fountain_sensor_diamonds", currentDiamonds);

        // Redonne les diamants restants sous forme d'items (par stack de 64 max)
        const spawnLocation = Vector.add(sourceEntity.location, { x: 0, y: 1, z: 0 });
        let diamondsLeftToSpawn = remainingDiamonds;

        while (diamondsLeftToSpawn > 0) {
            const stackSize = Math.min(64, diamondsLeftToSpawn);
            const droppedItem = sourceEntity.dimension.spawnItem(new ItemStack("minecraft:diamond", stackSize), spawnLocation);
            droppedItem.applyImpulse(
                new Vector(
                    sourceEntity.getViewDirection().x * 0.2,
                    0.1,
                    sourceEntity.getViewDirection().z * 0.2
                )
            );
            diamondsLeftToSpawn -= stackSize;
        }

        // Actualise le nameTag du senseur
        sourceEntity.nameTag = `§lRarity:§r ${rarityColor}${rarity} (${rarityNB}/4)\n ${rarity == "legendary"
            ? `Already Max Level !`
            : `Drop diamonds in the fountain (${currentDiamonds}/${requiredDiamond})`
            }`;

        if (currentDiamonds == requiredDiamond && rarity !== "legendary") {
            sourceEntity.setDynamicProperty("mf_mg:fountain_sensor_diamonds", 0);

            let weaponItem = null
            const inv = weaponEntity.getComponent('inventory').container;
            for (let i = 0; i < inv.size; i++) {
                const item = inv.getItem(i);
                if (item) {
                    weaponItem = item
                }
            }
            const newRarity = RARITIES[rarityNB]

            const currentAbility = weaponItem.getDynamicProperty("mf_mg:weapon_selected_ability") ?? 0;
            const currentLore = weaponItem.getLore()

            const newWeaponItem = new ItemStack(weaponItem.typeId.replace(RARITIES[rarityNB - 1], newRarity), 1)
            newWeaponItem.setDynamicProperty("mf_mg:weapon_selected_ability", currentAbility)
            newWeaponItem.setLore(currentLore)

            const newWeaponModel = sourceEntity.dimension.spawnEntity(`mf_mg:weapon_entity_${weapon}_${element}_${newRarity}`, weaponEntity.location)
            weaponEntity.remove()
            newWeaponModel.addTag("mf_mg:is_skeleton_safe")
            newWeaponModel.getComponent("inventory").container.setItem(0, newWeaponItem)
            newWeaponModel.setRotation(sourceEntity.getRotation());
            const weaponRide = getWeaponEntity(sourceEntity)
            system.runTimeout(() => {
                weaponRide.getComponent("rideable").addRider(newWeaponModel);
            }, 3)

            // Actualise le nameTag du senseur
            sourceEntity.nameTag = `§lRarity:§r ${RARITY_COLOR[rarityNB]}${newRarity} (${rarityNB + 1}/4)\n ${newRarity == "legendary"
                ? `Already Max Level !`
                : `Drop diamonds in the fountain (0/${REQUIRED_DIAMONDS[rarityNB]})`
                }`;

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


        }
    }

    if (id === "mf_mg:fountain_weapon_dummy_spawn") {
        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 fountain = sourceEntity.dimension.getEntities({
                type: "mf_mg:fountain",
                location: sourceEntity.location,
                maxDistance: 5,
                closest: 1,
            })[0];
            if (fountain)
                fountain.setProperty("mf_mg:have_weapon", true)

            const sensor = getFountainSensor(sourceEntity)
            const rarityNB = RARITIES.indexOf(rarity) + 1
            const rarityColor = RARITY_COLOR[rarityNB - 1]
            const requiredDiamond = REQUIRED_DIAMONDS[rarityNB - 1]
            const currentDiamonds = sensor.getDynamicProperty("mf_mg:fountain_sensor_diamonds") ?? 0

            sensor.nameTag = `§lRarity:§r ${rarityColor}${rarity} (${rarityNB}/4)\n ${rarity == "legendary" ? `Already Max Level !` : `Drop diamonds in the fountain (${currentDiamonds}/${requiredDiamond})`}`

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

        }

    }

    if (id === "mf_mg:upgrade_fountain_spawn") {
        // console.warn("spawn")
        if (!sourceEntity) return;
        sourceEntity.addTag("mf_mg:is_skeleton_safe")
        const DUMMY_IDS = [
            "mf_mg:fountain_sensor",
            "mf_mg:dummy_fountain_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:upgrade_fountain_remove") {
        if (!sourceEntity) return;

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

        const ENTITY_IDS = [
            "mf_mg:fountain_sensor",
            "mf_mg:dummy_fountain_weapon_entity",
            "mf_mg:fountain",
        ];
        const dimension = sourceEntity.dimension;

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

        dimension.spawnItem(
            new ItemStack(`mf_mg:fountain_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:upgrade_fountain_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 sensor = getFountainSensor(sourceEntity)
        const currentDiamonds = sensor.getDynamicProperty("mf_mg:fountain_sensor_diamonds") ?? 0
        //  console.warn(currentDiamonds)
        if (currentDiamonds > 0) {
            const droppedItem = sourceEntity.dimension.spawnItem(new ItemStack("minecraft:diamond", currentDiamonds), sourceEntity.location)
            droppedItem.applyImpulse(
                new Vector(
                    sourceEntity.getViewDirection().x * 0.2,
                    0.1,
                    sourceEntity.getViewDirection().z * 0.2
                )
            );
        }
        sensor.setDynamicProperty("mf_mg:fountain_sensor_diamonds", 0)
        sensor.nameTag = ""

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

        floatingWeapon.remove()
    }
});


























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

function getWeaponEntity(entity) {
    const weaponEntity = entity.dimension.getEntities({
        type: "mf_mg:dummy_fountain_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 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 }

}

