//VENOMOUS SWORD
import { world, Player, EquipmentSlot, Entity, system, ItemStack, ItemComponentTypes, EntityComponentTypes } from "@minecraft/server";

export async function onEntityHitEntity(event) {
    if (event.damagingEntity instanceof Player) {

        const equipment = event.damagingEntity.getComponent("minecraft:equippable");
        if (equipment !== undefined) {
            const itemStack = equipment.getEquipment(EquipmentSlot.Mainhand);
            if (itemStack !== undefined && itemStack.typeId === ("tcs_ohs:wither_spear")) {
                event.damagingEntity.runCommandAsync("playsound tcs_ohs:wither_spear_melee @s")
                event.hitEntity.runCommandAsync("particle minecraft:critical_hit_emitter ~ ~1 ~")
            }
            else if (itemStack !== undefined && itemStack.typeId === ("tcs_ohs:battle_axe")) {
                event.damagingEntity.runCommandAsync("playsound tcs_ohs:battle_axe_melee @s")
                event.hitEntity.runCommandAsync("particle minecraft:critical_hit_emitter ~ ~1 ~")
                event.damagingEntity.runCommandAsync("particle tcs_ohs:battle_axe_slash ^ ^1.2 ^0.5")
                event.hitEntity.runCommandAsync("effect @s weakness 2 1")
            }
            else if (itemStack !== undefined && itemStack.typeId === ("tcs_ohs:battle_scythe")) {
                event.damagingEntity.runCommandAsync("playsound tcs_ohs:battle_scythe_melee @s")
                event.damagingEntity.runCommandAsync("particle tcs_ohs:scythe_slash ~ ~1 ~")
                event.hitEntity.runCommandAsync("particle minecraft:critical_hit_emitter ~ ~1 ~")
            }
            else if (itemStack !== undefined && itemStack.typeId === ("tcs_ohs:venomous_sword")) {
                event.damagingEntity.runCommandAsync("playsound tcs_ohs:venomous_sword_melee @s")
                event.damagingEntity.runCommandAsync("particle tcs_ohs:sword_slash ^ ^1.2 ^0.5")
                try {
                    event.hitEntity.runCommandAsync("effect @s poison 2 1 true")
                    event.hitEntity.runCommandAsync('particle tcs_ohs:venomous_poison ~ ~ ~')
                    event.hitEntity.runCommandAsync("particle minecraft:critical_hit_emitter ~ ~1 ~")
                }
                catch (error) {}
            }
        }
    }
}


export async function onEntityHurt(event) {
    const attacker = event.damagingEntity;
    if (attacker instanceof Player) {
        let animationIndex = attacker.getDynamicProperty("tcs_ohs_attack_index");
        if (animationIndex == undefined) {
            animationIndex = -1;
        }
        animationIndex = (animationIndex + 1) % 3;
        attacker.setDynamicProperty("tcs_ohs_attack_index", animationIndex);
        attacker.runCommandAsync(`playanimation @s animation.tcs_ohs.player.custom_weapon.attack_fp_v${animationIndex + 1} animation.tcs_ohs.player.custom_weapon.attack_tp_v${animationIndex + 1} 0 "!v.is_first_person"`);
        attacker.runCommandAsync(`playanimation @s animation.tcs_ohs.player.custom_weapon.attack_tp_v${animationIndex + 1} animation.tcs_ohs.player.custom_weapon.attack_fp_v${animationIndex + 1} 0 "v.is_first_person"`);
        attacker.runCommandAsync(`playanimation @s animation.tcs_ohs.player.custom_weapon.attack_fp_v${animationIndex + 1} animation.tcs_ohs.player.empty 0.15 "q.all_animations_finished"`);
        attacker.runCommandAsync(`playanimation @s animation.tcs_ohs.player.custom_weapon.attack_tp_v${animationIndex + 1} animation.tcs_ohs.player.empty 0.15 "q.all_animations_finished"`);
    }
}

let useWeapon = false;
export async function onItemUse(event) {
    const player = event.source;
    if (useWeapon == false) {
        itemClick(player, event.itemStack.typeId);
    }
};

let chargeStartTime = 0;


