package dev.crucifixbeta.mod.modules.impl.misc;

import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.api.utils.render.TextUtil;
import dev.crucifixbeta.api.utils.world.BlockUtil;
import dev.crucifixbeta.core.Manager;
import dev.crucifixbeta.core.impl.FontManager;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.player.PacketMine;
import dev.crucifixbeta.mod.modules.settings.impl.BindSetting;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import dev.crucifixbeta.mod.modules.settings.impl.StringSetting;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
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.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
import net.minecraft.client.gui.screen.ingame.ShulkerBoxScreen;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.PotionContentsComponent;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.registry.Registries;
import net.minecraft.screen.GenericContainerScreenHandler;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.ShulkerBoxScreenHandler;
import net.minecraft.screen.slot.Slot;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.text.Text;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;

@Environment(EnvType.CLIENT)
public class ChestStealer extends Module {
   public static ChestStealer INSTANCE;
   private final StringSetting kit = this.add(new StringSetting("Kit", "1"));
   private final BooleanSetting rotate = this.add(new BooleanSetting("Rotate", true));
   private final BooleanSetting autoDisable = this.add(new BooleanSetting("AutoDisable", true));
   private final SliderSetting disableTime = this.add(new SliderSetting("DisableTime", 500, 0, 1000));
   private final SliderSetting delay = this.add(new SliderSetting("Delay", 0, 0, 1000));
   private final SliderSetting maxActions = this.add(new SliderSetting("MaxActions", 3, 1, 9));
   private final BooleanSetting grimStable = this.add(new BooleanSetting("GrimStable", true));
   private final BooleanSetting grimInstant = this.add(new BooleanSetting("GrimInstant", true, this.grimStable::getValue));
   private final SliderSetting grimDelay = this.add(
      new SliderSetting("GrimDelay", 50, 0, 200, () -> this.grimStable.getValue() && !this.grimInstant.getValue())
   );
   private final SliderSetting grimMaxActions = this.add(new SliderSetting("GrimMaxActions", 3, 1, 64, this.grimStable::getValue));
   private final SliderSetting range = this.add(new SliderSetting("Range", 4.0, 0.0, 6.0, 0.1));
   private final BooleanSetting inventory = this.add(new BooleanSetting("InventorySwap", true));
   private final BooleanSetting animation = this.add(new BooleanSetting("Animation", true));
   private final BooleanSetting silentOpen = this.add(new BooleanSetting("SilentOpen", true));
   private final SliderSetting chestHudX = this.add(new SliderSetting("ChestHudX", 0.0, -500.0, 500.0, 1.0, this.silentOpen::getValue));
   private final SliderSetting chestHudY = this.add(new SliderSetting("ChestHudY", 0.0, -500.0, 500.0, 1.0, this.silentOpen::getValue));
   private final BooleanSetting mine = this.add(new BooleanSetting("Mine", true));
   private final BooleanSetting enderChest = this.add(new BooleanSetting("EnderChest", false));
   private final BindSetting placeKey = this.add(new BindSetting("PlaceKey", -1));
   private final Timer timer = new Timer();
   private final Timer timeoutTimer = new Timer();
   private final Map<Integer, ItemStack> desiredInventory = new HashMap<>();
   private final List<BlockPos> openList = new ArrayList<>();
   private boolean wasPlaceKeyPressed;
   private boolean opened;
   private boolean stealing;
   private BlockPos placePos;
   private BlockPos openPos;

   public ChestStealer() {
      super("ChestStealer", Module.Category.Misc);
      this.setChinese("\u81ea\u52a8\u8865\u7ed9\u7bb1");
      INSTANCE = this;
   }

   public boolean shouldUseSilentContainerUi(Screen screen) {
      if (!this.isOn() || !this.silentOpen.getValue() || mc.player == null || mc.world == null) {
         return false;
      } else if (!(screen instanceof GenericContainerScreen) && !(screen instanceof ShulkerBoxScreen)) {
         return false;
      } else {
         ScreenHandler var2 = mc.player.currentScreenHandler;
         return !(var2 instanceof GenericContainerScreenHandler) && !(var2 instanceof ShulkerBoxScreenHandler) ? false : this.opened || this.stealing;
      }
   }

