package com.zivilon.cinder_loe.entity.projectile;

import com.zivilon.cinder_loe.CinderLoE;
import com.zivilon.cinder_loe.items.WarDart;
import lotr.common.entity.projectile.LOTREntityProjectileBase;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.DamageSource;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.world.World;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;

public class EntityWarDart extends LOTREntityProjectileBase {

    public static int POSITION_WATCHER_ID = 20;
    public static int ITEMSTACK_WATCHER_ID = 18;

    public int xTile = -1;
    public int yTile = -1;
    public int zTile = -1;
    public Block inTile;
    public int inData = 0;
    public boolean inGround = false;
    public int shake = 0;
    public Entity shootingEntity;
    public int ticksInGround;
    public int ticksInAir = 0;
    public int canBePickedUp = 0;
    public int knockbackStrength = 0;

    public ItemStack item;
    public double damage;
    public int dart_type;

    public EntityWarDart(World world) {
        super(world);
    }

    public EntityWarDart(World world, EntityLivingBase thrower, ItemStack item) {
        super(world, thrower, item, 3.0F);
        this.item = item.copy(); // Store a copy of the item stack
        this.item.stackSize = 1;
        this.damage = WarDart.getDamageFromMeta(item.getItemDamage());
        this.dart_type = item.getItemDamage();
    }

    @Override
    protected void entityInit() {
        this.dataWatcher.addObject(17, Byte.valueOf((byte)0));
        this.dataWatcher.addObjectByDataType(ITEMSTACK_WATCHER_ID, 5);
        this.dataWatcher.addObject(POSITION_WATCHER_ID, ""); // Test adding object with ID
    }

    @Override
    public void setThrowableHeading(double x, double y, double z, float velocity, float inaccuracy) {
        float f2 = MathHelper.sqrt_double(x * x + y * y + z * z);
        x /= f2;
        y /= f2;
        z /= f2;
        x += this.rand.nextGaussian() * 0.0075D * inaccuracy;
        y += this.rand.nextGaussian() * 0.0075D * inaccuracy;
        z += this.rand.nextGaussian() * 0.0075D * inaccuracy;
        x *= velocity;
        y *= velocity;
        z *= velocity;
        this.motionX = x;
        this.motionY = y;
        this.motionZ = z;
        float f3 = MathHelper.sqrt_double(x * x + z * z);
        this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(x, z) * 180.0D / Math.PI);
        this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(y, f3) * 180.0D / Math.PI);
        this.ticksInGround = 0;
    }

    @Override
    public void onUpdate() {
        super.onUpdate();

        if (!this.worldObj.isRemote) {
            this.dataWatcher.updateObject(ITEMSTACK_WATCHER_ID, this.item);
            if (this.inGround) {
                String posString = this.xTile + "," + this.yTile + "," + this.zTile;
                this.dataWatcher.updateObject(POSITION_WATCHER_ID, posString);
            }
        } else {
            this.item = this.dataWatcher.getWatchableObjectItemStack(ITEMSTACK_WATCHER_ID);
            String posString = this.dataWatcher.getWatchableObjectString(POSITION_WATCHER_ID);
            if (!posString.equals("")) {
                String[] coords = posString.split(",");
                this.xTile = Integer.parseInt(coords[0]);
                this.yTile = Integer.parseInt(coords[1]);
                this.zTile = Integer.parseInt(coords[2]);
            }
        }

        // Ensure proper synchronization of position
        if (this.inGround) {
            this.motionX = this.motionY = this.motionZ = 0;
            this.posX = this.xTile + 0.5;
            this.posY = this.yTile + 0.5;
            this.posZ = this.zTile + 0.5;
        }
    }

    @Override
    protected void onCollideWithTarget(Entity entity) {
        super.onCollideWithTarget(entity);
        if (entity instanceof EntityLivingBase)
            if (this.dart_type == 14) {
                ((EntityLivingBase)entity).addPotionEffect(new PotionEffect(Potion.wither.id, 160));
        }
    }

    @Override
    public float getBaseImpactDamage(Entity entity, ItemStack itemStack) {
        return (float)this.damage;
    }

    @Override
    public void writeEntityToNBT(NBTTagCompound tagCompound) {
        // Do not call super.writeEntityToNBT to avoid recursion issues
        tagCompound.setInteger("xTile", this.xTile);
        tagCompound.setInteger("yTile", this.yTile);
        tagCompound.setInteger("zTile", this.zTile);
        tagCompound.setInteger("inTile", Block.getIdFromBlock(this.inTile));
        tagCompound.setByte("inData", (byte)this.inData);
        tagCompound.setByte("shake", (byte)this.shake);
        tagCompound.setByte("inGround", (byte)(this.inGround ? 1 : 0));
        tagCompound.setByte("pickup", (byte)this.canBePickedUp);
        tagCompound.setByte("Knockback", (byte)this.knockbackStrength);
        if (this.item != null) {
            NBTTagCompound itemTag = new NBTTagCompound();
            this.item.writeToNBT(itemTag);
            tagCompound.setTag("Item", itemTag);
        }
    }

    @Override
    public void readEntityFromNBT(NBTTagCompound tagCompound) {
        // Do not call super.readEntityFromNBT to avoid recursion issues
        this.xTile = tagCompound.getInteger("xTile");
        this.yTile = tagCompound.getInteger("yTile");
        this.zTile = tagCompound.getInteger("zTile");
        this.inTile = Block.getBlockById(tagCompound.getInteger("inTile"));
        this.inData = tagCompound.getByte("inData");
        this.shake = tagCompound.getByte("shake");
        this.inGround = tagCompound.getByte("inGround") == 1;
        this.canBePickedUp = tagCompound.getByte("pickup");
        this.knockbackStrength = tagCompound.getByte("Knockback");
        if (tagCompound.hasKey("Item")) {
            this.item = ItemStack.loadItemStackFromNBT(tagCompound.getCompoundTag("Item"));
            if (this.item != null) {
                this.damage = WarDart.getDamageFromMeta(this.item.getItemDamage());
                this.dart_type = this.item.getItemDamage();
                this.dataWatcher.updateObject(ITEMSTACK_WATCHER_ID, this.item); // Ensure DataWatcher is updated with the deserialized ItemStack
            }
        }
    }




    public IIcon getDartIcon() {
        WarDart itemDart = (WarDart) CinderLoE.warDart;
        return itemDart.getIconFromDamage(this.item.getItemDamage());
    }
}