function itemClick(player, item) {
    if (item === "tcs_ohs:wither_spear") {
        wither_spear_charge(player);
        chargeStartTime = new Date().getTime();

    }
    else if (item == "tcs_ohs:battle_axe" && useWeapon == false) {
        useWeapon = true;
        let durabilityAxe = getDurabilityInHand(player);
        if (durabilityAxe <=240) {
        player.runCommand("playanimation @s animation.tcs_ohs.player.custom_weapon.attack_tp_v5");
       
        let nr = 0;

        const runId = system.runInterval(() => {
          
            player.runCommand("playsound tcs_ohs:battle_axe_throw @s")
            player.runCommand("replaceitem entity @s slot.weapon.mainhand 0 tcs_ohs:battle_axe")
            player.runCommand("clear @s tcs_ohs:battle_axe 0 1");
            battle_axe(player,durabilityAxe);

            nr++;
            if (nr > 0) {

                weaponReload(player)
                system.clearRun(runId);
            }

        }, 14);

    }

    }
    else if (item == "tcs_ohs:battle_scythe" && useWeapon == false) {
        useWeapon = true;
        let scythe = 0;
        player.runCommand("tag @s add Player");
        player.runCommand("playanimation @s animation.tcs_ohs.player.custom_weapon.attack_tp_v4_scythe");
        reduceDurabilityInHand(player);

        const runId = system.runInterval(() => {
            player.runCommand("particle tcs_ohs:scythe_slash ~ ~1 ~")
            player.runCommand("damage @e[r=4,tag=!Player,type=!item] 7 entity_attack ");
            player.runCommand("execute at @e[r=4,tag=!Player,type=!item] run particle minecraft:critical_hit_emitter ~ ~ ~");
            player.runCommand("playsound tcs_ohs:battle_scythe_slash @s")
            scythe++;
            if (scythe > 0) {
                weaponReload(player)
                system.clearRun(runId);
            }

        }, 8);
    }
    else if (item === "tcs_ohs:inferno_bow") {
        chargeStartTime = new Date().getTime();
        arrowCheck(player)
    }
}
let isCharged = false;
function weaponReload(player) {
    let l = 0;
    const reload = system.runInterval(() => {
        useWeapon = false;
        l++;
        if (l > 0) 
            system.clearRun(reload);
    }, 5);
}
function arrowCheck(player) {
    const component = player.getComponent("minecraft:inventory");
    if (!component) {
        player.sendMessage("You do not have an inventory component.");
        return false;
    }

    const inventory = component.container;
    let arrowCount = 0;

    for (let i = 0; i < inventory.size; i++) {
        let item = inventory.getItem(i);
        if (item && item.typeId === "minecraft:arrow")
            arrowCount += item.amount;
    }

    if (arrowCount >= 1) {
        inferno_bow_charge(player);
        player.runCommand(`clear @s arrow 0 1`)
        return true;
    }

    return false;
}

function inferno_bow_charge(player) {

    player.runCommandAsync(`playanimation @s animation.tcs_ohs.player.normal animation.tcs_ohs.player.normal 0 "v.is_first_person"`);
    player.runCommandAsync(`playanimation @s animation.humanoid.bow_and_arrow animation.tcs_ohs.player.normal 0 "v.is_first_person"`);
    player.runCommandAsync(`playanimation @s animation.player.empty animation.humanoid.bow_and_arrow 0 "!v.is_first_person"`);

    //const runId = system.runInterval(() => {}, 4);

    isCharged = true;

    player.runCommandAsync(`playsound tcs_ohs:inferno_bow_charge @s `)
    world.afterEvents.itemReleaseUse.subscribe(event => {
        const eventPlayer = event.source;

        if (isCharged && eventPlayer === player && event.itemStack.typeId === "tcs_ohs:inferno_bow") {
            const chargeEndTime = new Date().getTime();
            const chargeDuration = (chargeEndTime - chargeStartTime) / 1000;

            inferno_bow_shoot(player, chargeDuration);


            isCharged = false;

        }
    });
}

function reduceDurabilityInHand(player) {
    const equipment = player.getComponent("minecraft:equippable");
    if (equipment === undefined)
        return;

    const itemStack = equipment.getEquipment(EquipmentSlot.Mainhand);
    if (itemStack === undefined) 
        return;

    const durabilityComponent = itemStack.getComponent(ItemComponentTypes.Durability);
    if (durabilityComponent !== undefined && durabilityComponent.damage < durabilityComponent.maxDurability) {
        durabilityComponent.damage += 1; // Smanji durability za 1
        equipment.setEquipment(EquipmentSlot.Mainhand, itemStack); // Ažuriraj predmet u ruci
    }
}


