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

import dev.crucifixbeta.CrucifixBeta;
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.world.BlockUtil;
import dev.crucifixbeta.core.Manager;
import dev.crucifixbeta.mod.modules.Module;
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 java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
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.Blocks;
import net.minecraft.block.ShulkerBoxBlock;
import net.minecraft.client.gui.screen.ingame.GenericContainerScreen;
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.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult.Type;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;

@Environment(EnvType.CLIENT)
public class AutoRegear extends Module {
   public static AutoRegear INSTANCE;
   private static final String CURRENT_KIT_FILE;
   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));
   public final BooleanSetting animation = this.add(new BooleanSetting("Animation", true));
   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 mine = this.add(new BooleanSetting("Mine", true));
   private final BooleanSetting autoClose = this.add(new BooleanSetting("AutoClose", true));
   private final BooleanSetting enderChest = this.add(new BooleanSetting("EnderChest", false));
   private final BooleanSetting fallbackPlace = this.add(new BooleanSetting("FallbackPlace", true));
   private final BindSetting placeKey = this.add(new BindSetting("PlaceKey", -1));
   private final Timer timer = new Timer();
   public final Timer timeoutTimer = new Timer();
   private final Map<Integer, ItemStack> desiredInventory = new HashMap<>();
   private final List<BlockPos> openList = new ArrayList<>();
   public BlockPos placePos;
   private BlockPos openPos;
   private BlockPos pendingMinePos;
   private boolean opened;
   private boolean wasPlaceKeyPressed;
   private boolean waitForNextTick;

   public AutoRegear() {
      super("AutoRegear", Module.Category.Combat);
      this.setChinese("\u81ea\u52a8\u8865\u7ed9");
      INSTANCE = this;
      this.loadSavedKit();
   }

   @Override
   public void onEnable() {
      this.resetState();
      if (this.desiredInventory.isEmpty()) {
         this.sendMessage("\u00a7cNo kit loaded. Use kit load <name>.");
         this.disable();
      }
   }

   @Override
   public void onDisable() {
      this.opened = false;
      this.pendingMinePos = null;
      if (this.mine.getValue() && this.placePos != null && mc.world != null && mc.world.getBlockState(this.placePos).getBlock() instanceof ShulkerBoxBlock) {
         this.clickMine(this.placePos);
      }

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

   public boolean loadKit(String name) {
      Map var2 = this.readKit(name);
      if (var2.isEmpty()) {
         this.sendMessage("§cKit [" + name + "] is empty or not found.");
         return false;
      } else {
         this.desiredInventory.clear();
         this.desiredInventory.putAll(var2);
         this.resetState();
         this.saveCurrentKit(name);
         this.sendMessage("§aLoaded kit [" + name + "].");
         return true;
      }
   }

   public boolean hasLoadedKit() {
      return !this.desiredInventory.isEmpty();
   }

   public Map<Integer, ItemStack> getDesiredInventory() {
      return new HashMap<>(this.desiredInventory);
   }

   public boolean isKitItemEqual(ItemStack stack1, ItemStack stack2) {
      return this.isItemEqual(stack1, stack2);
   }

   @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
            || mc.currentScreen instanceof GenericContainerScreen
            || this.isEnderChestGui();
         if (var2) {
            this.opened = true;
            if (this.openPos != null && !this.openList.contains(this.openPos)) {
               this.openList.add(this.openPos);
            }

            this.processCurrentContainer();
         } else {
            if (this.opened) {
               this.opened = false;
               BlockPos var3 = this.openPos;
               if (var3 != null && !this.openList.contains(var3)) {
                  this.openList.add(var3);
               }

               this.pendingMinePos = var3 != null && mc.world.getBlockState(var3).getBlock() instanceof ShulkerBoxBlock ? var3 : null;
               this.openPos = null;
               this.placePos = null;
            }

            if (this.pendingMinePos != null) {
               if (this.mine.getValue() && mc.world.getBlockState(this.pendingMinePos).getBlock() instanceof ShulkerBoxBlock) {
                  this.clickMine(this.pendingMinePos);
               }

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

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

            this.wasPlaceKeyPressed = var4;
            this.tryOpenPending();
            if (this.autoDisable.getValue() && this.openPos == null && this.placePos == null && this.timeoutTimer.passed((long)this.disableTime.getValueInt())) {
               this.disable();
            }
         }
      }
   }

   private void resetState() {
      this.opened = false;
      this.openPos = null;
      this.placePos = null;
      this.waitForNextTick = false;
      this.pendingMinePos = null;
      this.timeoutTimer.reset();
      this.timer.reset();
   }

   private void loadSavedKit() {
      try {
         File var1 = Manager.getFile("autoregear-current-kit.txt");
         if (var1.exists()) {
            try (BufferedReader var2 = new BufferedReader(new InputStreamReader(new FileInputStream(var1), StandardCharsets.UTF_8))) {
               String var3 = var2.readLine();
               if (var3 != null && !var3.isBlank()) {
                  Map var4 = this.readKit(var3.trim());
                  if (!var4.isEmpty()) {
                     this.desiredInventory.clear();
                     this.desiredInventory.putAll(var4);
                  }

                  return;
               }
            }
         }
      } catch (Exception var7) {
         var7.printStackTrace();
      }
   }

   private void saveCurrentKit(String name) {
      try (OutputStreamWriter var2 = new OutputStreamWriter(new FileOutputStream(Manager.getFile("autoregear-current-kit.txt")), StandardCharsets.UTF_8)) {
         var2.write(name);
      } catch (Exception var7) {
         var7.printStackTrace();
      }
   }

   private Map<Integer, ItemStack> readKit(String name) {
      HashMap var2 = new HashMap();

      try {
         File var3 = Manager.getFile(name + ".kit");
         if (!var3.exists()) {
            return var2;
         }

         String var5;
         try (BufferedReader var4 = new BufferedReader(new InputStreamReader(new FileInputStream(var3), StandardCharsets.UTF_8))) {
            while ((var5 = var4.readLine()) != null) {
               String[] var6 = var5.split(":", 2);
               if (var6.length >= 2) {
                  try {
                     int var7 = Integer.parseInt(var6[0]);
                     ItemStack var8 = this.parseKitStack(var6[1]);
                     if (!var8.isEmpty()) {
                        var2.put(var7, var8);
                     }
                  } catch (Exception var10) {
                  }
               }
            }
         }
      } catch (Exception var12) {
         var12.printStackTrace();
      }

      return var2;
   }

   private ItemStack parseKitStack(String rawKey) {
      boolean var2 = rawKey.endsWith(":turtle");
      boolean var3 = rawKey.endsWith(":strength");
      String var4 = rawKey;
      if (var2) {
         var4 = rawKey.substring(0, rawKey.length() - (":turtle").length());
      } else if (var3) {
         var4 = rawKey.substring(0, rawKey.length() - (":strength").length());
      }

      for (Item var6 : Registries.ITEM) {
         if (var6.getTranslationKey().equals(var4)) {
            ItemStack var7 = new ItemStack(var6);
            if (var2) {
               var7.set(DataComponentTypes.CUSTOM_NAME, Text.literal("turtle"));
            }

            if (var3) {
               var7.set(DataComponentTypes.CUSTOM_NAME, Text.literal("strength"));
            }

            return var7;
         }
      }

      return ItemStack.EMPTY;
   }

   private void doPlaceOrOpen() {
      if (this.desiredInventory.isEmpty()) {
         this.sendMessage("\u00a7cNo kit loaded. Use kit load <name>.");
      } else {
         BlockPos var1 = this.findExistingEnderChest();
         if (var1 != null) {
            this.openPos = var1;
            this.openContainer(var1);
         } else {
            AutoRegear.Placement var2 = this.findPlacement();
            if (var2 == null) {
               this.sendMessage("\u00a74No place position found.");
            } else {
               int var3 = this.findContainerItem();
               if (var3 == -1) {
                  this.sendMessage(this.enderChest.getValue() ? "\u00a74No shulkerbox or enderchest found." : "\u00a74No shulkerbox found.");
               } else {
                  int var4 = mc.player.getInventory().selectedSlot;
                  if (this.inventory.getValue()) {
                     InventoryUtil.inventorySwap(var3, var4);
                     this.placeBlock(var2);
                     InventoryUtil.inventorySwap(var3, var4);
                  } else {
                     InventoryUtil.switchToSlot(var3);
                     this.placeBlock(var2);
                     InventoryUtil.switchToSlot(var4);
                  }

                  this.placePos = var2.pos;
                  this.openPos = var2.pos;
                  this.waitForNextTick = true;
                  this.timer.reset();
               }
            }
         }
      }
   }

   private BlockPos findExistingEnderChest() {
      return !this.enderChest.getValue()
         ? null
         : BlockUtil.getSphere(this.range.getValueFloat())
            .stream()
            .filter(pos -> !this.openList.contains(pos))
            .filter(pos -> mc.player.squaredDistanceTo(pos.toCenterPos()) <= this.range.getValue() * this.range.getValue())
            .filter(pos -> mc.world.getBlockState(pos).getBlock() == Blocks.ENDER_CHEST)
            .filter(this::canOpen)
            .min(Comparator.comparingDouble(pos -> mc.player.squaredDistanceTo(pos.toCenterPos())))
            .orElse(null);
   }

   private AutoRegear.Placement findPlacement() {
      AutoRegear.Placement var1 = this.findCrosshairPlacement();
      if (var1 != null) {
         return var1;
      } else {
         return !this.fallbackPlace.getValue()
            ? null
            : BlockUtil.getSphere(this.range.getValueFloat())
               .stream()
               .map(this::validPlacement)
               .filter(placement -> placement != null)
               .min(Comparator.comparingDouble(placement -> mc.player.squaredDistanceTo(placement.pos.toCenterPos())))
               .orElse(null);
      }
   }

   private AutoRegear.Placement findCrosshairPlacement() {
      if (mc.crosshairTarget instanceof BlockHitResult var2 && var2.getType() == Type.BLOCK) {
         BlockPos var9 = var2.getBlockPos();
         Direction var3 = var2.getSide();
         ArrayList<BlockPos> var4 = new ArrayList<>();
         BlockPos var5 = var9.offset(var3);
         var4.add(var5);

         for (Direction var7 : net.minecraft.util.math.Direction.Type.HORIZONTAL) {
            var4.add(var5.offset(var7));
         }

         if (var3.getAxis().isHorizontal()) {
            var4.add(var5.up());
            var4.add(var9.up().offset(var3));

            for (Direction var12 : net.minecraft.util.math.Direction.Type.HORIZONTAL) {
               if (var12 != var3 && var12 != var3.getOpposite()) {
                  var4.add(var9.offset(var12).offset(var3));
               }
            }
         }

         for (BlockPos var13 : var4) {
            AutoRegear.Placement var8 = this.validPlacement(var13);
            if (var8 != null) {
               return var8;
            }
         }

         return null;
      }

      return null;
   }

   private AutoRegear.Placement validPlacement(BlockPos pos) {
      if (mc.player.squaredDistanceTo(pos.toCenterPos()) > this.range.getValue() * this.range.getValue()) {
         return null;
      } else if (!BlockUtil.clientCanPlace(pos, false)) {
         return null;
      } else {
         for (Direction var5 : Direction.values()) {
            if (var5 != Direction.UP) {
               BlockPos var6 = pos.offset(var5);
               if (BlockUtil.canClick(var6) && !BlockUtil.canReplace(var6) && BlockUtil.isStrictDirection(var6, var5.getOpposite())) {
                  Direction var7 = var5 == Direction.DOWN ? Direction.UP : var5.getOpposite();
                  if (this.isOpenDirectionClear(pos, var7)) {
                     return new AutoRegear.Placement(pos, var6, var5.getOpposite(), var7);
                  }
               }
            }
         }

         return null;
      }
   }

   private boolean canOpen(BlockPos pos) {
      Block var2 = mc.world.getBlockState(pos).getBlock();
      if (var2 == Blocks.ENDER_CHEST) {
         return mc.world.isAir(pos.up());
      } else if (var2 instanceof ShulkerBoxBlock) {
         Direction var3 = mc.world.getBlockState(pos).get(ShulkerBoxBlock.FACING);
         return this.isOpenDirectionClear(pos, var3);
      } else {
         return false;
      }
   }

   private boolean isOpenDirectionClear(BlockPos pos, Direction direction) {
      return mc.world.isAir(pos.offset(direction));
   }

   private void placeBlock(AutoRegear.Placement placement) {
      if (AntiRegear.INSTANCE != null) {
         AntiRegear.INSTANCE.addSafe(placement.pos);
      }

      BlockUtil.clickBlock(placement.supportPos, placement.clickSide, this.rotate.getValue());
   }

   private void tryOpenPending() {
      if (this.openPos != null && mc.currentScreen == null) {
         if (this.waitForNextTick) {
            this.waitForNextTick = false;
         } else if (mc.player.squaredDistanceTo(this.openPos.toCenterPos()) > this.range.getValue() * this.range.getValue()) {
            this.openPos = null;
            this.placePos = null;
         } else {
            Block var1 = mc.world.getBlockState(this.openPos).getBlock();
            if ((this.openPos.equals(this.placePos) && var1 instanceof ShulkerBoxBlock || var1 == Blocks.ENDER_CHEST) && this.canOpen(this.openPos)) {
               this.openContainer(this.openPos);
            }
         }
      }
   }

   private void openContainer(BlockPos pos) {
      if (!(mc.player.squaredDistanceTo(pos.toCenterPos()) > this.range.getValue() * this.range.getValue())) {
         BlockUtil.clickBlock(pos, BlockUtil.getClickSide(pos), this.rotate.getValue());
      }
   }

   private void clickMine(BlockPos pos) {
      Direction var2 = BlockUtil.getClickSide(pos);
      if (var2 == null) {
         var2 = Direction.UP;
      }

      if (this.rotate.getValue()) {
         CrucifixBeta.ROTATION.lookAt(pos.toCenterPos());
      }

      mc.interactionManager.attackBlock(pos, var2);
      mc.player.swingHand(Hand.MAIN_HAND);
      if (this.rotate.getValue()) {
         CrucifixBeta.ROTATION.snapBack();
      }
   }

   private int findContainerItem() {
      int var1 = this.findShulker();
      if (var1 == -1 && this.enderChest.getValue()) {
         if (this.inventory.getValue()) {
            for (int var2 = 0; var2 < 36; var2++) {
               ItemStack var3 = mc.player.getInventory().getStack(var2);
               if (!var3.isEmpty() && var3.getItem() == Items.ENDER_CHEST) {
                  return var2 < 9 ? var2 + 36 : var2;
               }
            }

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

   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;
            }
         }

         return -1;
      } else {
         return InventoryUtil.findClass(ShulkerBoxBlock.class);
      }
   }

   private boolean isEnderChestGui() {
      return this.openPos != null
         && mc.world.getBlockState(this.openPos).getBlock() == Blocks.ENDER_CHEST
         && mc.player.currentScreenHandler instanceof GenericContainerScreenHandler;
   }

   private void processCurrentContainer() {
      if (!(this.delay.getValue() > 0.0) || this.timer.passed((long)this.delay.getValueInt())) {
         ScreenHandler var1 = mc.player.currentScreenHandler;
         if (var1 instanceof ShulkerBoxScreenHandler || var1 instanceof GenericContainerScreenHandler) {
            boolean var2 = false;
            int var3 = this.delay.getValue() <= 0.0 ? 36 : 1;

            for (int var4 = 0; var4 < var3 && this.processOneItem(var1); var4++) {
               var2 = true;
            }

            if (var2) {
               this.timer.reset();
            } else {
               if (!this.isKitted() && this.hasNeededItem(var1)) {
                  if (this.autoDisable.getValue()) {
                     this.timeoutToDisable();
                  }
               } else {
                  if (!this.autoClose.getValue() || !this.timer.passed(150L)) {
                     return;
                  }

                  if (!this.clearCursor(var1)) {
                     return;
                  }

                  if (this.shouldKeepOpenForAntiRegear()) {
                     return;
                  }

                  mc.player.closeHandledScreen();
               }
            }
         }
      }
   }

   private boolean shouldKeepOpenForAntiRegear() {
      return this.openPos == null && AntiRegear.INSTANCE != null && AntiRegear.INSTANCE.isHandlingOpenedContainer();
   }

   private boolean processOneItem(ScreenHandler handler) {
      for (Entry var3 : this.desiredInventory.entrySet()) {
         int var4 = (Integer)var3.getKey();
         ItemStack var5 = (ItemStack)var3.getValue();
         ItemStack var6 = mc.player.getInventory().getStack(var4);
         if (this.needsItem(var6, var5)) {
            Slot var7 = this.findContainerSlot(handler, var5, var6);
            if (var7 != null) {
               int var8 = this.getWindowSlotId(handler, var4);
               mc.interactionManager.clickSlot(handler.syncId, var7.id, 0, SlotActionType.PICKUP, mc.player);
               mc.interactionManager.clickSlot(handler.syncId, var8, 0, SlotActionType.PICKUP, mc.player);
               this.clearCursor(handler, var7.id);
               return true;
            }
         }
      }

      return false;
   }

   private boolean clearCursor(ScreenHandler handler) {
      return this.clearCursor(handler, -1);
   }

   private boolean clearCursor(ScreenHandler handler, int preferredSlot) {
      if (mc.player.currentScreenHandler.getCursorStack().isEmpty()) {
         return true;
      } else {
         if (preferredSlot >= 0) {
            mc.interactionManager.clickSlot(handler.syncId, preferredSlot, 0, SlotActionType.PICKUP, mc.player);
            if (mc.player.currentScreenHandler.getCursorStack().isEmpty()) {
               return true;
            }
         }

         int var3 = this.getContainerSlots(handler);

         for (Slot var5 : handler.slots) {
            if (var5.id < var3 && var5.getStack().isEmpty()) {
               mc.interactionManager.clickSlot(handler.syncId, var5.id, 0, SlotActionType.PICKUP, mc.player);
               return mc.player.currentScreenHandler.getCursorStack().isEmpty();
            }
         }

         return false;
      }
   }

   private Slot findContainerSlot(ScreenHandler handler, ItemStack targetStack, ItemStack playerStack) {
      int var4 = this.getContainerSlots(handler);

      for (Slot var6 : handler.slots) {
         if (var6.id < var4 && this.isValidSourceStack(var6.getStack(), targetStack, playerStack)) {
            return var6;
         }
      }

      return null;
   }

   private boolean isValidSourceStack(ItemStack sourceStack, ItemStack targetStack, ItemStack playerStack) {
      return !sourceStack.isEmpty() && this.isItemEqual(sourceStack, targetStack)
         ? playerStack.isEmpty() || !this.isItemEqual(playerStack, targetStack) || ItemStack.areItemsAndComponentsEqual(sourceStack, playerStack)
         : false;
   }

   private boolean hasNeededItem(ScreenHandler handler) {
      for (Entry var3 : this.desiredInventory.entrySet()) {
         ItemStack var4 = mc.player.getInventory().getStack((Integer)var3.getKey());
         if (this.needsItem(var4, (ItemStack)var3.getValue()) && this.findContainerSlot(handler, (ItemStack)var3.getValue(), var4) != null) {
            return true;
         }
      }

      return false;
   }

   private boolean needsItem(ItemStack playerStack, ItemStack targetStack) {
      boolean var5 = !playerStack.isEmpty() && playerStack.getItem() instanceof BlockItem var4 && var4.getBlock() instanceof ShulkerBoxBlock;
      if (var5) {
         return false;
      } else if (playerStack.isEmpty()) {
         return true;
      } else {
         return !this.isItemEqual(playerStack, targetStack) ? true : playerStack.getCount() < playerStack.getMaxCount();
      }
   }

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

            var10000 = false;
         }

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

            var10000 = false;
         }

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

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

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

            boolean var14 = stack2.contains(DataComponentTypes.CUSTOM_NAME) && ("turtle").equals(stack2.getName().getString());
            boolean var15 = stack2.contains(DataComponentTypes.CUSTOM_NAME) && ("strength").equals(stack2.getName().getString());
            return var11 == var14 && var13 == var15;
         }
      } else {
         return false;
      }
   }

   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;
   }

   private int getContainerSlots(ScreenHandler handler) {
      return Math.max(0, handler.slots.size() - 36);
   }

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

   private void timeoutToDisable() {
      if (this.timeoutTimer.passed((long)this.disableTime.getValueInt())) {
         this.disable();
      }
   }

   static {

      CURRENT_KIT_FILE = "autoregear-current-kit.txt";
   }
@Environment(EnvType.CLIENT)
   private static record Placement(BlockPos pos, BlockPos supportPos, Direction clickSide, Direction openDirection) {
   }
}
