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

const config_bainha = [
    { id: "nb:dragon_slayer", eventBack: "nb:ds_back", eventHide: "nb:ds_noback" },
    { id: "nb:long_sword", eventBack: "nb:ls_back", eventHide: "nb:ls_noback" },
    { id: "nb:reinforced_sword", eventBack: "nb:rs_back", eventHide: "nb:rs_noback" },
];

system.runInterval(() => {
    for (const player of world.getAllPlayers()) {
        const inv = player.getComponent("inventory").container;
        const equ = player.getComponent("equippable");
        const mao = equ.getEquipment("Mainhand");
        const slot9 = inv.getItem(8); 

        config_bainha.forEach(sword => {
            const is_main = mao?.typeId === sword.id;
            const is_slot9 = slot9?.typeId === sword.id;

            if (is_slot9 && !is_main) {
                if (!player.hasTag(`back_${sword.id}`)) {
                    player.triggerEvent(sword.eventBack);
                    player.addTag(`back_${sword.id}`);
                }
            } else {
                if (player.hasTag(`back_${sword.id}`)) {
                    player.triggerEvent(sword.eventHide);
                    player.removeTag(`back_${sword.id}`);
                }
            }
        });
    }
}, 5); 

const dados_espada = {
    'nb:long_sword': { tag: 'cd_ls', a1: 'animation.long_sword.attack1', a2: 'animation.long_sword.attack2', sk: 'animation.long_sword.skill', p: 'nb:corte', s: 'rapier_corte', dmg: 9.6, cd: 180, r: 5 },
    'nb:reinforced_sword': { tag: 'cd_rs', a1: 'animation.long_sword.attack1', a2: 'animation.long_sword.attack2', sk: 'animation.long_sword.skill', p: 'nb:corte', s: 'rapier_corte', dmg: 12.0, cd: 200, r: 5 },
    'nb:rapier': { tag: 'cd_rp', a1: 'animation.rapier.attack1', a2: 'animation.rapier.attack2', sk: 'animation.rapier.skill', p: 'nb:corte', s: 'rapier_corte', dmg: 8.0, cd: 150, r: 4 }
};

world.afterEvents.itemUse.subscribe(event => {
    const player = event.source;
    const item_id = event.itemStack.typeId;

    if (item_id === 'nb:dragon_slayer') {
        if (player.hasTag('ds_charging') || player.hasTag('berserk_acting')) return;
        if (player.hasTag('Berserk') && !player.hasTag('ds_spin_c') && !player.isSneaking) {
            ds_spin(player);
        } else if (player.isSneaking && !player.hasTag('ds_heavy_cooldown')) {
            ds_charge(player);
        } else if (!player.isSneaking && !player.hasTag('ds_quick_cooldown') && !player.hasTag('ds_quick_active')) {
            ds_stomp(player);
        }
        return;
    }

    const cfg = dados_espada[item_id];
    if (cfg && !player.hasTag(cfg.tag) && !player.hasTag('nb:casting')) {
        const dir = player.getViewDirection();
        player.addTag('nb:casting');

        if (item_id === 'nb:rapier') {
            player.applyKnockback(dir.x, dir.z, 3.5, 0.2);
        }

        player.runCommandAsync("inputpermission set @s movement disabled");
        player.runCommandAsync("inputpermission set @s camera disabled");
        player.runCommandAsync(`playanimation @s ${cfg.sk}`);
        player.runCommandAsync(`playsound corte @a ~ ~ ~ 1 1.2`);
        
        system.runTimeout(() => {
            if (!player.isValid()) return;
            player.addTag(cfg.tag);
            player.runCommandAsync("inputpermission set @s movement enabled");
            player.runCommandAsync("inputpermission set @s camera enabled");
            player.removeTag('nb:casting');
            
            const targets = player.dimension.getEntities({ location: player.location, maxDistance: cfg.r });
            for (const ent of targets) {
                if (ent.id !== player.id) {
                    ent.applyDamage(cfg.dmg, { cause: 'entityAttack', damagingEntity: player });
                    ent.applyKnockback(dir.x, dir.z, 2, 0.3);
                    ent.runCommandAsync("particle nb:varios_cortes ^ ^1.2 ^");
                }
            }
        }, 8);
        system.runTimeout(() => { if (player.isValid()) player.removeTag(cfg.tag); }, cfg.cd);
    }
});