   public void renderSilentContainerUi(DrawContext ctx, ScreenHandler handler) {
      if (handler != null) {
         int var3 = Math.max(0, handler.slots.size() - 36);
         if (var3 > 0) {
            int var4 = Math.max(1, (var3 + 8) / 9);
            short var5 = 187;
            int var6 = 38 + var4 * 20;
            int var7 = (ctx.getScaledWindowWidth() - var5) / 2 + this.chestHudX.getValueInt();
            int var8 = (ctx.getScaledWindowHeight() - var6) / 2 + 56 + this.chestHudY.getValueInt();
            Color var9 = new Color(224, 80, 255, 230);
            Render2DUtil.drawRoundedRect(ctx.getMatrices(), (float)var7, (float)var8, (float)var5, (float)var6, 6.0F, new Color(15, 15, 20, 205));
            Render2DUtil.drawRoundedStroke(ctx.getMatrices(), (float)var7, (float)var8, (float)var5, (float)var6, 6.0F, new Color(255, 255, 255, 55), 16);
            Render2DUtil.drawRect(ctx.getMatrices(), (float)(var7 + 8), (float)(var8 + 28), (float)(var5 - 16), 1.0F, new Color(255, 255, 255, 42));
            String var10 = "Stealing...";
            TextUtil.drawString(ctx, var10, (double)(var7 + 10), (double)(var8 + 11), var9.getRGB(), FontManager.isCustomFontEnabled(), false);
            this.drawSilentSpinner(ctx, (float)(var7 + var5) - 18.0F, (float)var8 + 15.5F, 8.0F, var9);
            int var11 = var7 + 6;
            int var12 = var8 + 34;

            for (int var13 = 0; var13 < var3 && var13 < handler.slots.size(); var13++) {
               Slot var14 = handler.slots.get(var13);
               ItemStack var15 = var14.getStack();
               int var16 = var11 + var13 % 9 * 20;
               int var17 = var12 + var13 / 9 * 20;
               Render2DUtil.drawRoundedRect(ctx.getMatrices(), (float)(var16 - 1), (float)(var17 - 1), 18.0F, 18.0F, 3.0F, new Color(255, 255, 255, 18));
               if (!var15.isEmpty()) {
                  ctx.drawItem(var15, var16, var17);
                  ctx.drawItemInSlot(mc.textRenderer, var15, var16, var17);
               }
            }
         }
      }
   }

   private void drawSilentSpinner(DrawContext ctx, float centerX, float centerY, float radius, Color color) {
      float var6 = (float)(System.currentTimeMillis() % 1200L) / 1200.0F * 360.0F;
      float var7 = var6 + 230.0F;
      float var8 = centerX + (float)Math.cos(Math.toRadians((double)var6)) * radius;
      float var9 = centerY + (float)Math.sin(Math.toRadians((double)var6)) * radius;

      for (int var10 = 1; var10 <= 28; var10++) {
         float var11 = (float)var10 / 28.0F;
         float var12 = var6 + (var7 - var6) * var11;
         float var13 = centerX + (float)Math.cos(Math.toRadians((double)var12)) * radius;
         float var14 = centerY + (float)Math.sin(Math.toRadians((double)var12)) * radius;
         int var15 = Math.max(35, Math.min(230, (int)((float)color.getAlpha() * var11)));
         Render2DUtil.drawLine(ctx.getMatrices(), var8, var9, var13, var14, new Color(color.getRed(), color.getGreen(), color.getBlue(), var15).getRGB());
         var8 = var13;
         var9 = var14;
      }
   }

   @Override
   public void onEnable() {
      this.opened = false;
      this.openPos = null;
      this.placePos = null;
      this.timeoutTimer.reset();
      this.desiredInventory.clear();
      this.loadKit();
      if (this.desiredInventory.isEmpty()) {
         this.sendMessage("\u00a7cKit is empty or not found!");
         this.disable();
      }
   }

