// espada_combos.js – ESPADA HUMANA (com eventos de dano em área via behavior pack)
import { world, system, EquipmentSlot } from "@minecraft/server";

const lastValidHit = new Map();
const combo4Cooldown = new Map();
const comboTimeouts = new Map();
const danoRemoveTimeouts = new Map(); // Novo: para cancelar remoção prematura no combo 4

const MIN_TICKS_BETWEEN_HITS = 10; // 0.5s entre hits
const COMBO4_COOLDOWN_TICKS = 100; // 5s de cooldown após combo 4

export function enableEspadaCombos() {
    function temEspada(player) {
        const equip = player.getComponent("minecraft:equippable");
        if (!equip) return false;
        const item = equip.getEquipment(EquipmentSlot.Mainhand);
        return item?.typeId === "well:espada_humano";
    }

    function getScore(player, obj) {
        try {
            return world.scoreboard.getObjective(obj)?.getScore(player) ?? 0;
        } catch {
            return 0;
        }
    }

    function limparCamera(player, combo = 0) {
        try { player.runCommand("camera @s clear"); } catch {}
        try { player.runCommand("scoreboard players set @s combo 0"); } catch {}

        // Remove knockback após 2s se não for combo 4
        if (combo !== 4) {
            system.runTimeout(() => {
                try { player.runCommand("event entity @s remove_knockback"); } catch {}
            }, 40);
        }
    }

    // Nova função: aplica evento de dano e agenda remoção após 20 ticks (1s)
    function ativarDanoArea(player, eventoDano) {
        // Remove qualquer dano anterior pendente
        try { player.runCommand("event entity @s remove_danos"); } catch {}

        // Cancela remoção anterior se existir
        if (danoRemoveTimeouts.has(player.id)) {
            danoRemoveTimeouts.get(player.id)();
            danoRemoveTimeouts.delete(player.id);
        }

        // Aplica o novo dano em área
        try { player.runCommand(`event entity @s ${eventoDano}`); } catch {}

        // Agenda remoção após 1 segundo (exceto se for combo 4, que trata separado)
        const timeout = system.runTimeout(() => {
            try { player.runCommand("event entity @s remove_danos"); } catch {}
            danoRemoveTimeouts.delete(player.id);
        }, 20);

        danoRemoveTimeouts.set(player.id, () => system.clearRun(timeout));
    }

    // FUNÇÃO COMUM PRA PROCESSAR HIT
    function processarHit(player) {
        const agora = system.currentTick;
        const cooldownEnd = combo4Cooldown.get(player.id);
        if (cooldownEnd && agora < cooldownEnd) return;

        const ultimoHit = lastValidHit.get(player.id) || 0;
        if (agora - ultimoHit < MIN_TICKS_BETWEEN_HITS) return;

        lastValidHit.set(player.id, agora);

        const furia = getScore(player, "furia");
        if (furia <= 0) return;

        if (comboTimeouts.has(player.id)) {
            comboTimeouts.get(player.id)();
            comboTimeouts.delete(player.id);
        }

        player.runCommand("scoreboard players add @s combo 1");
        player.runCommand("event entity @s add_knockback");
        player.runCommand("scoreboard players set @s stamina_player 0");
        player.runCommand("scoreboard players set @s animacao_esquiva 0");
        player.runCommand("scoreboard players remove @s[scores={combo=3..}] furia 1");
        player.runCommand("scoreboard players set @s[scores={combo=5..}] combo 0");

        const cmds = [
            "effect @s[scores={combos_animacoes=1,combo=1,furia=1..}] weakness 2 30 true",
            "effect @s[scores={combos_animacoes=1,combo=1,furia=1..}] resistance 7 50 true",
            "execute as @s[scores={combos_animacoes=1,combo=4..5,furia=1..}] at @s run effect @s speed 3 4 true",
            "playanimation @s[scores={combos_animacoes=1,combo=1,furia=1..}] animation.machadao.humano.combo1",
            "playanimation @s[scores={combos_animacoes=1,combo=2,furia=1..}] animation.machadao.humano.combo2",
            "playanimation @s[scores={combos_animacoes=1,combo=3,furia=1..}] animation.machadao.humano.combo3",
            "playanimation @s[scores={combos_animacoes=1,combo=4,furia=1..}] animation.machadao.humano.combo4",
            "playanimation @s[scores={combos_animacoes=1,combo=4,furia=1..}] animation.humano_guerreiro.ataque_counter",
            "camerashake add @s[scores={combos_animacoes=1,combo=4,furia=1..}] 0.3 3.4 positional",
            "execute as @s[scores={combos_animacoes=1,combo=4..5,furia=1..}] at @s run hud @s hide status_effects",
            "execute as @s[scores={combos_animacoes=1,combo=4..5,furia=1..}] at @s run camera @s set well:camera_rpg",
            "camerashake add @s[scores={furia=1..}] 0.2 0.3 positional",
            "execute as @s[scores={combos_animacoes=1,combo=1..3,furia=1..}] at @s run playsound mob.boss2.espadas @a ~ ~ ~ 0.3 2",
            "execute as @s[scores={combos_animacoes=1,combo=4..5,furia=1..}] at @s run playsound combos.espada @a ~ ~ ~ 1",
            "execute as @s[scores={genero=2,combos_animacoes=1,combo=1..3,furia=1..}] at @s run playsound player.female.attack @a ~ ~ ~ 1",
            "execute as @s[scores={genero=2,combo=4,furia=1..}] at @s run playsound player.female.attack.especial @a ~ ~ ~ 1",
            "execute as @s[scores={genero=1,combos_animacoes=1,combo=1..3,furia=1..}] at @s run playsound player.male.attack @a ~ ~ ~ 1",
            "execute as @s[scores={genero=1,combo=4,furia=1..}] at @s run playsound player.male.attack.especial @a ~ ~ ~ 1",
            "playsound random.totem @s[scores={combos_animacoes=1,combo=4,furia=1..}] ~ ~ ~ 0.1 2"
        ];
        cmds.forEach(c => { try { player.runCommand(c); } catch {} });

        const combo = getScore(player, "combo");

        if (combo === 1 || combo === 2) {
            ativarDanoArea(player, "add_dano2");
        } else if (combo === 3) {
            ativarDanoArea(player, "add_dano2");
        } else if (combo === 4) {
            const slotInicial = player.selectedSlotIndex;
            let ticks = 0;

            // Primeiro aplica o dano contínuo
            try { player.runCommand("event entity @s remove_danos"); } catch {} // limpa anterior
            try { player.runCommand("event entity @s add_dano2"); } catch {}

            // Cancela qualquer remoção automática pendente
            if (danoRemoveTimeouts.has(player.id)) {
                danoRemoveTimeouts.get(player.id)();
                danoRemoveTimeouts.delete(player.id);
            }

            const loop = system.runInterval(() => {
                if (!player || !player.isValid || player.selectedSlotIndex !== slotInicial) {
                    try { player.runCommand("event entity @s remove_danos"); } catch {}
                    try { player.runCommand("event entity @s remove_knockback"); } catch {}
                    limparCamera(player);
                    system.clearRun(loop);
                    return;
                }

                if (++ticks >= 76) {
                    limparCamera(player, 4);
                    try { player.runCommand("event entity @s remove_danos"); } catch {}
                    try { player.runCommand("event entity @s remove_knockback"); } catch {}
                    combo4Cooldown.set(player.id, system.currentTick + COMBO4_COOLDOWN_TICKS);
                    system.clearRun(loop);
                }
            }, 1);
        }

        // Reset por inatividade
        const reset = system.runTimeout(() => {
            limparCamera(player);
            // Remove dano em área se não estiver no combo 4 ativo
            try { player.runCommand("event entity @s remove_danos"); } catch {}
        }, 60);

        comboTimeouts.set(player.id, () => system.clearRun(reset));
    }

    // Eventos de hit
    world.afterEvents.entityHitEntity.subscribe(ev => {
        const player = ev.damagingEntity;
        if (!player || player.typeId !== "minecraft:player") return;
        if (!ev.hitEntity) return;
        if (!temEspada(player)) return;
        processarHit(player);
    });

    world.afterEvents.entityHitBlock.subscribe(ev => {
        const player = ev.damagingEntity;
        if (!player || player.typeId !== "minecraft:player") return;
        if (!temEspada(player)) return;
        processarHit(player);
    });

    // Limpeza ao sair
    world.afterEvents.playerLeave.subscribe(e => {
        lastValidHit.delete(e.playerId);
        combo4Cooldown.delete(e.playerId);
        if (comboTimeouts.has(e.playerId)) {
            comboTimeouts.get(e.playerId)();
            comboTimeouts.delete(e.playerId);
        }
        if (danoRemoveTimeouts.has(e.playerId)) {
            danoRemoveTimeouts.get(e.playerId)();
            danoRemoveTimeouts.delete(e.playerId);
        }
    });
}