package com.zivilon.cinder_loe.entity.boss;

import com.zivilon.cinder_loe.entity.projectile.EntityMorgulBlast;
import lotr.common.LOTRMod;
import lotr.common.enchant.LOTREnchantment;
import lotr.common.enchant.LOTREnchantmentHelper;
import lotr.common.entity.ai.*;
import lotr.common.entity.npc.LOTREntityMarshWraith;
import lotr.common.entity.npc.LOTREntityNPC;
import lotr.common.fac.LOTRFaction;
import lotr.common.quest.LOTRMiniQuest;
import lotr.common.world.structure.LOTRChestContents;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.*;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;

import java.util.Random;

public class CryptBoss extends LOTREntityNPC {

    private EntityAIBase meleeAttackAI = new LOTREntityAIAttackOnCollide(this, 2.0, false);
    private EntityAIBase rangedAttackAI = new LOTREntityAIRangedAttack(this, 1.5, 30, 50, 60.0f);

    //Copying Wraith temporarily
    public CryptBoss(World world) {
        super(world);
        setSize(0.8F, 2.5F);
        this.tasks.taskEntries.clear();
        this.tasks.addTask(0, (EntityAIBase)new EntityAISwimming((EntityLiving)this));
        //Causes crash
        //this.tasks.addTask(0, (EntityAIBase)new LOTREntityAIBossJumpAttack(this, 1.5, 0.02f));
        this.tasks.addTask(2, (EntityAIBase)new EntityAIWander((EntityCreature)this, 1.0));
        this.tasks.addTask(3, (EntityAIBase)new EntityAIWatchClosest2((EntityLiving)this, EntityPlayer.class, 12.0f, 0.02f));
        this.tasks.addTask(3, (EntityAIBase)new EntityAIWatchClosest2((EntityLiving)this, LOTREntityNPC.class, 8.0f, 0.02f));
        this.tasks.addTask(4, (EntityAIBase)new EntityAIWatchClosest((EntityLiving)this, EntityLiving.class, 10.0f, 0.02f));
        this.tasks.addTask(5, (EntityAIBase)new EntityAILookIdle((EntityLiving)this));
        addTargetTasks(true);
    }

    @Override
    public void sendSpeechBank(EntityPlayer entityplayer, String speechBank) {
        this.sendSpeechBank(entityplayer, speechBank, (LOTRMiniQuest)null);
    }

    protected void entityInit() {
        super.entityInit();
        this.dataWatcher.addObject(17, Integer.valueOf(0));
    }