   @Override
   public void onDisable() {
      this.opened = false;
      if (this.mine.getValue() && this.placePos != null && PacketMine.INSTANCE != null) {
         PacketMine.INSTANCE.mine(this.placePos);
      }

      this.placePos = null;
      this.openPos = null;
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      if (mc.player != null && mc.world != null) {
         this.openList.removeIf(pos -> {
            Block var1 = mc.world.getBlockState(pos).getBlock();
            return !(var1 instanceof ShulkerBoxBlock) && var1 != Blocks.ENDER_CHEST;
         });
         boolean var2 = mc.player.currentScreenHandler instanceof ShulkerBoxScreenHandler;
         boolean var3 = mc.player.currentScreenHandler instanceof GenericContainerScreenHandler;
         boolean var4 = var2 || var3 && this.openPos != null && mc.world.getBlockState(this.openPos).getBlock() == Blocks.ENDER_CHEST;
         if (mc.currentScreen != null && var4) {
            this.opened = true;
            if (this.openPos != null && !this.openList.contains(this.openPos)) {
               this.openList.add(this.openPos);
            }

            ScreenHandler var7 = mc.player.currentScreenHandler;
            this.processContainer(var7, var7.syncId);
         } else {
            this.stealing = false;
            if (this.opened) {
               this.opened = false;
               this.placePos = null;
               if (this.mine.getValue()
                  && this.openPos != null
                  && PacketMine.INSTANCE != null
                  && mc.world.getBlockState(this.openPos).getBlock() instanceof ShulkerBoxBlock) {
                  PacketMine.INSTANCE.mine(this.openPos);
               }

               if (this.autoDisable.getValue()) {
                  this.disable();
                  return;
               }
            }

            boolean var5 = this.placeKey.isPressed();
            if (var5 && !this.wasPlaceKeyPressed && mc.currentScreen == null) {
               this.doPlace();
            }

            this.wasPlaceKeyPressed = var5;
            if (this.placePos != null) {
               Block var6 = mc.world.getBlockState(this.placePos).getBlock();
               if (var6 instanceof ShulkerBoxBlock || var6 == Blocks.ENDER_CHEST) {
                  this.openPos = this.placePos;
                  BlockUtil.clickBlock(this.placePos, BlockUtil.getClickSide(this.placePos), this.rotate.getValue());
               }
            }
         }
      }
   }

   private void loadKit() {
      File var1 = Manager.getFile(this.kit.getValue() + ".kit");
      if (var1.exists()) {
         String var3;
         try (BufferedReader var2 = new BufferedReader(new InputStreamReader(new FileInputStream(var1), StandardCharsets.UTF_8))) {
            while ((var3 = var2.readLine()) != null) {
               String[] var4 = var3.split(":", 2);
               if (var4.length >= 2) {
                  int var5 = Integer.parseInt(var4[0]);
                  String var6 = var4[1];
                  boolean var7 = var6.endsWith(":turtle");
                  boolean var8 = var6.endsWith(":strength");
                  if (var7) {
                     var6 = var6.replace(":turtle", "");
                  }

                  if (var8) {
                     var6 = var6.replace(":strength", "");
                  }

                  Item var9 = Items.AIR;

                  for (Item var11 : Registries.ITEM) {
                     if (var11.getTranslationKey().equals(var6)) {
                        var9 = var11;
                        break;
                     }
                  }

                  if (var9 != Items.AIR) {
                     ItemStack var15 = new ItemStack(var9);
                     if (var7) {
                        var15.set(DataComponentTypes.CUSTOM_NAME, Text.literal("turtle"));
                     }

                     if (var8) {
                        var15.set(DataComponentTypes.CUSTOM_NAME, Text.literal("strength"));
                     }

                     this.desiredInventory.put(var5, var15);
                  }
               }
            }
         } catch (Exception var14) {
            var14.printStackTrace();
         }
      }
   }

