import { system, world } from '@minecraft/server';

world.afterEvents.entityHitEntity.subscribe(event => {
    const attacker = event.damagingEntity;
    const hitEntity = event.hitEntity;

    if (attacker.typeId !== 'nb:zodd') {
        return;
    }

    const randomNumber = Math.random();

    if (randomNumber < 0.25) {
        especial(attacker, hitEntity);

    } else if (randomNumber < 0.50) {
        attacker.runCommandAsync("playanimation @s animation.zodd.stab");
        hitEntity.runCommandAsync("particle nb:ataque_forte ~ ~1.2 ~");

        const knockbackStrengthH = 3;
        const knockbackStrengthV = 0.2;
        const viewDirection = attacker.getViewDirection();

        hitEntity.applyKnockback(
            viewDirection.x,
            viewDirection.z,
            knockbackStrengthH,
            knockbackStrengthV
        );
    } else {
        attacker.runCommandAsync("playanimation @s animation.zodd.attack");
    }
});

function especial(attacker, hitEntity) {
    system.runTimeout(() => {
        attacker.addTag("zodd_esp"); 
        attacker.runCommandAsync("playanimation @s animation.zodd.cortes");
        attacker.runCommandAsync("playsound zodd1_especial @a[r=20]");
    }, 1);

    const applyAreaDamage = (damageAmount, tickDelay) => {
        system.runTimeout(() => {
            if (!attacker.isValid()) return;
            attacker.runCommandAsync(`damage @e[tag=!zodd_esp,r=5] ${damageAmount} entity_attack entity @s`);
        }, tickDelay);
    };

    applyAreaDamage(1, 3);
    applyAreaDamage(1, 5);
    applyAreaDamage(1, 8);
    applyAreaDamage(1, 14);
    applyAreaDamage(1, 20);
    applyAreaDamage(1, 22);
    applyAreaDamage(1, 27);
    applyAreaDamage(1, 33);
    applyAreaDamage(1, 36);
    applyAreaDamage(6, 39); 

    system.runTimeout(() => {
        if (!attacker.isValid()) return; 

        attacker.removeTag("zodd_esp");

        const knockbackStrengthHesp = 3;
        const knockbackStrengthVesp = 0.3;
        const viewDirection = attacker.getViewDirection();

            const affectedEntities = attacker.dimension.getEntities({
            location: attacker.location,
            maxDistance: 5,
            excludeTags: ["zodd_esp"]
        });

        for (const entity of affectedEntities) {
            entity.applyKnockback(
                viewDirection.x,
                viewDirection.z,
                knockbackStrengthHesp,
                knockbackStrengthVesp
            );
        }

    }, 40);
}

/**
 *
 * @param {import('@minecraft/server').Entity} zodd
 */
