package com.zivilon.cinder_loe.util;

import net.minecraft.entity.*;
import net.minecraft.entity.player.*;
import net.minecraft.util.DamageSource;


import com.zivilon.cinder_loe.util.IBossEntity;
import com.zivilon.cinder_loe.mixins.MixinLOTREnchantment;
import lotr.common.enchant.LOTREnchantment;
import lotr.common.enchant.LOTREnchantmentHelper;

import lotr.common.item.*;
import net.minecraft.item.*;
import net.minecraft.world.World;
import lotr.common.entity.npc.LOTREntityMountainTrollChieftain;

public class DamageEvent {
    public DamageSource source;
    public float damage;
    public EntityLivingBase defender;
    public Entity attacker;

    public DamageEvent(DamageSource source, float damage, EntityLivingBase defender, Entity attacker) {
        this.source = source;
        this.damage = damage;
        this.defender = defender;
        this.attacker = attacker;
    }

    public static Pair<DamageEvent, Boolean> run_events(DamageEvent event) {
        boolean cancel = false;

        cancel = (cancel || attack_block_task(event));
        cancel = (cancel || fire_armor_repair_task(event));
        cancel = (cancel || fix_hill_troll_chieftain_task(event));

        return new Pair<>(event, cancel);
    }
    public static boolean attack_block_task(DamageEvent event) {
        boolean cancel = false;
        World world = event.defender.worldObj;
        if (event.defender instanceof EntityPlayer && !event.source.isUnblockable()) {
            EntityPlayerMP player = (EntityPlayerMP) event.defender;
            ItemStack sword = player.getHeldItem();
            if (!(event.attacker instanceof EntityLivingBase)) return cancel;
            EntityLivingBase attacker = (EntityLivingBase)event.attacker;

            float playerYaw = player.getRotationYawHead();
            float attackerYaw = attacker.getRotationYawHead();

            // Normalize both angles to be within 0 - 360
            playerYaw = (playerYaw + 360) % 360;
            attackerYaw = (attackerYaw + 360) % 360;

            // Calculate the angle difference
            float angleDifference = Math.abs(playerYaw - attackerYaw);

            if (angleDifference > 180) {
                angleDifference = 360 - angleDifference;
            }
            ItemStack weapon = attacker.getHeldItem();
            if (weapon != null) {
                if (player.isBlocking() && angleDifference >= 135 && angleDifference <=225) {
                    if (LOTREnchantmentHelper.hasEnchant(weapon, LOTREnchantment.getEnchantmentByName("wrath"))) {
                        world.playSoundAtEntity(player, "cinder_loe:attack.wrath", 0.5F, 0.75F);
                        return cancel;
                    }
                    if (weapon.getItem() instanceof ItemAxe || weapon.getItem() instanceof LOTRItemAxe || weapon.getItem() instanceof LOTRItemBattleaxe) {
                        sword.damageItem((int) (event.damage *1.5), player); // Axes deal 150% the Durability damage
                        player.clearItemInUse();
                        world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F);
                        event.damage *= 0.25f; // Only 25% Passes through
                    } else if (weapon.getItem() instanceof LOTRItemHammer) {
                        sword.damageItem((int) event.damage, player); // Hammers bypass the block better, but only deal 100% of the durability damage
                        player.clearItemInUse();
                        world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F);
                        event.damage *= 0.5f; // Only 50% Passes through
                    } else {
                        sword.damageItem((int) (event.damage/2), player); //Swords only deal 50% of durability damage
                        player.clearItemInUse();
                        world.playSoundAtEntity(player, "random.anvil_land", 1F, 2F);
                        event.damage = 0.0f;
                        cancel = true;
                    }
                }
            }
        }
        return cancel;
    }
    public static boolean fire_armor_repair_task(DamageEvent event) {
        boolean cancel = false;
        if (event.source.isFireDamage() && event.defender instanceof EntityPlayer) {
            EntityPlayer player = (EntityPlayer) event.defender;
            for (ItemStack armor : player.inventory.armorInventory) {
                if (armor != null && LOTREnchantmentHelper.hasEnchant(armor, LOTREnchantment.getEnchantmentByName("fireRepair"))) {
                    int currentDamage = armor.getItemDamage();
                    int reduction = (int) event.damage;
                    int newDamage = currentDamage - 2*reduction;

                    if (newDamage < 0) {
                        newDamage = 0;
                    }

                    armor.setItemDamage(newDamage);
                }
            }
        }
        return cancel;
    }
    public static boolean fix_hill_troll_chieftain_task(DamageEvent event) {
        boolean cancel = false;
        if (event.defender instanceof LOTREntityMountainTrollChieftain) {
            LOTREntityMountainTrollChieftain defender = (LOTREntityMountainTrollChieftain)event.defender;
            if (defender.getTrollArmorLevel() > 0)
                if (defender.getHealth() - event.damage <= 0.0F) {
                    ((IBossEntity)(Object)(defender)).change_phase();
                    cancel = true;
                }
        }
        return cancel;
    }
    public static boolean template_task(DamageEvent event) {
        boolean cancel = false;
        return cancel;
    }
}
