import * as mc from "@minecraft/server"

mc.world.beforeEvents.worldInitialize.subscribe(a => {
    a.itemComponentRegistry.registerCustomComponent("ld_eb:equip_amor", {
        onUse: (data) => {
            updateArmorEffects()
        }
    })
})

mc.world.afterEvents.playerSpawn.subscribe(a => {
    updateArmorEffects()
})

mc.Player.prototype.ld_eb_armor_state = null;

mc.system.runInterval(() => {
    updateArmorEffects()
}, 2 * 20)

function updateArmorEffects() {
    mc.world.getAllPlayers().forEach(p => {
        /** @type { mc.EntityEquippableComponent } */
        const equippableComponent = p.getComponent(mc.EntityEquippableComponent.componentId)
        if (!equippableComponent) return

        const equippedItems = [
            equippableComponent.getEquipment("Head")?.typeId ?? "none",
            equippableComponent.getEquipment("Chest")?.typeId ?? "none",
            equippableComponent.getEquipment("Legs")?.typeId ?? "none",
            equippableComponent.getEquipment("Feet")?.typeId ?? "none"
        ].filter(typeId => typeId !== "none")

        let armorEquipped = null

        armors.forEach(a => {
            if (equippedItems.length === 4 && equippedItems.every(item => item.startsWith(a.id))) {
                armorEquipped = a
            }
        })

        if (armorEquipped && p.ld_eb_armor_state !== armorEquipped.id && mc.world.getDynamicProperty("ld_eb:passive_skills")) {
            if (p.ld_eb_armor_state) {
                const previousArmor = armors.find(a => a.id === p.ld_eb_armor_state)
                if (previousArmor) previousArmor.close(p)
            }
            p.ld_eb_armor_state = armorEquipped.id
            armorEquipped.entry(p);
        } else if (!armorEquipped && p.ld_eb_armor_state || !mc.world.getDynamicProperty("ld_eb:passive_skills")) {
            const previousArmor = armors.find(a => a.id === p.ld_eb_armor_state)
            if (previousArmor) previousArmor.close(p)
            p.ld_eb_armor_state = null
        }
    })
}

