import { EntityHealthComponent, system, world, EquipmentSlot, EntityInventoryComponent } from "@minecraft/server";
import functions from './lib/functions';

const protectedPlayers = new Map();

system.runInterval(async () => {
    for (const player of world.getPlayers()) {
        functions.getItemsWithTag(player, "minecraft:is_sword").forEach(item => {
            const playerInventoryComponentContainer = player.getComponent(EntityInventoryComponent.componentId).container;
            item.item.setLore([ "§r§9 Blocking" ]);
            playerInventoryComponentContainer.setItem(item.slot, item.item);
        });
        const weapon = functions.findWeapon(player);

        if (functions.getWeapon(player, true)?.typeId == "minecraft:shield") continue;
        if (!weapon || !player.isSneaking) {
            protectedPlayers.delete(player.id);
            continue
        } else if (!protectedPlayers.get(player.id)) protectedPlayers.set(player.id, weapon);
        player.addEffect("weakness", 20, { amplifier: 5, showParticles: false });
        player.playAnimation("animation.player.weapon_blocking");
    }
});

world.afterEvents.entityHurt.subscribe(event => {
    const { hurtEntity: player, damage, damageSource: source } = event;
    const { damagingEntity:  entity, damagingProjectile: projectile } = source;
    const protectedPlayer = protectedPlayers.get(player.id);

    if (!protectedPlayer) return;
    const healthComponent = player.getComponent(EntityHealthComponent.componentId);
    const reduction = functions.calculateReduction(damage, entity || projectile, !!projectile);

    player.playSound('item.shield.block');
    functions.getEquipmentComponent(player)
        .setEquipment(EquipmentSlot.Mainhand, functions.damageWeapon(protectedPlayer, 10));
    player.teleport(player.location);
    system.run(() => {
        healthComponent.setCurrentValue(healthComponent.currentValue + reduction);
    });
}, { entityTypes: [ "minecraft:player" ] });


system.beforeEvents.watchdogTerminate.subscribe(ev => ev.cancel = true);