import { Entity, Player, EquipmentSlot, EntityEquippableComponent, ItemStack } from "@minecraft/server";
import * as mc from '@minecraft/server'
export const boss = {
    zombie_boss: {
        damage_melee: 4,
        damage_range: "ns_ab:minion_zombie",
        spawnAnimation: true,
        tagAttack: "bzAttack",
        music: 'boss_fight.dark_future'
    },
    minion_zombie: {
        damage_melee: 6,
        damage_range: "ns_ab:blank",
        spawnAnimation: false,
        tagAttack: "mzAttack",
        music: ''
    },
    skeleton_bow: {
        damage_melee: 6,
        damage_range: "ns_ab:blank",
        spawnAnimation: false,
        tagAttack: "mzAttack",
        music: ''
    },
    skeleton_sword: {
        damage_melee: 6,
        damage_range: "ns_ab:blank",
        spawnAnimation: false,
        tagAttack: "mzAttack",
        music: ''
    },
    tengu: {
        damage_melee: 4,
        damage_range: "ns_ab:shuriken",
        spawnAnimation: true,
        tagAttack: "btAttack",
        music: 'boss_fight.it_has_awoken'
    },
    hanniya: {
        damage_melee: 5,
        damage_range: "ns_ab:shuriken",
        spawnAnimation: true,
        tagAttack: "bhAttack",
        music: 'boss_fight.it_has_awoken'
    },
    ganimedes: {
        damage_melee: 3,
        damage_range: "ns_ab:blank",
        spawnAnimation: false,
        tagAttack: "bgAttack",
        music: 'boss_fight.night_of_the_drowned'
    },
    raijin: {
        damage_melee: 6,
        damage_range: "ns_ab:blank",
        spawnAnimation: false,
        tagAttack: "brAttack",
        music: 'boss_fight.one_with_the_tribe'
    },
    freezing_wolf: {
        damage_melee: 6,
        damage_range: "ns_ab:blank",
        spawnAnimation: false,
        tagAttack: "aaaa",
        music: 'boss_fight.when_darkness_returns'
    },
    mother_spider: {
        damage_melee: 3,
        damage_range: "ns_ab:web",
        spawnAnimation: false,
        tagAttack: "bmsAttack",
        music: 'boss_fight.the_proving_grounds'
    },
    dragon_fire: {
        damage_melee: 3,
        damage_range: "ns_ab:fireball",
        spawnAnimation: false,
        tagAttack: "aaaa",
        music: 'boss_fight.the_proving_grounds'
    },
    necromancer_king: {
        damage_melee: 3,
        damage_range: "ns_ab:minion_zombie",
        spawnAnimation: false,
        tagAttack: "bnkAttack",
        music: 'boss_fight.dark_sorcerers'
    },
    mini_spider: {
        damage_melee: 3,
        damage_range: "ns_ab:blank",
        spawnAnimation: true,
        tagAttack: "msAttack",
        music: ''
    }
};

