package com.zivilon.cinder_loe.mixins;

import com.zivilon.cinder_loe.util.DurableItemCrafter;
import cpw.mods.fml.common.FMLCommonHandler;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.SlotCrafting;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent;
import org.spongepowered.asm.mixin.Dynamic;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Overwrite;

import com.zivilon.cinder_loe.CinderLoE;

@Mixin(SlotCrafting.class)
public abstract class MixinSlotCrafting {
    @Shadow
    private final IInventory craftMatrix;
    @Shadow
    private EntityPlayer thePlayer;
    @Shadow
    protected void onCrafting(ItemStack p_75210_1_) {}

    public MixinSlotCrafting() {
        craftMatrix = null;
    }

    /**
    * @author Shinare
    * @reason Added support for crafting with item durability. To register items for durability crafting, refer to com.zivilon.cinder_loe.util.DurableItemCrafter
    */

    @Overwrite
    public void onPickupFromSlot(EntityPlayer p_82870_1_, ItemStack p_82870_2_) {
        FMLCommonHandler.instance().firePlayerCraftingEvent(p_82870_1_, p_82870_2_, craftMatrix);
        onCrafting(p_82870_2_);
        boolean hasExceptionItem = false;
        int arrow_count = 0;

        for (int i = 0; i < craftMatrix.getSizeInventory(); ++i) {
            ItemStack itemstack1 = craftMatrix.getStackInSlot(i);

            if (itemstack1 != null && DurableItemCrafter.exceptionItems.contains(itemstack1.getItem())) {
                hasExceptionItem = true;
            }
            if (itemstack1 != null && itemstack1.getItem() == Items.arrow) {
                arrow_count++;
            }
        }

        for (int i = 0; i < craftMatrix.getSizeInventory(); ++i) {
            ItemStack itemstack1 = craftMatrix.getStackInSlot(i);

            if (itemstack1 != null) {
                if (!hasExceptionItem && DurableItemCrafter.customItems.contains(itemstack1.getItem())) {
                    damage_item(itemstack1, i, 1, craftMatrix);
                } else {
                    craftMatrix.decrStackSize(i, 1);
                }

                if (itemstack1 != null && itemstack1.getItem().hasContainerItem(itemstack1)) {
                    ItemStack itemstack2 = itemstack1.getItem().getContainerItem(itemstack1);

                    if (itemstack2 != null && itemstack2.isItemStackDamageable() && itemstack2.getItemDamage() > itemstack2.getMaxDamage()) {
                        MinecraftForge.EVENT_BUS.post(new PlayerDestroyItemEvent(thePlayer, itemstack2));
                        continue;
                    }

                    if (!itemstack1.getItem().doesContainerItemLeaveCraftingGrid(itemstack1) || !thePlayer.inventory.addItemStackToInventory(itemstack2)) {
                        if (craftMatrix.getStackInSlot(i) == null) {
                            craftMatrix.setInventorySlotContents(i, itemstack2);
                        } else {
                            thePlayer.dropPlayerItemWithRandomChoice(itemstack2, false);
                        }
                    }
                }
            }
        }
    }

    @Dynamic
    public void damage_item(ItemStack item, int i, int damage, IInventory matrix) {
        item.setItemDamage(item.getItemDamage() + damage);
        if (item.getItemDamage() >= item.getMaxDamage()) {
            matrix.setInventorySlotContents(i, null); // Item breaks and is removed
        } else {
            matrix.setInventorySlotContents(i, item);
        }
    }
}