mc.Player.prototype.ld_eb_player_agua = undefined
mc.Player.prototype.ld_eb_player_air = undefined
mc.Player.prototype.ld_eb_player_lava = undefined
mc.Player.prototype.ld_eb_player_metalic = false
const armors = [
    {
        id: "ld_eb:armor.fogo",
        name: "§cFire",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("mob.blaze.shoot")
            player.addEffect("fire_resistance", 20000000, {
                amplifier: 255,
                showParticles: false
            })
        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("fire_resistance")
        },
    },
    {
        id: "ld_eb:armor.agua",
        name: "§bWater",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("bucket.fill_water")
            player.addEffect("water_breathing", 20000000, {
                amplifier: 255,
                showParticles: false
            })
            player.ld_eb_player_agua = mc.system.runInterval(() => {
                if (player.isSwimming) {
                    const velocity = 2
                    try { player.applyKnockback(player.getViewDirection().x, player.getViewDirection().z, 1 * velocity, velocity * player.getViewDirection().y / 2) } catch (e) {}
                }
            }, 0.2 * 20);
        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("water_breathing")
            mc.system.clearRun(player.ld_eb_player_agua)
        },
    },
    {
        id: "ld_eb:armor.ar",
        name: "§7Air",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("mob.snowgolem.shoot")
            let jumps = 0;
            let jumpReleased = true; // Garante que o jogador soltou o botão antes do próximo pulo

            player.ld_eb_player_air = mc.system.runInterval(() => {
                if (player.isOnGround) {
                    player.removeEffect("resistance")
                    jumps = 0; // Reseta os pulos ao tocar o solo
                    jumpReleased = true; // Permite pular novamente
                    return;
                }

                if (!player.isJumping) {
                    jumpReleased = true; // Detecta quando o jogador solta o botão de pulo
                }

                if (player.isJumping && jumpReleased) {
                    jumpReleased = false; // Impede outro pulo até que solte o botão
                    jumps++;

                    if (jumps === 2) { // Apenas no segundo pulo
                        //console1-console.warn("[DEBUG] Pulo Duplo Ativado!");
                        {
                        const equipmentSlots = ["Head", "Chest", "Legs", "Feet"];
                        equipmentSlots.forEach(slot => {
                            const item = player.getComponent(mc.EntityEquippableComponent.componentId)?.getEquipment(slot);
                            {
                                let durability = item.getComponent("durability");
                                if(durability.damage < durability.maxDurability){
                                const newItem = item.clone();
                                newItem.getComponent("durability").damage += 1;
                                player.getComponent(mc.EntityEquippableComponent.componentId)?.setEquipment(slot, newItem);
                                } else {
                                    player.runCommand(`title @s actionbar No armor durability left`)
                                }
                            }
                        });
                        }

                        player.addEffect("resistance", 999 * 20, { // 0.5s para suavizar a queda
                            amplifier: 255,
                            showParticles: false
                        });

                        player.addEffect("slow_falling", 0.5 * 20, { // 0.5s para suavizar a queda
                            amplifier: 255,
                            showParticles: false
                        });

                        // Define a intensidade do impulso
                        const velocity = 0.8;

                        // Aplica impulso vertical e um pequeno ajuste horizontal
                        try { player.applyKnockback(player.getVelocity().x, player.getVelocity().z, 0, velocity); } catch (e) {}
                        mc.world.playSound("ld_eb.dash", player.location)
                        player.dimension.spawnParticle("ld_eb:air_jump_1", {
                            x: player.location.x,
                            y: player.location.y + 0.5,
                            z: player.location.z
                        })
                        player.dimension.spawnParticle("ld_eb:air_jump_2", {
                            x: player.location.x,
                            y: player.location.y + 0.5,
                            z: player.location.z
                        })

                        jumps++; // Bloqueia até tocar o solo
                    }
                }
            }, 1); // Checagem a cada tick (20 vezes por segundo)

        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("slow_falling")
            mc.system.clearRun(player.ld_eb_player_air)
        },
    },
    {
        id: "ld_eb:armor.terra",
        name: "§gEarth",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("land.dirt_with_roots")
            player.addEffect("jump_boost", 20000000, {
                amplifier: 2,
                showParticles: false
            })
        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("jump_boost")
        },
    },
    {
        id: "ld_eb:armor.eletrico",
        name: "§1Electricity",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("beacon.activate")
            let jumps = 0;
            let jumpReleased = true; // Garante que o jogador soltou o botão antes do próximo pulo

            player.ld_eb_player_air = mc.system.runInterval(() => {
                if (player.isOnGround) {
                    player.removeEffect("resistance")
                    jumps = 0; // Reseta os pulos ao tocar o solo
                    jumpReleased = true; // Permite pular novamente
                    return;
                }

                if (!player.isJumping) {
                    jumpReleased = true; // Detecta quando o jogador solta o botão de pulo
                }

                if (player.isJumping && jumpReleased) {
                    jumpReleased = false; // Impede outro pulo até que solte o botão
                    jumps++;

                    if (jumps === 2) { // Apenas no segundo pulo
                        //console1-console.warn("[DEBUG] Pulo Duplo Ativado!");
                        
                        {
                        const equipmentSlots = ["Head", "Chest", "Legs", "Feet"];
                        equipmentSlots.forEach(slot => {
                            const item = player.getComponent(mc.EntityEquippableComponent.componentId)?.getEquipment(slot);
                            {
                                let durability = item.getComponent("durability");
                                if(durability.damage < durability.maxDurability){
                                const newItem = item.clone();
                                newItem.getComponent("durability").damage += 1;
                                player.getComponent(mc.EntityEquippableComponent.componentId)?.setEquipment(slot, newItem);
                                } else {
                                    player.runCommand(`title @s actionbar No armor durability left`)
                                }
                            }
                        });
                        }
                        //player.getComponent(mc.EntityEquippableComponent.componentId)?.getEquipment('Mainhand').damage += 100
                        player.addEffect("resistance", 999 * 20, { // 0.5s para suavizar a queda
                            amplifier: 255,
                            showParticles: false
                        });
                        mc.world.playSound("ld_eb.dash", player.location)
                        mc.world.playSound("ld_eb.zap_eletric", player.location)

                        // Define a intensidade do impulso
                        const velocity = 2;

                        // Aplica impulso vertical e um pequeno ajuste horizontal
                        try { player.applyKnockback(player.getVelocity().x, player.getVelocity().z, velocity, 0.4 * (velocity*(player.getViewDirection().y))/4); } catch (e) {}
                        player.dimension.spawnParticle("ld_eb:electricity_staff_electricoutburst_5", {
                            x: player.location.x,
                            y: player.location.y + 0.5,
                            z: player.location.z
                        })

                        jumps++; // Bloqueia até tocar o solo
                    }
                }
            }, 1); // Checagem a cada tick (20 vezes por segundo)

        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("speed")
            mc.system.clearRun(player.ld_eb_player_air)
        },
    },
    {
        id: "ld_eb:armor.espiritual",
        name: "§5Spiritual",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("mob.glow_squid.ink_squirt")
            player.addEffect("regeneration", 20000000, {
                amplifier: 2,
                showParticles: false
            })
        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("regeneration")
        },
    },
    {
        id: "ld_eb:armor.lava",
        name: "§gLava",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`);
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("mob.blaze.shoot");
            player.addEffect("fire_resistance", 20000000, { amplifier: 255, showParticles: false });

            player.ld_eb_player_lava = mc.system.runInterval(() => {
                const values = [8, 5];
                player.runCommand(`/fill ~${values[1]}~${values[1]}~${values[1]} ~-${values[1]}~-${values[1]}~-${values[1]} ld_eb:obsidian replace lava ["liquid_depth"=0]`);
            }, 0.2 * 20);
        },
        close: /** @param { mc.Player } player */ async function (player) {
            if (player.ld_eb_player_lava) {
                mc.system.clearRun(player.ld_eb_player_lava)
                player.ld_eb_player_lava = undefined
            }
        },
    },
    {
        id: "ld_eb:armor.metalica",
        name: "§8Metallic",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("mob.irongolem.repair")
            player.ld_eb_player_metalic = true
        },
        close: /** @param { mc.Player } player */ function (player) {
            player.ld_eb_player_metalic = false
        },
    },
    {
        id: "ld_eb:armor.vazio",
        name: "§0Void",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("mob.endermite.step")
            player.addEffect("night_vision", 20000000, {
                amplifier: 255,
                showParticles: false
            })
        },
        close: /** @param { mc.Player } player */ function (player) {
            player.removeEffect("night_vision")
        },
    },
    {
        id: "ld_eb:armor.gelo",
        name: "§bIce",
        entry: /** @param { mc.Player } player */ function (player) {
            player.onScreenDisplay.setActionBar(`§rYou have fully activated the ${this.name}§r armor!`)
            !mc.world.getDynamicProperty("ld_eb:efeitos_sonoros") ? null : player.playSound("break.amethyst_block")
            player.ld_eb_player_lava = mc.system.runInterval(() => {
                const values = [8, 5];
                player.runCommand(`/fill ~${values[1]}~${values[1]}~${values[1]} ~-${values[1]}~-${values[1]}~-${values[1]} ld_eb:ice replace water ["liquid_depth"=0]`);
            }, 0.2 * 20);
        },
        close: /** @param { mc.Player } player */ async function (player) {
            if (player.ld_eb_player_lava) {
                mc.system.clearRun(player.ld_eb_player_lava)
                player.ld_eb_player_lava = undefined
            }
        },
    },
];

mc.world.afterEvents.entityHurt.subscribe(data => {
    const entity = data.damageSource.damagingEntity,
        player = data.hurtEntity
    if (player.typeId !== "minecraft:player" || !player.ld_eb_player_metalic) return
    entity.applyDamage(data.damage, {
        cause: "contact",
        damagingEntity: player
    })
    entity.addEffect("slowness", 2 * 20, {
        showParticles: true,
        amplifier: 5
    })
})

mc.world.beforeEvents.worldInitialize.subscribe(data => {
    data.blockComponentRegistry.registerCustomComponent("ld_eb:ice", {
        onTick: a => {
            const block = a.block
            const filter = {
                type: "minecraft:player",
                location: block.location,
                maxDistance: 6
            }
            let players = block.dimension.getEntities(filter).filter(p => p.ld_eb_player_lava)
            players.forEach(p => {
                p.addEffect("speed", 1 * 20, { amplifier: 2, showParticles: false });
            })
            mc.system.runTimeout(() => {
                let players = block.dimension.getEntities(filter).filter(p => p.ld_eb_player_lava)
                if (players.length > 0) return
                block.setType("minecraft:water")
            }, 1 * 20)
        },
    })
    data.blockComponentRegistry.registerCustomComponent("ld_eb:obsidian", {
        onTick: a => {
            const block = a.block
            const filter = {
                type: "minecraft:player",
                location: block.location,
                maxDistance: 6
            }
            let players = block.dimension.getEntities(filter).filter(p => p.ld_eb_player_lava)
            players.forEach(p => {
                p.addEffect("speed", 1 * 20, { amplifier: 2, showParticles: false });
            })
            mc.system.runTimeout(() => {
                let players = block.dimension.getEntities(filter).filter(p => p.ld_eb_player_lava)
                if (players.length > 0) return
                block.setType("minecraft:lava")
            }, 1 * 20)
        },
    })
})