export const WEAPONS = {
    "ns_ab:red_katana": {
        damage:10,
        on_fire: true,
        timer: 3.25,
        item_cooldown:"red_katana",
        type_attack:{
            first_vision: {
                animation: "animation.ns_ab.red_katana.hit",
                vfx: "ns_ab:vfx_fire_1",
            },
            third_vision: {
                animation: "animation.ns_ab.red_katana.special",
                vfx: "ns_ab:vfx_fire_2",
            }
        },
    },
    "ns_ab:water_dual_blades": {
        damage: 8,
        on_fire: false,
        timer: 3.25,
        item_cooldown:"water_dual_blades",
        type_attack:{
            first_vision: {
                animation: "animation.ns_ab.blue_sword.hit",
                vfx: "ns_ab:vfx_water_1",
            },
            third_vision: {
                animation: "animation.ns_ab.blue_sword.special",
                vfx: "ns_ab:vfx_water_2",
            }
        },
    },
    "ns_ab:double_daggers": {
        damage: 7,
        on_fire: false,
        timer: 2.5,
        item_cooldown:"double_daggers",
        type_attack:{
            first_vision: {
                animation: "animation.ns_ab.double_daggers.attack",
                vfx: "ns_ab:vfx_dd_1",
            },
            third_vision: {
                animation: "animation.ns_ab.double_daggers.special",
                vfx: "ns_ab:vfx_dd_2",
            }
        },
    },
    "ns_ab:necromancer_sword": {
        damage: 15,
        on_fire: false,
        timer: 3,
        item_cooldown:"necromancer_sword",
        type_attack:{
            first_vision: {
                animation: "animation.ns_ab.necromancer_sword.attack",
                vfx: "ns_ab:vfx_nk_1",
            },
            third_vision: {
                animation: "animation.ns_ab.necromancer_sword.special",
                vfx: "ns_ab:vfx_nk_2",
            }
        },
    },
    "ns_ab:lighting_stick": {
        damage: 15,
        on_fire: false,
        timer: 3,
        item_cooldown: "lighting_stick",
        type_attack:{
            first_vision: {
                animation: "animation.ns_ab.lightning_stick.hit",
                vfx: "ns_ab:vfx_lighting_1",
            },
            third_vision: {
                animation: "animation.ns_ab.lightning_stick.special",
                vfx: "ns_ab:vfx_lighting_2",
            }
        },
    },
    "ns_ab:mothers_fang_dagger": {
        damage: 15,
        on_fire: false,
        timer: 3,
        item_cooldown: "mothers_fang_dagger",
        type_attack:{
            first_vision: {
                animation: "animation.ns_ab.mothers_fang_dagger.attack",
                vfx: "ns_ab:vfx_sd_1",
            },
            third_vision: {
                animation: "animation.ns_ab.lightning_stick.special",
                vfx: "ns_ab:vfx_lighting_1",
            }
        },
    }
}

export const WEAPONS_DATA = {}

/**
 *
 * @param {string} str
 * @returns {string}
 */
export function removerPrefixo(str) {
    let removes = ["v1", "v2", "  "];
    const indexDoisPontos = str.indexOf(":");
    if (indexDoisPontos !== -1) {
        let resultado = str.substring(indexDoisPontos + 1);
        for (const remove of removes) {
            resultado = resultado.replace(remove, " ");
        }
        resultado = resultado.charAt(0) + resultado.slice(1);
        return resultado;
    } else {
        return str;
    }
}

export function distance(source, victim) {
    let locationEntity = source.location;
    let locationVictim = victim.location;

    let dx = locationEntity.x - locationVictim.x;
    let dy = locationEntity.y - locationVictim.y;
    let dz = locationEntity.z - locationVictim.z;

    let distance = Math.sqrt(dx + dx * dy + dy * dz + dz);
    return distance;
}

export function launchEntity(
    projetil,
    source,
    target,
    strength,
    height,
    offset = { x: 0, y: 0, z: 0 }
) {
    const sourcePos = source.location;
    const targetPos = target.location;
  
    const dx = targetPos.x - sourcePos.x;
    const dz = targetPos.z - sourcePos.z;
    const distanceSquared = dx * dx + dz * dz;
  
    let ak = strength * (distanceSquared >= 64 ? 2.5 : (distanceSquared >= 9 ? 1.5 : 1));
  
    if (distanceSquared > 0) {
      const distance = Math.sqrt(distanceSquared);
      const directionX = dx / distance;
      const directionZ = dz / distance;
      const spawnPos = {
        x: sourcePos.x + offset.x,
        y: sourcePos.y + offset.y,
        z: sourcePos.z + offset.z,
      };
  
      let entity = source.dimension.spawnEntity(projetil, spawnPos);
      entity.addTag('projetil');
      entity.applyKnockback(directionX, directionZ, ak, height);
    }
}

/**
 *
 * @param {Entity|Player} source
 * @param {mc.EntityQueryOptions} options
 */
export function scanerMobs(source, options) {
    let entitys = source.dimension?.getEntities(options) ?? []
    return entitys
}

// Função para verificar se um bloco na posição dada é passável
function isPassableBlock(position, dimension) {
    const block = dimension.getBlock(position);
    return block && block.typeId === "minecraft:air";
}