    @Override
    protected void applyEntityAttributes() {
        super.applyEntityAttributes();
        this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(300.0);
        this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(32.0);
        this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.0);
        this.getEntityAttribute(npcAttackDamage).setBaseValue(16.0);
    }

    public int getDeathFadeTime() {
        return this.dataWatcher.getWatchableObjectInt(17);
    }

    public void setDeathFadeTime(int i) {
        this.dataWatcher.updateObject(17, Integer.valueOf(i));
    }

    public LOTRFaction getFaction() {
        return LOTRFaction.UTUMNO;
    }

    public void writeEntityToNBT(NBTTagCompound nbt) {
        super.writeEntityToNBT(nbt);
        nbt.setInteger("DeathFadeTime", getDeathFadeTime());
    }

    public void readEntityFromNBT(NBTTagCompound nbt) {
        super.readEntityFromNBT(nbt);
        setDeathFadeTime(nbt.getInteger("DeathFadeTime"));
    }

    @Override
    public void moveEntityWithHeading(float strafe, float forward) {
        // First, call the super method to preserve normal movement behavior
        super.moveEntityWithHeading(strafe, forward);

        // Check for water at the entity's feet
        int x = MathHelper.floor_double(this.posX);
        int y = MathHelper.floor_double(this.posY);
        int z = MathHelper.floor_double(this.posZ);

        boolean isWater = this.worldObj.getBlock(x, y, z).getMaterial() == Material.water ||
                this.worldObj.getBlock(x, y - 1, z).getMaterial() == Material.water; // Check below the entity too

        if (isWater) {
            this.onGround = true; // Treat water as solid ground
            this.motionY = 0.0; // Stop falling/sinking
            this.setPosition(this.posX, y + 1, this.posZ); // Adjust position to stay on top of the water
        }
    }


    public void setInWeb() {}

    @Override
    public void onLivingUpdate() {
        super.onLivingUpdate();
        if (this.worldObj.isRemote) {
            for (int l = 0; l < 1; ++l) {
                double d = this.posX + (double)this.width * MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.5, (double)0.5);
                double d1 = this.posY + (double)this.height * MathHelper.getRandomDoubleInRange((Random)this.rand, (double)0.4, (double)0.8);
                double d2 = this.posZ + (double)this.width * MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.5, (double)0.5);
                double d3 = MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.1, (double)0.1);
                double d4 = MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.2, (double)-0.05);
                double d5 = MathHelper.getRandomDoubleInRange((Random)this.rand, (double)-0.1, (double)0.1);
                if (this.rand.nextBoolean()) {
                    LOTRMod.proxy.spawnParticle("morgulPortal", d, d1, d2, d3, d4, d5);
                    continue;
                }
                this.worldObj.spawnParticle("smoke", d, d1, d2, d3, d4, d5);
            }
        }
    }

    @Override
    public void onAttackModeChange(LOTREntityNPC.AttackMode mode, boolean mounted) {
        if (mode == LOTREntityNPC.AttackMode.IDLE) {
            this.tasks.removeTask(this.meleeAttackAI);
            this.tasks.removeTask(this.rangedAttackAI);
            this.tasks.addTask(1, this.meleeAttackAI);
        }
        if (mode == LOTREntityNPC.AttackMode.MELEE) {
            this.tasks.removeTask(this.meleeAttackAI);
            this.tasks.removeTask(this.rangedAttackAI);
            this.tasks.addTask(1, this.meleeAttackAI);
        }
        if (mode == LOTREntityNPC.AttackMode.RANGED) {
            this.tasks.removeTask(this.meleeAttackAI);
            this.tasks.removeTask(this.rangedAttackAI);
            this.tasks.addTask(1, this.rangedAttackAI);
        }
    }

    @Override
    public void attackEntityWithRangedAttack(EntityLivingBase target, float f) {
        EntityMorgulBlast projectile = new EntityMorgulBlast(this.worldObj, (EntityLivingBase)this, target);
        projectile.leavesDamage = 16.0f;
        this.worldObj.spawnEntityInWorld((Entity)projectile);
        this.playSound("lotr:wraith.marshWraith_shoot", this.getSoundVolume(), this.getSoundPitch());
        this.swingItem();
    }

    public boolean attackEntityFrom(DamageSource damagesource, float f) {
        boolean vulnerable = false;
        Entity entity = damagesource.getEntity();
        if (entity instanceof EntityLivingBase && entity == damagesource.getSourceOfDamage()) {
            ItemStack itemstack = ((EntityLivingBase)entity).getHeldItem();
            if (itemstack != null && LOTREnchantmentHelper.hasEnchant(itemstack, LOTREnchantment.baneWight))
                vulnerable = true;
        }
        if (vulnerable && getDeathFadeTime() == 0) {
            boolean flag = super.attackEntityFrom(damagesource, f);
            return flag;
        }
        return false;
    }

    public void onDeath(DamageSource damagesource) {
        super.onDeath(damagesource);
        if (!((Entity)this).worldObj.isRemote)
            setDeathFadeTime(30);
    }

    protected void dropFewItems(boolean flag, int i) {
        super.dropFewItems(flag, i);
        int flesh = 1 + rand.nextInt(3) + rand.nextInt(i + 1);
        for (int l = 0; l < flesh; l++)
            dropItem(Items.rotten_flesh, 1);
        dropChestContents(LOTRChestContents.MARSH_REMAINS, 1, 3 + i);
    }

    public EnumCreatureAttribute getCreatureAttribute() {
        return EnumCreatureAttribute.UNDEAD;
    }

    protected String getHurtSound() {
        return "lotr:wight.hurt";
    }

    protected String getDeathSound() {
        return "lotr:wight.death";
    }

    public boolean handleWaterMovement() {
        return false;
    }

    protected void func_145780_a(int i, int j, int k, Block block) {}

    @Override
    public String getSpeechBank(EntityPlayer entityplayer) {
        if (this.isFriendlyAndAligned(entityplayer)) {
            return "corruptSpeak/all/neutral";
        }
        return "corruptSpeak/all/hostile";
    }
}
