import { world,system,MolangVariableMap,TicksPerSecond,ItemStack,Difficulty} from "@minecraft/server"
import { ancientShieldParry,bloodVial } from "../items/artifacts/artifacts.js";
import { getScore } from "../utils/score.js";
import { SpearsAnyAttack } from "../items/spears.js";

function isFamily(family,entity) {
    return entity?.getComponent('minecraft:type_family')?.hasTypeFamily(family)
  }

function getKnockbackValue(itemUsed) {
    var value = 1
    if(itemUsed?.getComponent('enchantable')?.getEnchantment("knockback")?.level>0)
        value = itemUsed?.getComponent('enchantable')?.getEnchantment("knockback")?.level*1.25
    return value
}

function getDamage(player,damage)
{
    if(player.hasTag('charged_hit_scroll'))
    {
        damage*=1.2
    }
    if(player.hasTag('chaining_scroll'))
    {
        damage*=(1+0.1*getScore(player,'Chaining'))
    }
    damage = Math.round(damage * 100) / 100 // 2 chiffres apres virgule 
    return damage
}

world.afterEvents.entityHurt.subscribe((ev) => {
    //try{
    var victim = ev?.hurtEntity
    var damage = ev?.damage
    var attacker = ev?.damageSource.damagingEntity
    var projectile = ev?.damageSource.damagingProjectile
    const dimension = victim?.dimension
    SpearsAnyAttack(victim,attacker)
    if(victim?.typeId=="minecraft:player" && attacker==undefined )
    {
        const block = dimension.getBlockFromRay(victim.location,{x:0,y:-1,z:0})?.block
        if(block?.permutation?.getState("edx:apply_damage")==true)
            victim.playSound('mob.player.hurt_on_fire');
    }
    if(isFamily('can_enrage', victim) && projectile?.typeId=="edx:red_runic_fireball" ){
        victim.triggerEvent('enrage')
    }
    if(victim.typeId == "edx:enlightened" ){
      victim.triggerEvent('invincible')
    }
    if(victim.typeId == "edx:blame_thrower" && projectile?.typeId=="edx:red_runic_fireball" ){
      victim.dimension.createExplosion(victim.location, 3, { breaksBlocks: false, causesFire: false })
      victim.kill()
    }
    if(victim.typeId=="edx:abomination" ||victim.typeId=="edx:abomination2")
        {
            if(Math.random()>=0.7)
            {
                var block = victim.dimension.getBlock(victim.location)
                if(block.typeId == "minecraft:water" || block.typeId == "minecraft:lava")
                {
                    const raycast = victim.dimension.getBlockFromRay({x:victim.location.x,y:victim.location.y+200,z:victim.location.z},{x:0,y:-1,z:0},{ maxDistance: 250})
                    if(raycast?.block?.typeId != undefined)
                    {
                        victim.tryTeleport(raycast?.block.above().center())
                        dimension.playSound('mob.endermen.portal', {x:victim.location.x ,y:victim.location.y,z:victim.location.z});
                    }
                }
                else 
                {
                    for (let i = 0; i <= 100 ; i++)
                    {
                        var x = Math.random()*20-10
                        var y = Math.random()*5
                        var z = Math.random()*20-10
                        const raycast = victim.dimension.getBlockFromRay({x:victim.location.x+x,y:victim.location.y+y,z:victim.location.z+z},{x:0,y:-1,z:0},{ maxDistance: 40})
                        if(victim.tryTeleport(raycast?.block.above().center(),{checkForBlocks:true}))
                        {
                            dimension.playSound('mob.endermen.portal', {x:victim.location.x ,y:victim.location.y,z:victim.location.z});
                            break
                        }
                        if(i>=100)
                        {
                            dimension.createExplosion(victim.location, 10, { breaksBlocks: true, causesFire: false,allowUnderwater:true,source:victim })
                            victim.addEffect('regeneration',40, { amplifier: 10, showParticles: true})
                            dimension.spawnParticle('minecraft:villager_angry',{x:victim.location.x ,y:victim.location.y+2,z:victim.location.z})
                        }
                    }
                    
                        
                    
                }
            }
        }
    if (attacker?.typeId === 'edx:fire_tornado') {
        victim.setOnFire(4, true);
                victim.applyKnockback({x:0, z:0}, 1.5)
    }
    if (attacker?.typeId === 'edx:soul_ground_tornado') {
        victim.setOnFire(5, true);
                victim.applyKnockback({x:0, z:0}, 1.5)
    }
    if (attacker?.typeId === 'edx:soul_laser') {
        victim.setOnFire(7, true);
    }
    if (attacker?.typeId === 'edx:fire_tornado') {
        victim.setOnFire(4, true);
                victim.applyKnockback({x:0, z:0}, 1.5)
    }
    if(victim.typeId == "edx:angry_skeleton")
    {
        victim.triggerEvent('unshield')
    }
    if(victim.typeId == "edx:baste" )
    {
        victim.applyKnockback({x:Math.random()*2-1,z: Math.random()*2-1}, -0.2)
    }
    if(victim.typeId == "edx:bondling" )
        {
            victim.applyKnockback({x:0,z:0}, -0.2)
        }
    if(attacker?.typeId == "minecraft:player" && attacker?.hasTag('void_armor'))
    {
        if((victim.getComponent("health").currentValue<20 && victim.typeId!="minecraft:player") || (victim.getComponent("health").currentValue<6 && victim.typeId=="minecraft:player"))
        {
            victim.kill()
            
        }
    }
    if (isFamily('mob', victim) === true && attacker?.typeId === 'minecraft:player' && attacker?.hasTag("blood_vial")) {
        bloodVial(attacker,damage,victim)
    }
    if(victim.typeId == "minecraft:player" && attacker!=undefined)
        ancientShieldParry(attacker,victim,damage) //also void cloak artifact
        
    if(victim.typeId == "edx:training_dummy")
    {
        victim.addEffect('regeneration', 5, { amplifier: 200, showParticles: false})
        victim.nameTag = Math.round(Math.round(damage * 100) / 100).toString()
        victim.triggerEvent('show')
        system.runTimeout(() => {
            victim.triggerEvent('stop_show')
            victim.nameTag =""
        }, TicksPerSecond);
    }

    if (projectile != undefined && attacker != undefined){
        if (projectile.typeId === 'edx:fire_strike') {
            victim.setOnFire(4, true);
        }
    }
    if(victim.typeId == "edx:gloopine")
        {
            if(victim.getComponent('variant')?.value==0)
            {
                victim.triggerEvent('go_fat')
            }
            else{
                dimension.spawnParticle('edx:gloopine_explode',victim.location)
                dimension.createExplosion(victim.location, 4, { breaksBlocks: false, causesFire: false })
                victim.runCommand(`loot spawn  ~~~ loot gloopine`)
                victim.remove()
            }
        }
        if(victim.typeId == "edx:gloop_ball")
            {
                if(victim.getComponent('variant')?.value==0)
                {
                    victim.triggerEvent('go_fat')
                }
                else{
                    dimension.spawnParticle('edx:gloopine_explode',victim.location)
                    dimension.createExplosion(victim.location, 4, { breaksBlocks: false, causesFire: false })
                    victim.remove()
                }
            }
    if (attacker != undefined){
        if (attacker.typeId === 'minecraft:player' && attacker.hasTag("explosive_blaze_rod") && victim.getComponent("minecraft:onfire")) {
            system.runTimeout(() => {
                var entities = victim.dimension.getEntities({
                    location: { x: victim.location.x, y: victim.location.y, z: victim.location.z },
                    maxDistance: 0.5,
                });
                victim.runCommand(`particle edx:blazeblade_explosion ~~1~`)
                for (let entity of entities) {
                    entity.applyDamage(5,{
                        cause: "fire" ,
                    },)
                    entity.applyKnockback({x:0,z:0},0.5);
                entity.extinguishFire()
                };
                
            },20)
        }
        
        //sword sweep attack
        else if(attacker?.typeId === 'minecraft:player' && attacker?.getComponent('equippable')?.getEquipment('Mainhand')?.hasTag('minecraft:is_sword'))
            {
                const player = attacker;
                if( getScore(player,'Hit_cooldown')<=1 && !player.isSprinting && player.isOnGround)
                    {
                        const itemUsed = player?.getComponent('equippable')?.getEquipment('Mainhand')
                        let fireAspectLevel = itemUsed?.getComponent('enchantable')?.getEnchantment("fire_aspect")?.level ?? 0
                        var entitiesCircle = world.getDimension(player.dimension.id).getEntities({
                            excludeTypes: ["minecraft:item"],
                            excludeFamilies:["inanimate"],
                            families:["mob"],
                            location: victim.location, 
                            maxDistance: 2,
                        });
                        entitiesCircle.forEach(entity=>
                            {
                                if(victim.typeId != "minecraft:player" || world.gameRules.pvp==true)
                                    if(victim!=entity && entity!=player && entity?.typeId!="minecraft:xp_orb" && entity?.typeId!="minecraft:item" && entity?.typeId!="minecraft:arrow")
                                        {
                                            
                                            entity?.applyKnockback({x:player?.getViewDirection()?.x* Math.sqrt(player?.getViewDirection()?.x ** 2 + player?.getViewDirection()?.z ** 2)*getKnockbackValue(itemUsed),z: player?.getViewDirection()?.z* Math.sqrt(player.getViewDirection()?.x ** 2 + player?.getViewDirection()?.z ** 2)*getKnockbackValue(itemUsed)}, 0.5)
                                            entity.applyDamage(getDamage(player,damage)/3,{cause: "entityAttack",damagingEntity:player})
                                            entity.setOnFire(fireAspectLevel*4)
                                        }
                            }
                        )
                        const particleLocation = {x:player.getHeadLocation().x+player.getViewDirection().x ,y:player.getHeadLocation().y+player.getViewDirection().y-0.4 ,z:player.getHeadLocation().z+player.getViewDirection().z} 
                        world.getDimension(player.dimension.id).spawnParticle("edx:sweep_attack", particleLocation)
                        world.getDimension(player.dimension.id).playSound('vr.stutterturn', player.location);
                        if(player.hasTag('charged_hit_scroll'))
                        {
                            const power = Math.sqrt(player.getViewDirection().x ** 2 + player.getViewDirection().z ** 2)*2
                            player.applyKnockback({x:-player.getViewDirection().x*power,z: -player.getViewDirection().z*power}, 0.5)
                        }
                        if(player.hasTag('charged_hit_scroll') || player.hasTag('chaining_scroll'))
                            victim?.applyDamage(getDamage(player,damage)/3,{cause: "entityAttack",damagingEntity:player})
                        if(player.hasTag('uppercut_scroll') && !victim.dimension.getBlock({x:victim.location.x,y:victim.location.y-0.5,z:victim.location.z}).isAir)
                        {
                            world.getDimension(victim.dimension.id).spawnParticle('edx:uppercut',victim.location);
                            victim.clearVelocity()
                            victim.applyKnockback({x:0,z:0}, 0.5)
                        }
                            
                    }
                    
                    if(player.hasTag('crushing_scroll') && victim.dimension.getBlock({x:victim.location.x,y:victim.location.y-0.5,z:victim.location.z}).isAir)
                        {
                            world.getDimension(victim.dimension.id).spawnParticle('edx:uppercut',victim.location);
                            victim?.applyKnockback({x:0,z:0}, -0.7)
                            victim.applyDamage(getDamage(player,damage)/3,{cause: "entityAttack",damagingEntity:player})
                        }
                    if(player.hasTag('chaining_scroll') && (isFamily('monster', victim) === true || isFamily('mob', victim) === true))
                    {
                        if(getScore(player,'Chaining')<6)
                        {
                            world.getDimension(victim.dimension.id).spawnParticle('edx:chaining_particle',victim.getHeadLocation());
                            player.runCommand(`scoreboard players add @s Chaining 1`)
                        }
                    }
                        player.runCommand(`scoreboard players set @s Hit_cooldown 10`)

                     
            }
            
            if(attacker?.typeId === 'minecraft:player')
            {
                
                
            }
        }
        if(victim.typeId === 'minecraft:player')
        {
            var player = victim
            if(getScore(player,'Chaining')>0)
            {
                const vmap = new MolangVariableMap();
                vmap.setFloat('variable.amount', getScore(victim,'Chaining'));
                world.getDimension(victim.dimension.id).spawnParticle('edx:chaining_hurt_particle',victim.getHeadLocation(),vmap);
                player.runCommand(`scoreboard players set @s Chaining 0`)
            }
        }


    

    //}
    //catch(e){}
})