async function transform(zodd) { 
    if (!zodd.isValid()) return; 

    zodd.runCommandAsync("playsound zodd_ost @a[r=10]");
    zodd.addTag("cutcine");
    zodd.runCommandAsync("effect @s invisibility 255 255 true");
    zodd.runCommandAsync("effect @s resistance 255 255 true");
    zodd.runCommandAsync("effect @s fire_resistance 255 255 true");
    
    zodd.runCommandAsync("summon nb:zodd_cut ~~~");
    
    await system.runTimeout(() => {}, 1);

    const zoddcutEntities = zodd.dimension.getEntities({
        type: 'nb:zodd_cut',
        location: zodd.location,
        maxDistance: 3,  
        closest: 1      
    });

    const zoddcut = zoddcutEntities[0]; 

    if (!zoddcut) {
        console.warn("Não foi possível encontrar a entidade 'nb:zodd_cut' para a transformação.");
        zodd.removeTag("cutcine");
        return;
    }
    
    zoddcut.addTag("cutcine");
    zoddcut.runCommandAsync("playanimation @s animation.zodd.transform");
    zoddcut.runCommandAsync("playsound zodd_transform @a[r=20]");

    system.runTimeout(() => {
        
    zodd.runCommandAsync("playanimation @e[tag=cutcine,r=5] animation.zodd.transform"); 
    
        const loop1 = system.runInterval(() => {
            if (!zodd.isValid()) { system.clearInterval(loop1); return; }
            zodd.runCommandAsync("title @a[r=20] actionbar §oThroughout my three hundred years of slaughtering, you are the first...");
        }, 10);
        system.runTimeout(() => { system.clearInterval(loop1); }, 118);
        zoddcut.addTag("cutcine");
        zodd.addTag("cutcine");
    }, 20);

    system.runTimeout(() => {
        const loop2 = system.runInterval(() => {
            if (!zodd.isValid()) { system.clearInterval(loop2); return; }
            zodd.runCommandAsync("title @a[r=20] actionbar §o...who has stabbed me like this.");
        }, 10);
        system.runTimeout(() => { system.clearInterval(loop2); }, 50);
    }, 140);

    system.runTimeout(() => {
        if (!zodd.isValid()) return;
        zodd.runCommandAsync("camera @a[r=20] fade time 0.5 3 1 color 0 0 0");
        zodd.runCommandAsync("title @a[r=20] title §o「血と鋼に飢えている」");
        zodd.runCommandAsync("title @a[r=20] subtitle Hungering for blood and steel");
        zodd.runCommandAsync("particle nb:red_smoke ~ ~1.1 ~");
        zodd.runCommandAsync("particle nb:red_smoke ~ ~1.3 ~");
        zodd.runCommandAsync("effect @e[tag=cutcine,r=5] invisibility 255 255 true");
        zoddcut.runCommandAsync("effect @s invisibility 255 255 true");
        zodd.runCommandAsync("summon nb:zodd_apostle ~~~"); 
    }, 199);

    system.runTimeout(() => {
        world.getDimension("overworld").runCommandAsync("tag @e[type=nb:zodd_apostle,r=5,c=1] add fase2");
        world.getDimension("overworld").runCommandAsync("playanimation @e[type=nb:zodd_apostle,tag=fase2] animation.zoddapostle.roar");
        world.getDimension("overworld").runCommandAsync("playsound zodd_roar @a[r=10]");
        zoddcut.runCommandAsync("tp @s ~ ~-100 ~");
        zodd.runCommandAsync("tp @s ~ ~-100 ~");
        world.getDimension("overworld").runCommandAsync("tag @e[tag=fase2,r=10] remove fase2");
    }, 260);

    system.runTimeout(() => {

        if (zodd.isValid()) {
            zodd.kill(); 
        }
        if (zoddcut.isValid()) {
            zoddcut.kill();
        }
    }, 265);
}

system.runInterval(() => {
    const zoddEntities = world.getDimension("overworld").getEntities({ type: 'nb:zodd' });
    const zoddcutEntities = world.getDimension("overworld").getEntities({ type: 'nb:zodd_cut' });

    for (const zodd of zoddEntities) {
        
   const health = zodd.getComponent('health');
        if (health) { 
            if (health.currentValue <= 200 && !zodd.hasTag('cutcine')) {
                transform(zodd); 
            }
        }        
        if (zodd.hasTag('cutcine')) {
            zodd.runCommandAsync("tp @s @s");
        }    

        if (zodd.hasTag('zodd_esp')) {
            zodd.runCommandAsync("particle nb:zodd_cortes ^ ^1.4 ^0.9");
            continue;
        }

        const velocity = zodd.getVelocity();
        const horizontalVelocity = Math.sqrt(velocity.x ** 2 + velocity.z ** 2);

        if (horizontalVelocity > 0.08) {
            zodd.runCommandAsync("playanimation @s[tag=!cutcine] animation.zodd.walk");
        } else {
            zodd.runCommandAsync("playanimation @s[tag=!cutcine] animation.zodd.idle");
        }
    }
    
        for (const zoddcut of zoddcutEntities) {
            
     if (zoddcut.hasTag('cutcine')) {
            zoddcut.runCommandAsync("tp @s @s");
        }            
   }
}, 10); 