   private void doPlace() {
      int var1 = mc.player.getInventory().selectedSlot;
      double var2 = 100.0;
      BlockPos var4 = null;

      for (BlockPos var6 : BlockUtil.getSphere(this.range.getValueFloat())) {
         if (mc.world.isAir(var6.up())) {
            BlockPos var7 = var6.down();
            BlockState var8 = mc.world.getBlockState(var7);
            if (BlockUtil.clientCanPlace(var6, false)
               && BlockUtil.isStrictDirection(var7, Direction.UP)
               && BlockUtil.canClick(var7)
               && !var8.isAir()
               && var8.isSolidBlock(mc.world, var7)
               && (var4 == null || (double)MathHelper.sqrt((float)mc.player.squaredDistanceTo(var6.toCenterPos())) < var2)) {
               var2 = (double)MathHelper.sqrt((float)mc.player.squaredDistanceTo(var6.toCenterPos()));
               var4 = var6;
            }
         }
      }

      if (var4 == null) {
         this.sendMessage("\u00a74No place position found.");
      } else {
         int var9 = this.findShulker();
         if (var9 == -1) {
            this.sendMessage(this.enderChest.getValue() ? "\u00a74No shulkerbox or enderchest found." : "\u00a74No shulkerbox found.");
         } else {
            if (this.inventory.getValue()) {
               InventoryUtil.inventorySwap(var9, var1);
               this.placeBlock(var4);
               this.placePos = var4;
               InventoryUtil.inventorySwap(var9, var1);
            } else {
               InventoryUtil.switchToSlot(var9);
               this.placeBlock(var4);
               this.placePos = var4;
               InventoryUtil.switchToSlot(var1);
            }

            this.timer.reset();
         }
      }
   }

   private void placeBlock(BlockPos pos) {
      BlockUtil.clickBlock(pos.down(), Direction.UP, this.rotate.getValue());
   }

   private int findShulker() {
      if (this.inventory.getValue()) {
         for (int var1 = 0; var1 < 36; var1++) {
            ItemStack var2 = mc.player.getInventory().getStack(var1);
            if (!var2.isEmpty() && var2.getItem() instanceof BlockItem var4 && var4.getBlock() instanceof ShulkerBoxBlock) {
               return var1 < 9 ? var1 + 36 : var1;
            }
         }
      } else {
         int var5 = InventoryUtil.findClass(ShulkerBoxBlock.class);
         if (var5 != -1) {
            return var5;
         }
      }

      if (!this.enderChest.getValue()) {
         return -1;
      } else if (this.inventory.getValue()) {
         for (int var6 = 0; var6 < 36; var6++) {
            if (mc.player.getInventory().getStack(var6).getItem() == Items.ENDER_CHEST) {
               return var6 < 9 ? var6 + 36 : var6;
            }
         }

         return -1;
      } else {
         return InventoryUtil.findItem(Items.ENDER_CHEST);
      }
   }

   private boolean isItemEqual(ItemStack stack1, ItemStack stack2) {
      if (stack1.isEmpty() && stack2.isEmpty()) {
         return true;
      } else if (!stack1.isEmpty() && !stack2.isEmpty()) {
         boolean var10000;
         label72: {
            if (stack1.getItem() instanceof BlockItem var4 && var4.getBlock() instanceof ShulkerBoxBlock) {
               var10000 = true;
               break label72;
            }

            var10000 = false;
         }

         boolean var5;
         label67: {
            var5 = var10000;
            if (stack2.getItem() instanceof BlockItem var11 && var11.getBlock() instanceof ShulkerBoxBlock) {
               var10000 = true;
               break label67;
            }

            var10000 = false;
         }

         boolean var13 = var10000;
         if (var5 && var13) {
            return true;
         } else if (!ItemStack.areItemsEqual(stack1, stack2)) {
            return false;
         } else if (stack1.getItem() != Items.SPLASH_POTION) {
            return true;
         } else {
            boolean var12 = false;
            boolean var14 = false;
            PotionContentsComponent var7 = stack1.getOrDefault(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT);

            for (StatusEffectInstance var9 : var7.getEffects()) {
               if (var9.getEffectType().value() == StatusEffects.RESISTANCE.value()) {
                  var12 = true;
               }

               if (var9.getEffectType().value() == StatusEffects.STRENGTH.value()) {
                  var14 = true;
               }
            }

            boolean var15 = false;
            boolean var16 = false;
            if (stack2.contains(DataComponentTypes.CUSTOM_NAME)) {
               String var10 = stack2.getName().getString();
               var15 = ("turtle").equals(var10);
               var16 = ("strength").equals(var10);
            }

            return var12 == var15 && var14 == var16;
         }
      } else {
         return false;
      }
   }

