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

function voice(griffith) {
    const voices = ["griffith.voice2", "griffith.voice4"];
    const sorteio = Math.floor(Math.random() * voices.length); 
    const falaescolhida = voices[sorteio];
    griffith.runCommandAsync(`playsound ${falaescolhida} @a[r=15] ~ ~ ~`);
}

function aplicarAtordoar(entity) {
    if (!entity.isValid() || entity.hasTag("processando_atordoamento")) return;

    entity.addTag("atordoado");
    entity.addTag("processando_atordoamento");
    
    entity.runCommandAsync("inputpermission set @s movement disabled");
    entity.runCommandAsync("inputpermission set @s sneak disabled");
    entity.addEffect("slowness", 40, { amplifier: 10, showParticles: false });

    system.runTimeout(() => {
        if (entity.isValid()) {
            entity.runCommandAsync("inputpermission set @s movement enabled");
            entity.runCommandAsync("inputpermission set @s sneak enabled");
            entity.removeTag("atordoado");
            entity.removeTag("processando_atordoamento");
        }
    }, 40); 
}

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

    if (hitEntity.typeId === 'nb:griffith') {
        const parryChance = Math.random();
        if (parryChance < 0.05) {
            executarParry(hitEntity, attacker);
            return;
        }

        const dist = Math.sqrt(
            Math.pow(attacker.location.x - hitEntity.location.x, 2) + 
            Math.pow(attacker.location.z - hitEntity.location.z, 2)
        );

        if (!hitEntity.hasTag("cooldown_esquiva") && dist < 4 && Math.random() < 0.30) {
            executarEsquiva(hitEntity, attacker);
        }
        return;
    }

    if (attacker.typeId === 'nb:griffith') {
        const attackChoice = Math.random();

        if (attackChoice < 0.11) {
            skill(attacker, hitEntity);
        } else {
            const anim = attackChoice < 0.50 ? "animation.griffith.atk1" : "animation.griffith.atk2";
            attacker.runCommandAsync("tag @s add atk");  
            attacker.runCommandAsync(`playanimation @s ${anim}`);
            attacker.dimension.playSound("corte", attacker.location, { volume: 1, pitch: 1.2 });
            hitEntity.runCommandAsync("particle nb:corte ~ ~1.2 ~");
            
            if (Math.random() < 0.20) {
                voice(attacker);
            }
            system.runTimeout(() => {    
                if (attacker.isValid()) {
                    attacker.runCommandAsync("tag @s remove atk");
                }
            }, 10);         
        }
    }
});

function executarParry(griffith, attacker) {
    griffith.runCommandAsync("tag @s add parry");
    griffith.runCommandAsync("inputpermission set @s movement disabled"); 

    griffith.runCommandAsync("playanimation @s animation.griffith.parry");
    griffith.runCommandAsync("playsound griffith.voice @a[r=8] ~~~");
    
    system.runTimeout(() => {
        if (!griffith.isValid()) return;
        griffith.runCommandAsync("playanimation @s animation.griffith.parry2");
        griffith.runCommandAsync("particle nb:parry ^ ^1.1 ^0.5");
        
        if (attacker && attacker.isValid()) {
            if (attacker.typeId === "minecraft:player") {
                attacker.runCommandAsync("title @s actionbar §4Griffith Parry!");
                attacker.playSound("random.break", { pitch: 1.5 });
                aplicarAtordoar(attacker);
            } else {
                attacker.addTag("atordoado");
                attacker.addEffect("slowness", 40, { amplifier: 10 });
                system.runTimeout(() => {
                    if (attacker.isValid()) attacker.removeTag("atordoado");
                }, 40);
            }
        }
        griffith.runCommandAsync("inputpermission set @s movement enabled");
        griffith.runCommandAsync("tag @s remove parry"); 
    }, 20);
}

function executarEsquiva(griffith, attacker) {
    if (!griffith.isValid()) return;
    griffith.runCommandAsync("tag @s add esquiva");  
    griffith.addTag("cooldown_esquiva");
    griffith.dimension.playSound("fall.big", griffith.location, { volume: 1, pitch: 1.5 });
    
    const viewDir = griffith.getViewDirection();
    griffith.runCommandAsync("playsound griffith.voice3 @a[r=8] ~~~");
    griffith.runCommandAsync("playanimation @s animation.griffith.esquiva");
    griffith.runCommandAsync("particle nb:dash ^ ^1.4 ^");
    griffith.applyKnockback(viewDir.x * -1, viewDir.z * -1, 1.9, 0.3);

    system.runTimeout(() => {
        if (griffith.isValid()) { 
            griffith.removeTag("cooldown_esquiva");
            griffith.runCommandAsync("tag @s remove esquiva");   
        }
    }, 60);
}

function skill(attacker, hitEntity) {
    if (!attacker.isValid()) return;
    const raio = 5;
    const viewDirection = attacker.getViewDirection();

    attacker.addTag('rapier_fly_g');
    attacker.runCommandAsync("playanimation @s animation.rapier.skill");
    attacker.dimension.playSound("rapierfly", attacker.location, { volume: 1, pitch: 1.2 });
    attacker.applyKnockback(viewDirection.x, viewDirection.z, 7.5, 0);

    system.runTimeout(() => {
        if (!attacker.isValid()) return;
        const targets = attacker.dimension.getEntities({
            location: attacker.location,
            maxDistance: raio,
            excludeTags: ['rapier_fly_g']
        });

        for (const entity of targets) {
            if (entity.id === attacker.id) continue;
            entity.applyDamage(10, { cause: 'entityAttack', damagingEntity: attacker });
            entity.applyKnockback(viewDirection.x, viewDirection.z, 2, 0.3);
            entity.runCommandAsync("particle nb:varios_cortes ~ ~1.2 ~");
        }
        attacker.removeTag('rapier_fly_g');
    }, 5);
}

system.runInterval(() => {
    const griffiths = world.getDimension("overworld").getEntities({ type: 'nb:griffith' });
    for (const g of griffiths) {
        if (!g.isValid()) continue;
        const vel = g.getVelocity();
        const speed = Math.sqrt(vel.x ** 2 + vel.z ** 2);
        if (speed > 0.02) { 
       g.runCommandAsync("playanimation @s[tag=!parry,tag=!esquiva,tag=!atk] animation.griffith.walk");
        } else {
            g.runCommandAsync("playanimation @s[tag=!parry,tag=!esquiva,tag=!atk] animation.griffith.idle");
        }
    }
}, 5);