package com.zivilon.cinder_loe.mixins;

import com.zivilon.cinder_loe.CinderAchievement;
import com.zivilon.cinder_loe.droptables.DropTable;
import com.zivilon.cinder_loe.droptables.DropContext;
import com.zivilon.cinder_loe.util.ILootableEntity;
import com.zivilon.cinder_loe.util.IMixinEntityPlayer;
import com.zivilon.cinder_loe.util.PickpocketUtils;
import com.zivilon.cinder_loe.CinderLoE;

import lotr.common.LOTRLevelData;
import lotr.common.entity.npc.LOTREntityOlogHai;
import lotr.common.entity.npc.LOTRSpeech;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.EntityCreature;
import net.minecraft.entity.IEntityLivingData;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.*;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.IChatComponent;
import net.minecraft.world.World;

import lotr.common.entity.npc.LOTREntityNPC;
import lotr.common.entity.npc.LOTREntityQuestInfo;

import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.*;

import java.util.ArrayList;
import java.util.List;

@Mixin(LOTREntityNPC.class)
public abstract class MixinLOTREntityNPC extends EntityCreature implements ILootableEntity {
    public DropTable drop_table = null;
    public int last_pickpocket = 0;
    public float pickpocket_chance = 0.0F;

    @Shadow(remap = false)
    public LOTREntityQuestInfo questInfo;
    @Shadow(remap = false)
    public boolean speakTo(EntityPlayer entityplayer) {return false;}
    @Shadow(remap = false)
    public boolean canNPCTalk() {return false;}

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

    /**
     * @author
     * @reason
     */
    @Overwrite(remap = false)
    public boolean func_70085_c(EntityPlayer entityplayer) { // interact()
        if (PickpocketUtils.can_pickpocket(entityplayer, (LOTREntityNPC)(Object)this)) {
            boolean success = PickpocketUtils.pickpocket(entityplayer, (LOTREntityNPC)(Object)this);
            ((IMixinEntityPlayer)entityplayer).set_last_pickpocket_attempt((int)(System.currentTimeMillis() / 1000L));
            if (success) {
                List<ItemStack> drops = DropTable.generate_drops((LOTREntityNPC)(Object)this, new DropContext[]{DropContext.PICKPOCKET}, 0);
                ItemStack item = drops.get(DropTable.random.nextInt(drops.size()));

                if (entityplayer.inventory.addItemStackToInventory(item)) {
                    last_pickpocket = (int)(System.currentTimeMillis() / 1000L);
                } else {
                }
            } else {
                last_pickpocket = (int)(System.currentTimeMillis() / 1000L);
                ((LOTREntityNPC)(Object)this).setRevengeTarget(entityplayer);
                entityplayer.playSound("lotr:block.treasure.step", 1.0F, 1.0F);
                if ((LOTREntityNPC)(Object)this instanceof LOTREntityOlogHai) {
                    LOTRLevelData.getData(entityplayer).addAchievement(CinderAchievement.pickOlog);
                }
            }
            return true;
        }
        if (!this.worldObj.isRemote && canNPCTalk()) {
            if (this.questInfo.interact(entityplayer))
                return true;
            if (getAttackTarget() == null)
            if (speakTo(entityplayer))
                return true;
        }
        return super.interact(entityplayer);
    }

    @Inject(method = "func_110161_a", at = @At("HEAD"), remap = false) // onSpawnWithEgg
    private void onSpawned(IEntityLivingData entity, CallbackInfoReturnable<IEntityLivingData> cir) {
        PickpocketUtils.assign_drop_table((LOTREntityNPC)(Object)this);
    }

    /**
    * Add support for DropTables
    */
    @Inject(method = "func_70628_a", at = @At("HEAD"), remap = false) // dropFewItems
    private void loot_drop_table(boolean flag, int i, CallbackInfo ci) {
        DropContext[] context = new DropContext[3];
        int len = 0;
        context[len++] = DropContext.KILLED;

        if (((LOTREntityNPC)(Object)this).isBurning()) {
            context[len++] = DropContext.KILLED_BY_FIRE;
        }
        if (flag) {
            context[len++] = DropContext.KILLED_BY_PLAYER;
        }
        DropTable.drop_items((LOTREntityNPC)(Object)this, context, i);
    }
    @Inject(method = "func_70014_b", at = @At("TAIL"), remap = false) // writeEntityToNBT
    private void write_drop_table(NBTTagCompound tag, CallbackInfo ci) {
        if (drop_table != null) {
            tag.setTag("DropTable", DropTable.serialize_to_nbt(drop_table));
        }
        tag.setTag("last_pickpocket", new NBTTagInt(last_pickpocket));
        tag.setTag("pickpocket_chance", new NBTTagFloat(pickpocket_chance));
    }
    @Inject(method = "func_70037_a", at = @At("TAIL"), remap = false) // readEntityFromNBT
    private void read_drop_table(NBTTagCompound tag, CallbackInfo ci) {
        if (tag.hasKey("DropTable")) {
            this.drop_table = DropTable.deserialize_from_nbt(tag.getCompoundTag("DropTable"));
        }
        this.last_pickpocket = tag.getInteger("last_pickpocket");
        this.pickpocket_chance = tag.getFloat("pickpocket_chance");
    }

    @Override
    public void set_drop_table(DropTable table) {
        drop_table = table;
    }
    @Override
    public DropTable get_drop_table() {
        return drop_table;
    }
    @Override
    public void set_last_pickpocket(int i) {
        this.last_pickpocket = i;
    }
    @Override
    public int get_last_pickpocket() {
        return this.last_pickpocket;
    }
    @Override
    public void set_pickpocket_chance(Float f) {
        this.pickpocket_chance = f;
    }
    @Override
    public Float get_pickpocket_chance() {
        return this.pickpocket_chance;
    }
}
