/*import { EasingType, ItemStack, system } from "@minecraft/server";
import { POKEMON_CAN_LEARN, POKEMONS_DATA } from "../pokemon.js";
import { ActionFormData } from "@minecraft/server-ui";
import { MOVEMENTS_DATA, TYPE_ADVANTAGES } from "../movement.js";
import { StringUtils } from "../../utils/stringUtils.js";
export function battleForm(source, yourPokemon, opponentPokemon) {
    const form = new ActionFormData();
    mainBattleForm(source, yourPokemon, opponentPokemon, form);
    form.button("Battle");
    form.button("Run");
    form.button("Pokeball");
    form.button("Bag");
    return form;
}
function battleMovementForm(source, yourPokemon, opponentPokemon) {
    const form = new ActionFormData();
    mainBattleForm(source, yourPokemon, opponentPokemon, form);
    [1, 2, 3, 4].forEach(i => form.button(returnMovementName(yourPokemon, i)));
    return form;
}
function mainBattleForm(source, yourPokemon, opponentPokemon, form) {
    const yourPokemonData = POKEMONS_DATA.find(pokemon => pokemon.id == yourPokemon.typeId);
    const opponentPokemonData = POKEMONS_DATA.find(pokemon => pokemon.id == opponentPokemon.typeId);
    if (!yourPokemonData || !opponentPokemonData)
        return;
    const healthYourPokemon = yourPokemon.getComponent("minecraft:health");
    const healthOpponentPokemon = opponentPokemon.getComponent("minecraft:health");
    if (!healthYourPokemon || !healthOpponentPokemon)
        return;
    const { opponentPokemonHealthPercentage, yourPokemonHealthPercentage } = returnHealthPokemons(source, yourPokemon, opponentPokemon, yourPokemonData, opponentPokemonData, healthYourPokemon, healthOpponentPokemon);
    form.title("Battle");
    form.body(`P1:${yourPokemonHealthPercentage}`.padEnd(6, " ") + `P2:${opponentPokemonHealthPercentage}`.padEnd(12, " "));
    form.button(StringUtils.toTitleCaseEntityName(yourPokemon.typeId) + " (My)", "textures/icons/pokemons/" + StringUtils.toLowerCaseEntityName(yourPokemon.typeId));
    form.button(StringUtils.toTitleCaseEntityName(opponentPokemon.typeId), "textures/icons/pokemons/" + StringUtils.toLowerCaseEntityName(opponentPokemon.typeId));
}
function returnMovementName(yourPokemon, moveIndex) {
    const moveId = yourPokemon.getDynamicProperty(`pr:move${moveIndex}`);
    const moveList = POKEMON_CAN_LEARN.get(yourPokemon.typeId.replace("pr:", ""));
    if (moveList && moveList.includes(moveId)) {
        const move = MOVEMENTS_DATA.find((m) => m.id === moveId);
        if (move) {
            return move.name;
        }
    }
    return "";
}
export const buttonOfBattleForm = {
    0: (source, yourPokemon, opponentPokemon) => {
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleForm(source, yourPokemon, opponentPokemon);
        }, 10);
    },
    1: (source, yourPokemon, opponentPokemon) => {
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleForm(source, yourPokemon, opponentPokemon);
        }, 5);
    },
    2: (source, yourPokemon, opponentPokemon) => {
        system.runTimeout(() => {
            const form = battleMovementForm(source, yourPokemon, opponentPokemon);
            form.show(source).then((result) => {
                if (result.canceled || result.cancelationReason || !result.selection)
                    return;
                const moveIndex = result.selection;
                const moveFunction = buttonOfBattleMovementForm[moveIndex];
                if (moveFunction) {
                    moveFunction(source, yourPokemon, opponentPokemon);
                }
            });
        }, 0.25 * 20);
    },
    3: (source, yourPokemon, opponentPokemon) => {
        yourPokemon.setDynamicProperty("pr:on_battle", false);
        opponentPokemon.setDynamicProperty("pr:on_battle", false);
        source.camera.clear();
    },
    4: (source, yourPokemon, opponentPokemon) => {
        return;
    },
    5: (source, yourPokemon, opponentPokemon) => {
        return;
    }
};
const buttonOfBattleMovementForm = {
    0: (source, yourPokemon, opponentPokemon) => {
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleMovementForm(source, yourPokemon, opponentPokemon);
        }, 10);
    },
    1: (source, yourPokemon, opponentPokemon) => {
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleMovementForm(source, yourPokemon, opponentPokemon);
        }, 10);
    },
    2: (source, yourPokemon, opponentPokemon) => {
        buttonMovementAttack(source, yourPokemon, opponentPokemon);
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleMovementForm(source, yourPokemon, opponentPokemon);
        }, 10);
    },
    3: (source, yourPokemon, opponentPokemon) => {
        buttonMovementAttack(source, yourPokemon, opponentPokemon);
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleMovementForm(source, yourPokemon, opponentPokemon);
        }, 10);
    },
    4: (source, yourPokemon, opponentPokemon) => {
        buttonMovementAttack(source, yourPokemon, opponentPokemon);
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleMovementForm(source, yourPokemon, opponentPokemon);
        }, 10);
    },
    5: (source, yourPokemon, opponentPokemon) => {
        buttonMovementAttack(source, yourPokemon, opponentPokemon);
        setCameraForBattle(source, yourPokemon);
        system.runTimeout(() => {
            battleMovementForm(source, yourPokemon, opponentPokemon);
        }, 10);
    }
};
function buttonMovementAttack(source, yourPokemon, opponentPokemon) {
    const yourPokemonHealth = yourPokemon.getComponent("minecraft:health");
    const opponentPokemonHealth = opponentPokemon.getComponent("minecraft:health");
    if (!yourPokemonHealth || !opponentPokemonHealth)
        return;
    const yourPokemonLevel = yourPokemon.getDynamicProperty("pr:level");
    const opponentPokemonLevel = opponentPokemon.getDynamicProperty("pr:level");
    if (yourPokemonHealth.currentValue > 1 || opponentPokemonHealth.currentValue > 1) {
        applyDamage(source, yourPokemon, opponentPokemon, yourPokemonLevel, opponentPokemonLevel);
    }
}
function setCameraForBattle(source, pokemon) {
    const pokemonViewDirection = pokemon.getViewDirection();
    source.camera.setCamera("minecraft:free", {
        location: {
            x: pokemon?.location.x - (pokemonViewDirection.x * 3),
            y: pokemon?.location.y + 1.5,
            z: pokemon?.location.z - (pokemonViewDirection.z * 3),
        },
        rotation: pokemon.getRotation(),
        easeOptions: {
            easeTime: 0.25,
            easeType: EasingType.Linear,
        },
        facingEntity: pokemon,
    });
}
function returnHealthPokemons(player, yourPokemon, opponentPokemon, yourPokemonData, opponentPokemonData, healthYourPokemon, healthOpponentPokemon) {
    const yourPokemonCurrentHealth = Math.round(healthYourPokemon.currentValue);
    const yourPokemonMaxHealth = Math.round(yourPokemonData.maxHealth);
    const opponentPokemonCurrentHealth = Math.round(healthOpponentPokemon.currentValue);
    const opponentPokemonMaxHealth = Math.round(opponentPokemonData.maxHealth);
    const yourPokemonHealthPercentage = Math.round((yourPokemonCurrentHealth / yourPokemonMaxHealth) * 100);
    const opponentPokemonHealthPercentage = Math.round((opponentPokemonCurrentHealth / opponentPokemonMaxHealth) * 100);
    return {
        yourPokemonHealthPercentage,
        opponentPokemonHealthPercentage
    };
}
export function applyDamage(source, yourPokemon, opponentPokemon, level, enemyLevel) {
    const damageToEnemy = calculateDamage(yourPokemon.typeId, opponentPokemon.typeId, level, enemyLevel);
    const damageToPoke = calculateDamage(opponentPokemon.typeId, yourPokemon.typeId, enemyLevel, level);
    const enemyHealthComp = opponentPokemon.getComponent("minecraft:health");
    const pokeHealthComp = yourPokemon.getComponent("minecraft:health");
    if (!enemyHealthComp || !pokeHealthComp)
        return;
    const enemyCurrent = enemyHealthComp.currentValue;
    const pokeCurrent = pokeHealthComp.currentValue;
    if (enemyCurrent > 1) {
        applyDamageToEnemy(source, yourPokemon, opponentPokemon, damageToEnemy);
    }
    if (pokeCurrent > 1) {
        applyDamageToEnemy(source, opponentPokemon, yourPokemon, damageToPoke);
    }
    const stillAlive = (enemyHealthComp.currentValue > 1 &&
        pokeHealthComp.currentValue > 1);
    if (stillAlive) {
        battleForm(source, yourPokemon, opponentPokemon);
    }
}
function applyDamageToEnemy(source, yourPokemon, opponentPokemon, damageToEnemy) {
    const opponentPokemonHealthComp = opponentPokemon.getComponent("minecraft:health");
    const yourPokemonHealthComp = yourPokemon.getComponent("minecraft:health");
    if (!opponentPokemonHealthComp || !yourPokemonHealthComp)
        return;
    const pokemonHealthCurrent = Math.round(opponentPokemonHealthComp.currentValue);
    if (pokemonHealthCurrent <= 1)
        return;
    const newEnemyHealth = Math.round(Math.max(1, pokemonHealthCurrent - damageToEnemy));
    opponentPokemonHealthComp.setCurrentValue(newEnemyHealth);
    if (newEnemyHealth == 1) {
        const playerName = opponentPokemon.getDynamicProperty("pr:owner_name");
        const tamed = opponentPokemon.getDynamicProperty("pr:tamed");
        opponentPokemon.dimension.getPlayers({
            location: opponentPokemon.location,
            maxDistance: 32
        }).forEach((player) => {
            if (tamed) {
                if (player.id === playerName) {
                    const item = new ItemStack(opponentPokemon.typeId + "_fainted", 1);
                    item.setLore([
                        `${StringUtils.toTitleCaseEntityName(opponentPokemon.typeId)} Tamed`,
                        `Owner:§7 ${player.nameTag}`,
                        `Level:§7 ${opponentPokemon.getDynamicProperty("pr:level")}`,
                        `§cDeath`
                    ]);
                    player.dimension.spawnItem(item, opponentPokemon.location);
                    player.onScreenDisplay.setActionBar("Battle is finished!");
                    player.camera.clear();
                    opponentPokemon.remove();
                }
                return;
            }
            const level = yourPokemon.getDynamicProperty("pr:level");
            const nickname = yourPokemon.getDynamicProperty("pr:nickname");
            yourPokemon.setDynamicProperty("pr:level", level + 1);
            if (!nickname) {
                yourPokemon.nameTag = StringUtils.toTitleCaseEntityName(yourPokemon.typeId) + " | Lvl: §a" + yourPokemon.getDynamicProperty("pr:level") + "§r\n" + "Owner:§a " + yourPokemon.getDynamicProperty("pr:owner_name");
            }
            else {
                yourPokemon.nameTag = yourPokemon.getDynamicProperty("pr:nickname") + " | Lvl: §a" + yourPokemon.getDynamicProperty("pr:level") + "§r\n" + "Owner:§a " + yourPokemon.getDynamicProperty("pr:owner_name");
            }
            source.onScreenDisplay.setActionBar("Battle is finished!");
            source.camera.clear();
            source.playSound("firework.twinkle");
            source.playSound("random.orb");
            opponentPokemon.remove();
        });
    }
    else {
        opponentPokemon.playAnimation("attack");
        opponentPokemon.runCommand("damage @s 0");
    }
}
function getPokemonType(typeId) {
    const data = POKEMONS_DATA.find(p => p.id === typeId);
    return data?.types?.[0] || "normal";
}
function getMultiplier(attackerType, defenderType) {
    const advantages = TYPE_ADVANTAGES[attackerType];
    if (!advantages)
        return 1;
    if (advantages.strong.includes(defenderType))
        return 2;
    if (advantages.weak.includes(defenderType))
        return 0.5;
    return 1;
}
function calculateDamage(attackerId, defenderId, attackerLevel, defenderLevel) {
    const attackerType = getPokemonType(attackerId);
    const defenderType = getPokemonType(defenderId);
    const baseDamage = 10;
    const typeMultiplier = getMultiplier(attackerType, defenderType);
    const levelDifference = attackerLevel - defenderLevel;
    let levelMultiplier = 1 + (levelDifference * 0.1);
    levelMultiplier = Math.max(0.5, Math.min(1.5, levelMultiplier));
    return baseDamage * levelMultiplier * typeMultiplier;
}