function inferno_bow_shoot(player, chargeDuration) {

    reduceDurabilityInHand(player)
    const currentDimension = world.getDimension(world.getPlayers()[0].dimension.id);
    const minImpulse = 2;
    const maxImpulse = 3.5;
    const minDuration = 0.2;
    const maxDuration = 0.5;

    const duration = Math.min(maxDuration, Math.max(minDuration, chargeDuration));
    const impulseForce = minImpulse + ((duration - minDuration) / (maxDuration - minDuration)) * (maxImpulse - minImpulse);
    player.runCommandAsync(`playsound tcs_ohs:inferno_bow_shoot @s `)
    player.runCommand("playanimation @s animation.tcs_ohs.player.normal_bow")

    const playerLocation = { x: player.location.x, y: player.location.y + 1.4, z: player.location.z };
    const viewDirection = player.getViewDirection();
    const facingLocation = { x: playerLocation.x + viewDirection.x, y: playerLocation.y + viewDirection.y, z: playerLocation.z + viewDirection.z };
    const projectile = currentDimension.spawnEntity("tcs_ohs:inferno_bow_projectile", playerLocation);
    const summonCommand = `summon tcs_ohs:inferno_bow_dummy ${playerLocation.x} ${playerLocation.y} ${playerLocation.z} facing ${facingLocation.x} ${facingLocation.y} ${facingLocation.z}`;
    try {
        currentDimension.runCommand(summonCommand);
    } catch (error) {
        console.error("Failed to summon the wither spear projectile:", error);
        return;
    }

    const dummy = currentDimension.getEntities({
        type: "tcs_ohs:inferno_bow_dummy",
        location: playerLocation,
        maxDistance: 5
    })[0];

    projectile.applyImpulse({ x: viewDirection.x * impulseForce, y: viewDirection.y * impulseForce, z: viewDirection.z * impulseForce });
    let inc = 1;


    const runId = system.runInterval(() => {
        if (!dummy || !dummy.isValid()) {
            system.clearRun(runId);
            return;
        }

        const projectileLocation = projectile.location;
        const facingLocation = { x: projectileLocation.x + viewDirection.x, y: projectileLocation.y + viewDirection.y, z: projectileLocation.z + viewDirection.z };
        dummy.teleport(projectileLocation, {  facingLocation: facingLocation });

        if (inc > 100)
            system.clearRun(runId);
        inc++;
    }, 1);
}

function wither_spear_charge(player) {
    let durabilitySpear = getDurabilityInHand(player);
    if (durabilitySpear <=240) {
        player.runCommandAsync(`playanimation @s animation.tcs_ohs.player.empty animation.tcs_ohs.player_shoot_spear_fp 0 "v.is_first_person"`);
        player.runCommandAsync(`playanimation @s animation.tcs_ohs.player.shoot_spear animation.tcs_ohs.player_shoot_spear_fp 0 "v.is_first_person"`);

        isCharged = true;

        player.runCommandAsync(`playsound tcs_ohs:wither_spear_charge @s`)

        world.afterEvents.itemReleaseUse.subscribe(event => {
            const eventPlayer = event.source;

            if (isCharged && eventPlayer === player && event.itemStack !== undefined && event.itemStack.typeId === "tcs_ohs:wither_spear") {
                wither_spear(player);
                isCharged = false;
            }
        });
    }
}

function wither_spear(player) {
    let durability = getDurabilityInHand(player);
    startCheckingForTamedSpear(player, durability)
    const currentDimension = world.getDimension(world.getPlayers()[0].dimension.id);
    player.runCommand(`tag @s add Player`)
    player.runCommandAsync(`playsound tcs_ohs:wither_spear_throw @s`)
    player.runCommandAsync(`playanimation @s animation.tcs_ohs.player.normal`);

    player.runCommand("replaceitem entity @s slot.weapon.mainhand 0 tcs_ohs:wither_spear")
    player.runCommand("clear @p tcs_ohs:wither_spear 0 1");
    const impulseForce = 3.6;
    // const overworld = world.getDimension('overworld');
    const playerLocation = { x: player.location.x, y: player.location.y + 1.3, z: player.location.z };
    const viewDirection = player.getViewDirection();
    const facingLocation = { x: playerLocation.x + viewDirection.x, y: playerLocation.y + viewDirection.y, z: playerLocation.z + viewDirection.z };
    const projectile = currentDimension.spawnEntity("tcs_ohs:wither_spear_projectile", playerLocation);
    const summonCommand = `summon tcs_ohs:wither_spear_dummy ${playerLocation.x} ${playerLocation.y} ${playerLocation.z} facing ${facingLocation.x} ${facingLocation.y} ${facingLocation.z}`;
    try {
        currentDimension.runCommand(summonCommand);
    } catch (error) {
        console.error("Failed to summon the wither spear projectile:", error);
        return;
    }

    const dummy = currentDimension.getEntities({
        type: "tcs_ohs:wither_spear_dummy",
        location: playerLocation,
        maxDistance: 5
    })[0];

    projectile.applyImpulse({ x: viewDirection.x * impulseForce, y: viewDirection.y * impulseForce, z: viewDirection.z * impulseForce });
    let inc = 1;
    const projectileComponent = projectile.getComponent('minecraft:projectile');
    if (projectileComponent) {
        if (player)
            projectileComponent.owner = player;
    }

    const runId = system.runInterval(() => {
        if (!dummy || !dummy.isValid()) {
            system.clearRun(runId);
            return;
        }
        const isStunned = dummy.getComponent("minecraft:is_stunned");
        if (isStunned) {
            system.clearRun(runId);
            return;
        }

        if (!projectile || projectile.location == undefined) {
            system.clearRun(runId);
            return;
        }

        const projectileLocation = projectile.location;
        if (!projectileLocation) {
            system.clearRun(runId);
            return;
        }

        const facingLocation = {
            x: projectileLocation.x + viewDirection.x,
            y: projectileLocation.y + viewDirection.y,
            z: projectileLocation.z + viewDirection.z
        };
        dummy.teleport(projectileLocation, {
            facingLocation: facingLocation
        });

        if (inc > 50)
            system.clearRun(runId);
        inc++;
    }, 1);
}