   private void processContainer(ScreenHandler handler, int syncId) {
      if (mc.player != null && mc.player.currentScreenHandler == handler) {
         this.stealing = false;
         int var3 = 0;
         int var4 = this.getMaxActionsPerTick(handler);
         int var5 = this.getActionDelay(handler);

         while (
            var3 < var4
               && mc.player != null
               && mc.player.currentScreenHandler == handler
               && (this.grimInstant.getValue() || this.shouldAnimate(handler) || this.timer.passedMs((double)var5))
               && (!this.shouldAnimate(handler) || this.timer.passedMs((double)var5))
               && this.tryStealOne(handler, syncId)
         ) {
            var3++;
            this.stealing = true;
            if (!this.grimInstant.getValue() || this.shouldAnimate(handler)) {
               this.timer.reset();
               if (var5 > 0) {
                  return;
               }
            }
         }

         if (this.grimInstant.getValue() && !this.shouldAnimate(handler) && var3 > 0) {
            this.timer.reset();
         }

         if (var3 <= 0 || this.grimInstant.getValue() && !this.shouldAnimate(handler)) {
            if (!mc.player.currentScreenHandler.getCursorStack().isEmpty()) {
               ItemStack var6 = mc.player.currentScreenHandler.getCursorStack();
               if (this.isShulker(var6) && this.isShulkerContainer(handler)) {
                  int var8 = this.findEmptyPlayerSlot();
                  if (var8 != -1) {
                     mc.interactionManager.clickSlot(syncId, var8 + (handler.slots.size() - 36), 0, SlotActionType.PICKUP, mc.player);
                     this.timer.reset();
                  }

                  return;
               }

               int var7 = this.findEmptySlot(handler);
               if (var7 != -1) {
                  mc.interactionManager.clickSlot(syncId, var7, 0, SlotActionType.PICKUP, mc.player);
                  this.timer.reset();
                  return;
               }
            }

            if (this.isKitted() && mc.player != null) {
               if (this.shouldAnimate(handler) && !this.timer.passedMs((double)var5)) {
                  return;
               }

               mc.player.closeHandledScreen();
               this.stealing = false;
            }
         }
      } else {
         this.stealing = false;
      }
   }

   private int getActionDelay(ScreenHandler handler) {
      if (this.shouldAnimate(handler)) {
         int var2 = this.delay.getValueInt();
         if (this.grimStable.getValue()) {
            var2 = Math.max(
               var2, handler instanceof GenericContainerScreenHandler ? this.grimDelay.getValueInt() : Math.max(0, this.grimDelay.getValueInt() / 2)
            );
         }

         return Math.max(50, var2);
      } else if (!this.grimStable.getValue()) {
         return this.delay.getValueInt();
      } else {
         return this.grimInstant.getValue()
            ? 0
            : Math.max(
               this.delay.getValueInt(),
               handler instanceof GenericContainerScreenHandler ? this.grimDelay.getValueInt() : Math.max(0, this.grimDelay.getValueInt() / 2)
            );
      }
   }

   private int getMaxActionsPerTick(ScreenHandler handler) {
      if (this.shouldAnimate(handler)) {
         return 1;
      } else if (!this.grimStable.getValue()) {
         return this.maxActions.getValueInt();
      } else if (this.grimInstant.getValue()) {
         return this.grimMaxActions.getValueInt();
      } else {
         return handler instanceof GenericContainerScreenHandler
            ? Math.min(this.maxActions.getValueInt(), this.grimMaxActions.getValueInt())
            : Math.min(this.maxActions.getValueInt(), Math.max(1, this.grimMaxActions.getValueInt() + 1));
      }
   }

   private boolean shouldAnimate(ScreenHandler handler) {
      return this.animation.getValue() && handler != null;
   }

   private int getWindowSlotId(ScreenHandler handler, int targetSlot) {
      int var3 = handler.slots.size() - 36;
      return targetSlot < 9 ? targetSlot + var3 + 27 : targetSlot + var3 - 9;
   }

   private boolean shouldMergeStack(ItemStack playerStack, ItemStack targetStack) {
      return !playerStack.isEmpty()
         && playerStack.getMaxCount() > 1
         && this.isItemEqual(playerStack, targetStack)
         && playerStack.getCount() < playerStack.getMaxCount();
   }