// Função para spawnar uma entidade com ajuste de altura
function spawnEntityWithCheck(typeId, position, dimension,source) {
    if (isPassableBlock(position, dimension)) {
        dimension.spawnEntity(typeId, position).addTag(`${source.id}`);
        
    } else {
        position.y += 1;
        if (isPassableBlock(position, dimension)) {
            dimension.spawnEntity(typeId, position).addTag(`${source.id}`);
        } else {
            return false;
        }
    }
    return true;
}

function spawnEntityWithCheck2(typeId, position, dimension,source) {
    if (isPassableBlock(position, dimension)) {
        summon(dimension, typeId, position,source)
        
    } else {
        position.y += 1;
        if (isPassableBlock(position, dimension)) {
            summon(dimension, typeId, position,source)
        } else {
            return false;
        }
    }
    return true;
}

function summon(dimension, typeId, position, source) {
    let summon = dimension.spawnEntity(typeId, position);
    let projetil = summon.getComponent('minecraft:projectile');
    
    projetil.owner = source;
    summon.triggerEvent('transform')
}

function calculateDistance(start, end) {
    return Math.max(Math.abs(start.x - end.x), Math.abs(start.z - end.z));
}

export function spawnEntitiesInLine(typeId, startPosition, endPosition, player) {
    const dimension = player.dimension;
    const distance = calculateDistance(startPosition, endPosition);
    
    for (let i = 0; i <= distance; i++) {
        const currentPosition = {
            x: Math.round(startPosition.x + (endPosition.x - startPosition.x) * (i / distance)),
            y: startPosition.y,
            z: Math.round(startPosition.z + (endPosition.z - startPosition.z) * (i / distance)),
        };

        if (!spawnEntityWithCheck(typeId, currentPosition, dimension,player)) {
            break;
        }
    }
}

/**
 * 
 * @param {string[]} typeID 
 * @param {Entity} source 
 * @param {Entity} target 
 */
export function spawnRandomMinions(typeID, source, target) {
    const cont = 6;
    const dimension = source.dimension;
    for (let index = 0; index < cont; index++) {
        let offsetX = Math.floor(Math.random() * 10) - 5;
        let offsetZ = Math.floor(Math.random() * 10) - 5;
        let newLocation = {
            x: source.location.x + offsetX,
            y: source.location.y,
            z: source.location.z + offsetZ,
        }
        if (index%2 == 0){
            spawnEntityWithCheck(typeID[0],newLocation, dimension,source)
        } else {
            spawnEntityWithCheck(typeID[1],newLocation, dimension,source)
        }
    }
}

export function spawnRandomMinionsPlayer(typeID, source, target) {
    const cont = 3;
    const dimension = source.dimension;
    for (let index = 0; index < cont; index++) {
        let offsetX = Math.floor(Math.random() * 10) - 5;
        let offsetZ = Math.floor(Math.random() * 10) - 5;
        let newLocation = {
            x: source.location.x + offsetX,
            y: source.location.y,
            z: source.location.z + offsetZ,
        }
        if (index%2 == 0){
            spawnEntityWithCheck2(typeID[0],newLocation, dimension,source)
        } else {
            spawnEntityWithCheck2(typeID[1],newLocation, dimension,source)
        }
    }
}

export function getItem(source, ppk) {
    /**
     * @type {EntityEquippableComponent}
     */
    const componet = source.getComponent("minecraft:equippable");
    try {
        if (ppk)
            if (componet.getEquipment(EquipmentSlot.Offhand) != undefined)
                return componet.getEquipment(EquipmentSlot.Offhand);
            else return new ItemStack("minecraft:stick", 1);
        else {
            if (componet.getEquipment(EquipmentSlot.Mainhand) != undefined)
                return componet.getEquipment(EquipmentSlot.Mainhand);
            else return new ItemStack("minecraft:stick", 1);
        }
    } catch (error) {
        return new ItemStack("minecraft:stick", 1);
    }
};



export const dsEntity = [
    "overworld",
    "nether",
    "the_end"
]