function startCheckingForTamedSpear(player, durability) {
    const intervalId = system.runInterval(() => {
        for (const entity of  world.getDimension(world.getPlayers()[0].dimension.id).getEntities()) {
            if (entity.typeId === "tcs_ohs:wither_spear_dummy") {
                const isTamedComponent = entity.getComponent("minecraft:is_tamed");
                if (isTamedComponent !== undefined) {
                    updateDurabilityAndGiveItem(player, durability);
                    entity.runCommandAsync('/event entity @s tcs_ohs:despawn');
                    system.clearRun(intervalId);
                    return;
                }
            }
        }
    }, 4);
}

function updateDurabilityAndGiveItem(player, durability) {
    const currentDurability = durability;
    if (currentDurability !== null) {
        const newDurability = currentDurability + 10; // Decrease durability by 10
        giveHurtWitherSpear(player, newDurability);
    }
}

function getDurabilityInHand(player) {
    const equipment = player.getComponent("minecraft:equippable");
    if (equipment === undefined)
        return null;

    const itemStack = equipment.getEquipment(EquipmentSlot.Mainhand);
    if (itemStack === undefined)
        return null;

    const durabilityComponent = itemStack.getComponent(ItemComponentTypes.Durability);
    if (durabilityComponent !== undefined) {
        return durabilityComponent.damage;
    }

    return null;
}

function giveHurtWitherSpear(player, newDurability) {
    const inventory = player.getComponent(EntityComponentTypes.Inventory);
    if (inventory === undefined || inventory.container === undefined) {
        return;
    }
    const hurtWitherSpear = new ItemStack("tcs_ohs:wither_spear");
    const durabilityComponent = hurtWitherSpear.getComponent(ItemComponentTypes.Durability);
    if (durabilityComponent !== undefined) {
        durabilityComponent.damage = newDurability;
    }

    inventory.container.addItem(hurtWitherSpear);
}


//BATTLE AXE
function startCheckingForAxe(player, durability) {
    const intervalId = system.runInterval(() => {
        for (const entity of  world.getDimension(world.getPlayers()[0].dimension.id).getEntities()) {
            if (entity.typeId === "tcs_ohs:returning_battle_axe") {
                const isTamedComponent = entity.getComponent("minecraft:is_tamed");
                if (isTamedComponent !== undefined) {
                    updateDurabilityAndGiveItemAxe(player, durability);
                    entity.runCommandAsync("event entity @s tcs_ohs:despawn")
                    system.clearRun(intervalId);
                    return;
                }
            }
        }
    }, 4);
}

function updateDurabilityAndGiveItemAxe(player, durability) {
    const currentDurability = durability;
    if (currentDurability !== null) {
        const newDurability = currentDurability + 10; // Decrease durability by 10
        giveHurtBattleAxe(player, newDurability);
    }
}


function giveHurtBattleAxe(player, newDurability) {
    const inventory = player.getComponent(EntityComponentTypes.Inventory);
    if (inventory === undefined || inventory.container === undefined)
        return;
    
    const hurtBattleAxe = new ItemStack("tcs_ohs:battle_axe");
    const durabilityComponent = hurtBattleAxe.getComponent(ItemComponentTypes.Durability);
    if (durabilityComponent !== undefined)
        durabilityComponent.damage = newDurability;

    inventory.container.addItem(hurtBattleAxe);
}

function battle_axe(player,durabilityAxe) {
    startCheckingForAxe(player, durabilityAxe)
    player.runCommand('/tag @s add Player')
    const location = { x: player.location.x, y: player.location.y + 1.3, z: player.location.z };
    const playerViewDirection = player.getViewDirection();
    const projectile = world.getDimension(player.dimension.id).spawnEntity("tcs_ohs:thrown_battle_axe", { ...location });


    const impulseForce = 1.1;
    const direction = {
        x: player.getViewDirection().x * impulseForce,
        y: player.getViewDirection().y * impulseForce,
        z: player.getViewDirection().z * impulseForce
    };
    projectile.applyImpulse({ ...direction });
}