   private boolean moveStackToTarget(ScreenHandler handler, int syncId, int sourceSlotId, int targetSlot) {
      int var5 = this.getWindowSlotId(handler, targetSlot);
      mc.interactionManager.clickSlot(syncId, sourceSlotId, 0, SlotActionType.PICKUP, mc.player);
      mc.interactionManager.clickSlot(syncId, var5, 0, SlotActionType.PICKUP, mc.player);
      if (!mc.player.currentScreenHandler.getCursorStack().isEmpty()) {
         ItemStack var6 = mc.player.currentScreenHandler.getCursorStack();
         if (this.isShulker(var6) && this.isShulkerContainer(handler)) {
            int var7 = this.findEmptyPlayerSlot();
            if (var7 != -1) {
               mc.interactionManager.clickSlot(syncId, var7 + (handler.slots.size() - 36), 0, SlotActionType.PICKUP, mc.player);
            }
         } else {
            mc.interactionManager.clickSlot(syncId, sourceSlotId, 0, SlotActionType.PICKUP, mc.player);
         }
      }

      return true;
   }

   private boolean tryStealOne(ScreenHandler handler, int syncId) {
      return this.tryStealOne(handler, syncId, true) || this.tryStealOne(handler, syncId, false);
   }

   private boolean tryStealOne(ScreenHandler handler, int syncId, boolean hotbarOnly) {
      for (Entry var5 : this.desiredInventory.entrySet()) {
         if (mc.player == null || mc.player.currentScreenHandler != handler) {
            return false;
         }

         int var6 = (Integer)var5.getKey();
         if (var6 < 9 == hotbarOnly) {
            ItemStack var7 = (ItemStack)var5.getValue();
            ItemStack var8 = mc.player.getInventory().getStack(var6);
            boolean var9 = var8.isEmpty() || !this.isItemEqual(var8, var7) || var8.getCount() < var8.getMaxCount();
            if (var9) {
               int var10 = handler.slots.size() - 36;

               for (Slot var12 : handler.slots) {
                  if (var12.id < var10 && !var12.getStack().isEmpty() && this.isItemEqual(var12.getStack(), var7)) {
                     if (this.animation.getValue()) {
                        mc.interactionManager.clickSlot(syncId, var12.id, 0, SlotActionType.QUICK_MOVE, mc.player);
                        return true;
                     }

                     if (this.shouldMergeStack(var8, var7)) {
                        return this.moveStackToTarget(handler, syncId, var12.id, var6);
                     }

                     if (var6 < 9) {
                        if (this.isShulker(var8) && this.isShulkerContainer(handler)) {
                           return this.moveStackToTarget(handler, syncId, var12.id, var6);
                        }

                        mc.interactionManager.clickSlot(syncId, var12.id, var6, SlotActionType.SWAP, mc.player);
                        return true;
                     }

                     return this.moveStackToTarget(handler, syncId, var12.id, var6);
                  }
               }
            }
         }
      }

      return false;
   }

   private boolean isShulker(ItemStack stack) {
      return !stack.isEmpty() && stack.getItem() instanceof BlockItem var3 && var3.getBlock() instanceof ShulkerBoxBlock;
   }

   private boolean isShulkerContainer(ScreenHandler handler) {
      return handler instanceof ShulkerBoxScreenHandler;
   }

   private int findEmptyPlayerSlot() {
      for (int var1 = 0; var1 < 36; var1++) {
         if (mc.player.getInventory().getStack(var1).isEmpty()) {
            return var1;
         }
      }

      return -1;
   }

   private int findEmptySlot(ScreenHandler handler) {
      for (Slot var3 : handler.slots) {
         if (var3.getStack().isEmpty()) {
            return var3.id;
         }
      }

      return -1;
   }

   private boolean isKitted() {
      for (Entry var2 : this.desiredInventory.entrySet()) {
         ItemStack var3 = mc.player.getInventory().getStack((Integer)var2.getKey());
         if (!this.isItemEqual(var3, (ItemStack)var2.getValue())) {
            return false;
         }

         if (!var3.isEmpty() && var3.getCount() < var3.getMaxCount()) {
            return false;
         }
      }

      return true;
   }
}
