package dev.crucifixbeta.api.utils.player;

import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.world.BlockUtil;
import dev.crucifixbeta.mod.modules.impl.client.AntiCheat;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.packet.c2s.play.PickFromInventoryC2SPacket;
import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket;
import net.minecraft.screen.slot.SlotActionType;

@Environment(EnvType.CLIENT)
public class InventoryUtil implements Wrapper {
   static int lastSlot = -1;
   static int lastSelect = -1;

   public static void inventorySwap(int slot, int selectedSlot) {
      if (slot == lastSlot) {
         switchToSlot(lastSelect);
         lastSlot = -1;
         lastSelect = -1;
      } else if (slot - 36 != selectedSlot) {
         if (EntityUtil.inInventory()) {
            if (AntiCheat.INSTANCE.invSwapBypass.getValue()) {
               if (slot - 36 >= 0) {
                  lastSlot = slot;
                  lastSelect = selectedSlot;
                  switchToSlot(slot - 36);
                  return;
               }

               mc.getNetworkHandler().sendPacket(new PickFromInventoryC2SPacket(slot));
            } else {
               mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, slot, selectedSlot, SlotActionType.SWAP, mc.player);
               mc.player.getInventory().updateItems();
            }
         }
      }
   }

   public static void switchToSlot(int slot) {
      mc.player.getInventory().selectedSlot = slot;
      mc.getNetworkHandler().sendPacket(new UpdateSelectedSlotC2SPacket(slot));
   }

   public static int findItem(Item input) {
      for (int var1 = 0; var1 < 9; var1++) {
         Item var2 = mc.player.getInventory().getStack(var1).getItem();
         if (Item.getRawId(var2) == Item.getRawId(input)) {
            return var1;
         }
      }

      return -1;
   }

   public static boolean isItemInSlot(int slot, Item item) {
      if (slot < 0) {
         return false;
      } else {
         int var2 = slot >= 36 ? slot - 36 : slot;
         return var2 >= 0 && var2 < 36 ? mc.player.getInventory().getStack(var2).getItem() == item : false;
      }
   }

   public static boolean isItemInSlot(int slot, Class<?> clazz) {
      if (slot < 0) {
         return false;
      } else {
         int var2 = slot >= 36 ? slot - 36 : slot;
         if (var2 >= 0 && var2 < 36) {
            ItemStack var3 = mc.player.getInventory().getStack(var2);
            if (var3.isEmpty()) {
               return false;
            } else {
               return clazz.isInstance(var3.getItem()) ? true : var3.getItem() instanceof BlockItem && clazz.isInstance(((BlockItem)var3.getItem()).getBlock());
            }
         } else {
            return false;
         }
      }
   }

   public static boolean isItemInSlot(int slot, Block block) {
      if (slot < 0) {
         return false;
      } else {
         int var2 = slot >= 36 ? slot - 36 : slot;
         if (var2 >= 0 && var2 < 36) {
            ItemStack var3 = mc.player.getInventory().getStack(var2);
            return var3.getItem() instanceof BlockItem && ((BlockItem)var3.getItem()).getBlock() == block;
         } else {
            return false;
         }
      }
   }

   public static int getFood() {
      for (int var0 = 0; var0 < 9; var0++) {
         if (mc.player.getInventory().getStack(var0).getComponents().contains(DataComponentTypes.FOOD)) {
            return var0;
         }
      }

      return -1;
   }

   public static int getPotionCount(StatusEffect targetEffect) {
      int var1 = 0;

      for (int var2 = 35; var2 >= 0; var2--) {
         ItemStack var3 = mc.player.getInventory().getStack(var2);
         if (Item.getRawId(var3.getItem()) == Item.getRawId(Items.SPLASH_POTION)) {
            PotionContentsComponent var4 = var3.getOrDefault(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT);

            for (StatusEffectInstance var6 : var4.getEffects()) {
               if (var6.getEffectType().value() == targetEffect) {
                  var1 += var3.getCount();
               }
            }
         }
      }

      return var1;
   }

   public static int getItemCount(Class<?> clazz) {
      int var1 = 0;

      for (Entry var3 : getInventoryAndHotbarSlots().entrySet()) {
         if (((ItemStack)var3.getValue()).getItem() instanceof BlockItem && clazz.isInstance(((BlockItem)((ItemStack)var3.getValue()).getItem()).getBlock())) {
            var1 += ((ItemStack)var3.getValue()).getCount();
         }
      }

      return var1;
   }

   public static int getItemCount(Item item) {
      int var1 = 0;

      for (Entry var3 : getInventoryAndHotbarSlots().entrySet()) {
         if (((ItemStack)var3.getValue()).getItem() == item) {
            var1 += ((ItemStack)var3.getValue()).getCount();
         }
      }

      if (mc.player.getOffHandStack().getItem() == item) {
         var1 += mc.player.getOffHandStack().getCount();
      }

      return var1;
   }

   public static int findClass(Class<?> clazz) {
      for (int var1 = 0; var1 < 9; var1++) {
         ItemStack var2 = mc.player.getInventory().getStack(var1);
         if (var2 != ItemStack.EMPTY) {
            if (clazz.isInstance(var2.getItem())) {
               return var1;
            }

            if (var2.getItem() instanceof BlockItem && clazz.isInstance(((BlockItem)var2.getItem()).getBlock())) {
               return var1;
            }
         }
      }

      return -1;
   }

   public static int findClassInventorySlot(Class<?> clazz) {
      if (AntiCheat.INSTANCE.priorHotbar.getValue()) {
         for (int var1 = 0; var1 < 36; var1++) {
            ItemStack var2 = mc.player.getInventory().getStack(var1);
            if (var2 != ItemStack.EMPTY) {
               if (clazz.isInstance(var2.getItem())) {
                  return var1 < 9 ? var1 + 36 : var1;
               }

               if (var2.getItem() instanceof BlockItem && clazz.isInstance(((BlockItem)var2.getItem()).getBlock())) {
                  return var1 < 9 ? var1 + 36 : var1;
               }
            }
         }
      } else {
         for (int var3 = 35; var3 >= 0; var3--) {
            ItemStack var4 = mc.player.getInventory().getStack(var3);
            if (var4 != ItemStack.EMPTY) {
               if (clazz.isInstance(var4.getItem())) {
                  return var3 < 9 ? var3 + 36 : var3;
               }

               if (var4.getItem() instanceof BlockItem && clazz.isInstance(((BlockItem)var4.getItem()).getBlock())) {
                  return var3 < 9 ? var3 + 36 : var3;
               }
            }
         }
      }

      return -1;
   }

   public static int findBlock(Block blockIn) {
      for (int var1 = 0; var1 < 9; var1++) {
         ItemStack var2 = mc.player.getInventory().getStack(var1);
         if (var2 != ItemStack.EMPTY && var2.getItem() instanceof BlockItem && ((BlockItem)var2.getItem()).getBlock() == blockIn) {
            return var1;
         }
      }

      return -1;
   }

   public static int findUnBlock() {
      for (int var0 = 0; var0 < 9; var0++) {
         ItemStack var1 = mc.player.getInventory().getStack(var0);
         if (!(var1.getItem() instanceof BlockItem)) {
            return var0;
         }
      }

      return -1;
   }

   public static int findBlock() {
      for (int var0 = 0; var0 < 9; var0++) {
         ItemStack var1 = mc.player.getInventory().getStack(var0);
         if (var1.getItem() instanceof BlockItem
            && !BlockUtil.isClickable(Block.getBlockFromItem(var1.getItem()))
            && ((BlockItem)var1.getItem()).getBlock() != Blocks.COBWEB) {
            return var0;
         }
      }

      return -1;
   }

   public static int findBlockInventorySlot(Block block) {
      return findItemInventorySlot(block.asItem());
   }

   public static int findItemInventorySlot(Item item) {
      if (AntiCheat.INSTANCE.priorHotbar.getValue()) {
         return findItemInventorySlotFromZero(item.asItem());
      } else {
         for (int var1 = 35; var1 >= 0; var1--) {
            ItemStack var2 = mc.player.getInventory().getStack(var1);
            if (var2.getItem() == item) {
               return var1 < 9 ? var1 + 36 : var1;
            }
         }

         return -1;
      }
   }

   public static int findItemInventorySlotFromZero(Item item) {
      for (int var1 = 0; var1 < 36; var1++) {
         ItemStack var2 = mc.player.getInventory().getStack(var1);
         if (var2.getItem() == item) {
            return var1 < 9 ? var1 + 36 : var1;
         }
      }

      return -1;
   }

   public static Map<Integer, ItemStack> getInventoryAndHotbarSlots() {
      HashMap var0 = new HashMap();

      for (int var1 = 0; var1 <= 35; var1++) {
         var0.put(var1, mc.player.getInventory().getStack(var1));
      }

      return var0;
   }
}