function ds_stomp(player) {
    const dir = player.getViewDirection();
    player.addTag('ds_quick_active'); 
    player.applyKnockback(0, 0, 0, 0.4); 
    player.runCommandAsync("playanimation @s animation.dragonslayer.skill");
    player.runCommandAsync("particle nb:dragon_cut ~ ~ ~");
    system.runTimeout(() => {
        if (!player.isValid()) return;
        const entities = player.dimension.getEntities({ location: player.location, maxDistance: 4 });
        for (const ent of entities) {
            if (ent.id === player.id) continue;
            ent.applyDamage(5.5, { cause: 'entityAttack', damagingEntity: player });
            player.runCommandAsync("particle nb:dragon_cut ~ ~2.5 ~");
            ent.applyKnockback(dir.x, dir.z, 0.3, 0.5);
        }
        player.removeTag('ds_quick_active');
        player.addTag('ds_quick_cooldown');
        system.runTimeout(() => { if (player.isValid()) player.removeTag('ds_quick_cooldown'); }, 120);
    }, 10);
}

function ds_spin(player) {
    player.addTag("berserk_acting");
    player.addTag("ds_spin_c");
    player.runCommandAsync("inputpermission set @s movement disabled");
    player.runCommandAsync("clear @s nb:dragon_slayer 0 1");
    player.runCommandAsync("event entity @s nb:ds_spin");
    player.runCommandAsync("playanimation @s animation.ds.spin");
    player.runCommandAsync("particle nb:ds_charge ~ ~0.1 ~");
    system.runTimeout(() => {
        if (!player.isValid()) return;
        const dir = player.getViewDirection();
        player.applyKnockback(dir.x, dir.z, 7.5, 0.3);
        const entities = player.dimension.getEntities({ location: player.location, maxDistance: 9 });
        for (const ent of entities) {
            if (ent.id === player.id) continue;
            ent.applyDamage(20, { cause: 'entityAttack', damagingEntity: player });
            player.runCommandAsync(`playsound clang @a ~ ~ ~`);    
            ent.runCommandAsync("particle nb:corte ^ ^1 ^");
        }
    }, 25);
    system.runTimeout(() => {
        if (!player.isValid()) return;
        player.runCommandAsync("event entity @s nb:ds_spin_no");
        player.runCommandAsync("give @s nb:dragon_slayer 1");
        player.runCommandAsync("inputpermission set @s movement enabled");
        player.removeTag("berserk_acting");
    }, 79);
    system.runTimeout(() => {
        if (player.isValid()) player.removeTag("ds_spin_c");
    }, 200);
}

function ds_charge(player) {
    player.addTag('ds_charging');
    player.runCommandAsync("playanimation @s animation.dragonslayer.charge");
    let t = 0;
    const task = system.runInterval(() => {
        if (!player.isValid() || !player.isSneaking) { 
            system.clearRun(task); 
            if (player.isValid()) player.removeTag('ds_charging'); 
            return; 
        }
        if (++t >= 40) {
            system.clearRun(task);
            ds_heavy_hit(player);
        }
    }, 1);
}

function ds_heavy_hit(player) {
    player.runCommandAsync("particle nb:ds_charge ~ ~0.1 ~");
    player.runCommandAsync("playanimation @s animation.dragonslayer.charge_complet");
    system.runTimeout(() => {
        if (!player.isValid()) return;
        const entities = player.dimension.getEntities({ location: player.location, maxDistance: 5 });
        for (const ent of entities) {
            if (ent.id !== player.id) ent.applyDamage(16, { cause: 'entityAttack', damagingEntity: player });
        }
        player.removeTag('ds_charging');
        player.addTag('ds_heavy_cooldown');
        system.runTimeout(() => { if (player.isValid()) player.removeTag('ds_heavy_cooldown'); }, 200);
    }, 20);
}

world.afterEvents.entityHitEntity.subscribe(event => {
    const attacker = event.damagingEntity;
    const target = event.hitEntity;
    if (!(attacker instanceof Player)) return;
    const item = attacker.getComponent('equippable').getEquipment('Mainhand');
    
    const cfg = dados_espada[item?.typeId];
    if (cfg) {
        const dir = attacker.getViewDirection();
        attacker.runCommandAsync(`playanimation @s ${Math.random() > 0.5 ? cfg.a1 : cfg.a2}`);
        target.applyKnockback(dir.x, dir.z, 0.4, 0);
        attacker.runCommandAsync(`playsound ${cfg.s} @a ~ ~ ~ 1 1.2`);
        target.runCommandAsync(`particle ${cfg.p} ^ ^1.2 ^0.3`);
        return;
    }

    if (item?.typeId === 'nb:dragon_slayer') {
        const dir = attacker.getViewDirection();
        attacker.runCommandAsync(`playanimation @s animation.dragonslayer.atk${Math.random() > 0.5 ? '1' : '2'}`);
        target.applyKnockback(dir.x, dir.z, 0.6, 0);
        attacker.runCommandAsync(`playsound clang @a ~ ~ ~ 0.9 1.2`);
        target.runCommandAsync("particle nb:corte ^ ^1.2 ^0.3");
    }
});