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

import asm.accessors.IMinecraftClient;
import asm.accessors.IPlayerMoveC2SPacket;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.PacketEvent;
import dev.crucifixbeta.api.events.impl.PlaySoundEvent;
import dev.crucifixbeta.api.events.impl.TickEvent;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.math.MathUtil;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.api.utils.world.BlockUtil;
import dev.crucifixbeta.core.impl.CommandManager;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.exploit.BowBomb;
import dev.crucifixbeta.mod.modules.impl.exploit.Phase;
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.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.AirBlock;
import net.minecraft.block.Blocks;
import net.minecraft.block.TorchBlock;
import net.minecraft.client.gui.screen.DownloadingTerrainScreen;
import net.minecraft.client.sound.SoundInstance;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.Entity;
import net.minecraft.entity.boss.WitherEntity;
import net.minecraft.entity.projectile.FishingBobberEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket.Mode;
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
import net.minecraft.sound.SoundEvents;
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.Box;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.LightType;
import net.minecraft.world.RaycastContext;
import net.minecraft.world.RaycastContext.FluidHandling;
import net.minecraft.world.RaycastContext.ShapeType;

@Environment(EnvType.CLIENT)
public class AutoTool extends Module {
   private final BooleanSetting mine = this.add(new BooleanSetting("Mine", true));
   private final BooleanSetting fish = this.add(new BooleanSetting("Fish", true).setParent());
   private final BooleanSetting autoCast = this.add(new BooleanSetting("AutoCast", true, this.fish::isOpen));
   private final SliderSetting ticksAutoCast = this.add(new SliderSetting("TicksAutoCast", 10, 0, 60, this.fish::isOpen));
   private final SliderSetting ticksCatch = this.add(new SliderSetting("TicksCatch", 6, 0, 60, this.fish::isOpen));
   private final SliderSetting ticksThrow = this.add(new SliderSetting("TicksThrow", 14, 0, 60, this.fish::isOpen));
   private final BooleanSetting splashDetection = this.add(new BooleanSetting("SplashDetection", false, this.fish::isOpen));
   private final SliderSetting splashDetectionRange = this.add(new SliderSetting("DetectionRange", 10, 0, 60, this.fish::isOpen));
   private final BooleanSetting autoEat = this.add(new BooleanSetting("AutoEat", false).setParent());
   private final SliderSetting eatHunger = this.add(new SliderSetting("EatHunger", 10.0, 0.0, 19.0, 1.0, this.autoEat::isOpen));
   private final SliderSetting eatHealth = this.add(new SliderSetting("EatHealth", 20.0, 0.0, 35.9, 0.1, this.autoEat::isOpen));
   private final BooleanSetting eatAnyFood = this.add(new BooleanSetting("EatAnyFood", true, this.autoEat::isOpen));
   private final BooleanSetting eatOffhand = this.add(new BooleanSetting("EatOffhand", true, this.autoEat::isOpen));
   private final BooleanSetting eatRestoreSlot = this.add(new BooleanSetting("EatRestoreSlot", true, this.autoEat::isOpen));
   private final BooleanSetting eatPauseIfUsing = this.add(new BooleanSetting("EatPauseIfUsing", true, this.autoEat::isOpen));
   private final BooleanSetting portalGod = this.add(new BooleanSetting("PortalGod", false, this.autoEat::isOpen).setParent());
   private final BooleanSetting portalApplyPos = this.add(
      new BooleanSetting("PortalApplyPos", true, () -> this.autoEat.isOpen() && this.portalGod.isOpen())
   );
   private final BooleanSetting antiHunger = this.add(new BooleanSetting("AntiHunger", false, this.autoEat::isOpen).setParent());
   private final BooleanSetting antiHungerSprint = this.add(
      new BooleanSetting("AntiHungerSprint", false, () -> this.autoEat.isOpen() && this.antiHunger.isOpen())
   );
   private final BooleanSetting antiHungerGround = this.add(
      new BooleanSetting("AntiHungerGround", true, () -> this.autoEat.isOpen() && this.antiHunger.isOpen())
   );
   private final BooleanSetting autoTorch = this.add(new BooleanSetting("AutoTorch", false).setParent());
   private final SliderSetting torchDelay = this.add(new SliderSetting("TorchDelay", 50.0, 0.0, 10000.0, 1.0, this.autoTorch::isOpen));
   private final SliderSetting torchRange = this.add(new SliderSetting("TorchRange", 5.0, 0.0, 6.0, 1.0, this.autoTorch::isOpen));
   private final BooleanSetting torchOnlyRender = this.add(new BooleanSetting("TorchOnlyRender", false, this.autoTorch::isOpen));
   private final BooleanSetting torchThroughWall = this.add(new BooleanSetting("TorchThroughWall", false, this.autoTorch::isOpen));
   private final SliderSetting torchLightLevel = this.add(new SliderSetting("TorchLightLevel", 7.0, 0.0, 15.0, 1.0, this.autoTorch::isOpen));
   private final BooleanSetting autoWither = this.add(new BooleanSetting("AutoWither", false).setParent());
   private final SliderSetting witherDelay = this.add(new SliderSetting("WitherDelay", 3.0, 1.0, 10.0, 1.0, this.autoWither::isOpen));
   private final BooleanSetting witherAutoRename = this.add(new BooleanSetting("WitherAutoRename", true, this.autoWither::isOpen));
   private final SliderSetting witherRenameDelay = this.add(new SliderSetting("WitherRenameDelay", 5.0, 1.0, 20.0, 1.0, this.autoWither::isOpen));
   private final StringSetting witherName = this.add(
      new StringSetting("WitherName", "Wither Boss", () -> this.autoWither.isOpen() && this.witherAutoRename.getValue())
   );
   private final Timer torchTimer = new Timer();
   private final Timer portalTimer = new Timer();
   private boolean ticksEnabled;
   private int ticksToRightClick;
   private int ticksData;
   private int autoCastTimer;
   private boolean autoCastEnabled;
   private int autoCastCheckTimer;
   private boolean eating;
   private boolean eatingOffhand;
   private int prevSlot = -1;
   private int activeSlot = -1;
   private double teleportX;
   private double teleportY;
   private double teleportZ;
   private boolean cancelTeleport;
   private int witherPlaceTimer;
   private int witherRenameTimer;
   private int witherStage;
   private BlockPos witherPos;
   private boolean witherSpawned;

   public AutoTool() {
      super("AutoTool", Module.Category.Player);
      this.setChinese("\u81ea\u52a8\u5de5\u5177");
   }

   @Override
   public void onEnable() {
      this.ticksEnabled = false;
      this.autoCastEnabled = false;
      this.autoCastCheckTimer = 0;
      this.stopEating();
      this.resetPortalGod();
      this.resetWitherBuilder(false);
   }

   @Override
   public void onDisable() {
      this.stopEating();
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      if (!nullCheck()) {
         this.autoFish();
         this.autoTool();
         this.runAutoEat();
         this.runAutoWither();
      }
   }

   public void autoTool() {
      if (this.mine.getValue()) {
         if (mc.crosshairTarget instanceof BlockHitResult var2) {
            BlockPos var3 = var2.getBlockPos();
            if (!mc.world.isAir(var3)) {
               int var4 = getTool(var3);
               if (var4 != -1 && mc.options.attackKey.isPressed()) {
                  mc.player.getInventory().selectedSlot = var4;
               }
            }
         }
      }
   }

   @EventListener
   private void onPlaySound(PlaySoundEvent event) {
      if (!nullCheck() && this.fish.getValue()) {
         SoundInstance var2 = event.sound;
         FishingBobberEntity var3 = mc.player.fishHook;
         if (var3 != null) {
            if (var2.getId().getPath().equals("entity.fishing_bobber.splash")
               && (
                  !this.splashDetection.getValue()
                     || MathUtil.getDistance(var3.getX(), var3.getY(), var3.getZ(), var2.getX(), var2.getY(), var2.getZ())
                        <= this.splashDetectionRange.getValue()
               )) {
               this.ticksEnabled = true;
               this.ticksToRightClick = this.ticksCatch.getValueInt();
               this.ticksData = 0;
            }
         }
      }
   }

   public void autoFish() {
      if (this.fish.getValue()) {
         if (this.autoCastCheckTimer <= 0) {
            this.autoCastCheckTimer = 30;
            if (this.autoCast.getValue()
               && !this.ticksEnabled
               && !this.autoCastEnabled
               && mc.player.fishHook == null
               && mc.player.getMainHandStack().getItem() == Items.FISHING_ROD) {
               this.autoCastTimer = 0;
               this.autoCastEnabled = true;
            }
         } else {
            this.autoCastCheckTimer--;
         }

         if (this.autoCastEnabled) {
            this.autoCastTimer++;
            if ((double)this.autoCastTimer > this.ticksAutoCast.getValue()) {
               this.autoCastEnabled = false;
               ((IMinecraftClient)mc).invokeDoItemUse();
            }
         }

         if (this.ticksEnabled && this.ticksToRightClick <= 0) {
            if (this.ticksData == 0) {
               ((IMinecraftClient)mc).invokeDoItemUse();
               this.ticksToRightClick = this.ticksThrow.getValueInt();
               this.ticksData = 1;
            } else if (this.ticksData == 1) {
               ((IMinecraftClient)mc).invokeDoItemUse();
               this.ticksEnabled = false;
            }
         }

         this.ticksToRightClick--;
      }
   }

   @EventListener
   private void onKey(KeyEvent event) {
      if (mc.options.useKey.isPressed()) {
         this.ticksEnabled = false;
      }
   }

   private void runAutoEat() {
      if (!this.autoEat.getValue()) {
         this.stopEating();
      } else if (!this.eatPauseIfUsing.getValue() || !mc.player.isUsingItem() || this.eating) {
         boolean var1 = EntityUtil.getHealth(mc.player) <= this.eatHealth.getValueFloat()
            || (float)mc.player.getHungerManager().getFoodLevel() <= this.eatHunger.getValueFloat();
         if (!var1) {
            this.stopEating();
         } else if (!this.eatOffhand.getValue()
            || mc.player.getOffHandStack().getItem() != Items.ENCHANTED_GOLDEN_APPLE && mc.player.getOffHandStack().getItem() != Items.GOLDEN_APPLE) {
            int var2 = InventoryUtil.findItem(Items.ENCHANTED_GOLDEN_APPLE);
            if (var2 == -1) {
               var2 = InventoryUtil.findItem(Items.GOLDEN_APPLE);
            }

            if (var2 == -1 && this.eatAnyFood.getValue()) {
               var2 = InventoryUtil.getFood();
            }

            if (var2 != -1) {
               this.startEatingMainhand(var2);
            } else {
               this.stopEating();
            }
         } else {
            this.startEatingOffhand();
         }
      }
   }

   private void startEatingOffhand() {
      if (!this.eating) {
         this.prevSlot = mc.player.getInventory().selectedSlot;
      }

      this.eating = true;
      this.eatingOffhand = true;
      this.activeSlot = -1;
      mc.options.useKey.setPressed(true);
      mc.interactionManager.interactItem(mc.player, Hand.OFF_HAND);
   }

   private void startEatingMainhand(int slot) {
      if (!this.eating) {
         this.prevSlot = mc.player.getInventory().selectedSlot;
      }

      this.eating = true;
      this.eatingOffhand = false;
      this.activeSlot = slot;
      InventoryUtil.switchToSlot(slot);
      mc.options.useKey.setPressed(true);
   }

   private void stopEating() {
      if (this.eating) {
         mc.options.useKey.setPressed(false);
         if (mc.player == null) {
            this.eating = false;
            this.eatingOffhand = false;
            this.prevSlot = -1;
            this.activeSlot = -1;
         } else {
            if (this.eatRestoreSlot.getValue()
               && !this.eatingOffhand
               && this.prevSlot != -1
               && this.activeSlot != -1
               && mc.player.getInventory().selectedSlot == this.activeSlot) {
               InventoryUtil.switchToSlot(this.prevSlot);
            }

            this.eating = false;
            this.eatingOffhand = false;
            this.prevSlot = -1;
            this.activeSlot = -1;
         }
      }
   }

   @EventListener(
      priority = -100
   )
   public void onPacketSend(PacketEvent.Send event) {
      if (this.autoEat.getValue() && this.antiHunger.getValue()) {
         if (!BowBomb.send && !AutoPearl.throwing && !Phase.INSTANCE.isOn()) {
            Packet var2 = event.getPacket();
            if (var2 instanceof ClientCommandC2SPacket var3 && this.antiHungerSprint.getValue() && var3.getMode() == Mode.START_SPRINTING) {
               event.cancel();
            }

            if (var2 instanceof PlayerMoveC2SPacket
               && this.antiHungerGround.getValue()
               && mc.player.fallDistance <= 0.0F
               && !mc.interactionManager.isBreakingBlock()) {
               ((IPlayerMoveC2SPacket)var2).setOnGround(false);
            }
         }
      }
   }

   @EventListener
   public void onPacketInbound(PacketEvent.Receive event) {
      if (!nullCheck()) {
         if (this.autoEat.getValue() && this.portalGod.getValue()) {
            this.handlePortalGodPacket(event);
         }

         if (this.autoWither.getValue()
            && this.witherSpawned
            && event.getPacket() instanceof PlaySoundS2CPacket var3
            && var3.getSound().value() == SoundEvents.ENTITY_WITHER_SPAWN) {
            this.witherRenameTimer = this.witherRenameDelay.getValueInt();
         }
      }
   }

   private void handlePortalGodPacket(PacketEvent.Receive event) {
      if (mc.currentScreen instanceof DownloadingTerrainScreen) {
         this.cancelTeleport = true;
         mc.currentScreen = null;
         this.portalTimer.reset();
      }

      if (event.getPacket() instanceof PlayerPositionLookS2CPacket var3) {
         if (this.portalApplyPos.getValue() && !mc.player.isRiding()) {
            this.teleportX = var3.getX();
            this.teleportY = var3.getY();
            this.teleportZ = var3.getZ();
            mc.player.setPosition(var3.getX(), var3.getY(), var3.getZ());
         }

         event.cancel();
      }
   }

   @EventListener
   public void onTick(TickEvent event) {
      if (!nullCheck()) {
         this.runPortalGodTick(event);
         this.runAutoTorch(event);
      }
   }

   private void runPortalGodTick(TickEvent event) {
      if (this.autoEat.getValue() && this.portalGod.getValue()) {
         if (event.isPre() && this.teleportX != 0.0 && this.teleportY != 0.0 && this.teleportZ != 0.0 && this.cancelTeleport) {
            mc.player.setPosition(this.teleportX, this.teleportY, this.teleportZ);
            if (this.portalTimer.passed(2500L)) {
               this.cancelTeleport = false;
            }
         }
      }
   }

   private void resetPortalGod() {
      this.teleportX = 0.0;
      this.teleportY = 0.0;
      this.teleportZ = 0.0;
      this.cancelTeleport = false;
   }

   private void runAutoTorch(TickEvent event) {
      if (this.autoTorch.getValue() && event.isPost() && mc.currentScreen == null && !this.torchOnlyRender.getValue()) {
         if (this.torchTimer.passedMs(this.torchDelay.getValue())) {
            int var2 = this.findHotbarItem(Items.TORCH);
            if (var2 != -1) {
               int var3 = mc.player.getInventory().selectedSlot;
               int var4 = 0;

               for (BlockPos var6 : this.getSphere(this.torchRange.getValueInt())) {
                  if (var4 >= 1) {
                     break;
                  }

                  if ((!this.torchThroughWall.getValue() || !this.behindWall(var6))
                     && !(mc.world.getBlockState(var6).getBlock() instanceof TorchBlock)
                     && !(mc.world.getBlockState(var6.down()).getBlock() instanceof TorchBlock)
                     && mc.world.isAir(var6)
                     && !mc.world.isAir(var6.down())
                     && !mc.world.getBlockState(var6.down()).isReplaceable()
                     && !this.hasPlayerEntity(var6)
                     && mc.world.getLightLevel(LightType.BLOCK, var6) <= this.torchLightLevel.getValueInt()) {
                     InventoryUtil.switchToSlot(var2);
                     BlockUtil.placeBlock(var6, false, true);
                     var4++;
                     InventoryUtil.switchToSlot(var3);
                  }
               }

               this.torchTimer.reset();
            }
         }
      }
   }

   private boolean behindWall(BlockPos pos) {
      Vec3d var2 = new Vec3d((double)pos.getX() + 0.5, (double)pos.getY() + 1.7, (double)pos.getZ() + 0.5);
      BlockHitResult var3 = mc.world.raycast(new RaycastContext(mc.player.getEyePos(), var2, ShapeType.COLLIDER, FluidHandling.NONE, mc.player));
      return var3 != null && var3.getType() != Type.MISS;
   }

   private boolean hasPlayerEntity(BlockPos pos) {
      return mc.world.getPlayers().stream().anyMatch(player -> player.getBlockPos().equals(pos));
   }

   private List<BlockPos> getSphere(int radius) {
      ArrayList<BlockPos> var2 = new ArrayList<>();
      BlockPos var3 = mc.player.getBlockPos();

      for (int var4 = -radius; var4 <= radius; var4++) {
         for (int var5 = -radius; var5 <= radius; var5++) {
            for (int var6 = -radius; var6 <= radius; var6++) {
               if (var4 * var4 + var5 * var5 + var6 * var6 <= radius * radius) {
                  var2.add(var3.add(var4, var5, var6));
               }
            }
         }
      }

      var2.sort((a, b) -> Double.compare(a.getSquaredDistance(var3), b.getSquaredDistance(var3)));
      return var2;
   }

   private void runAutoWither() {
      if (!this.autoWither.getValue()) {
         this.resetWitherBuilder(false);
      } else {
         if (this.witherPos == null) {
            this.resetWitherBuilder(true);
            CommandManager.sendMessage("[AutoTool] AutoWither started. Put 4 soul sand and 3 skulls in your hotbar.");
         }

         if (this.witherSpawned) {
            this.handleWitherRename();
         } else if (!this.hasRequiredWitherItems()) {
            CommandManager.sendMessage("[AutoTool] AutoWither missing materials: 4 soul sand and 3 wither skulls are required.");
            this.autoWither.setValue(false);
         } else if (this.witherPlaceTimer > 0) {
            this.witherPlaceTimer--;
         } else {
            switch (this.witherStage) {
               case 0:
                  this.placeWitherSoulSandBase();
                  break;
               case 1:
                  this.placeWitherSoulSandTop();
                  break;
               case 2:
                  this.placeWitherSkulls();
                  break;
               case 3:
                  CommandManager.sendMessage("[AutoTool] AutoWither build finished.");
                  this.witherSpawned = true;
                  if (!this.witherAutoRename.getValue()) {
                     this.autoWither.setValue(false);
                  }
                  break;
               default:
                  this.autoWither.setValue(false);
            }
         }
      }
   }

   private void resetWitherBuilder(boolean start) {
      this.witherPlaceTimer = 0;
      this.witherRenameTimer = 0;
      this.witherStage = 0;
      this.witherSpawned = false;
      this.witherPos = start && mc.player != null ? mc.player.getBlockPos().offset(mc.player.getHorizontalFacing(), 2) : null;
   }

   private void placeWitherSoulSandBase() {
      if (mc.world.getBlockState(this.witherPos).getBlock() != Blocks.SOUL_SAND) {
         this.placeWitherBlock(this.witherPos, Items.SOUL_SAND);
         this.witherPlaceTimer = this.witherDelay.getValueInt();
      } else {
         this.witherStage = 1;
      }
   }

   private void placeWitherSoulSandTop() {
      BlockPos[] var1 = new BlockPos[]{this.witherPos.up(), this.witherPos.up().west(), this.witherPos.up().east()};

      for (BlockPos var5 : var1) {
         if (mc.world.getBlockState(var5).getBlock() != Blocks.SOUL_SAND) {
            this.placeWitherBlock(var5, Items.SOUL_SAND);
            this.witherPlaceTimer = this.witherDelay.getValueInt();
            return;
         }
      }

      this.witherStage = 2;
   }

   private void placeWitherSkulls() {
      BlockPos var1 = this.witherPos.up(2);
      BlockPos var2 = this.witherPos.west().up(2);
      BlockPos var3 = this.witherPos.east().up(2);
      boolean var4 = mc.world.getBlockState(var1).getBlock() == Blocks.WITHER_SKELETON_SKULL;
      boolean var5 = mc.world.getBlockState(var2).getBlock() == Blocks.WITHER_SKELETON_SKULL;
      boolean var6 = mc.world.getBlockState(var3).getBlock() == Blocks.WITHER_SKELETON_SKULL;
      if (var4 && var5 && var6) {
         this.witherStage = 3;
      } else if (!var4) {
         this.placeWitherSkull(var1, Direction.UP);
         this.witherPlaceTimer = this.witherDelay.getValueInt();
      } else if (!var5) {
         this.placeWitherSkull(var2, Direction.EAST);
         this.witherPlaceTimer = this.witherDelay.getValueInt();
      } else {
         this.placeWitherSkull(var3, Direction.WEST);
         this.witherPlaceTimer = this.witherDelay.getValueInt();
      }
   }

   private void placeWitherBlock(BlockPos pos, Item item) {
      int var3 = this.findHotbarItem(item);
      if (var3 != -1) {
         InventoryUtil.switchToSlot(var3);
         mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, new BlockHitResult(Vec3d.ofCenter(pos), Direction.UP, pos, false));
      }
   }

   private void placeWitherSkull(BlockPos pos, Direction direction) {
      int var3 = this.findHotbarItem(Items.WITHER_SKELETON_SKULL);
      if (var3 != -1) {
         InventoryUtil.switchToSlot(var3);
         BlockPos var4 = pos.down();
         mc.interactionManager.interactBlock(mc.player, Hand.MAIN_HAND, new BlockHitResult(Vec3d.ofCenter(var4), direction, var4, false));
      }
   }

   private boolean hasRequiredWitherItems() {
      return this.countHotbarItem(Items.WITHER_SKELETON_SKULL) >= 3 && this.countHotbarItem(Items.SOUL_SAND) >= 4;
   }

   private int countHotbarItem(Item item) {
      int var2 = 0;

      for (int var3 = 0; var3 < 9; var3++) {
         ItemStack var4 = mc.player.getInventory().getStack(var3);
         if (var4.getItem() == item) {
            var2 += var4.getCount();
         }
      }

      return var2;
   }

   private int findHotbarItem(Item item) {
      for (int var2 = 0; var2 < 9; var2++) {
         if (mc.player.getInventory().getStack(var2).getItem() == item) {
            return var2;
         }
      }

      return -1;
   }

   private void handleWitherRename() {
      if (this.witherAutoRename.getValue()) {
         if (this.witherRenameTimer > 0) {
            this.witherRenameTimer--;
         } else {
            int var1 = this.findNamedNameTag();
            if (var1 == -1) {
               CommandManager.sendMessage("[AutoTool] AutoWither needs a named name tag in your hotbar: " + this.witherName.getValue());
               this.autoWither.setValue(false);
            } else {
               BlockPos var2 = mc.player.getBlockPos();
               Box var3 = new Box(
                  (double)(var2.getX() - 5),
                  (double)(var2.getY() - 5),
                  (double)(var2.getZ() - 5),
                  (double)(var2.getX() + 5),
                  (double)(var2.getY() + 5),
                  (double)(var2.getZ() + 5)
               );
               List var4 = mc.world.getEntitiesByClass(WitherEntity.class, var3, entity -> true);
               if (!var4.isEmpty()) {
                  InventoryUtil.switchToSlot(var1);
                  mc.interactionManager.interactEntity(mc.player, (Entity)var4.get(0), Hand.MAIN_HAND);
                  this.autoWither.setValue(false);
               }
            }
         }
      }
   }

   private int findNamedNameTag() {
      String var1 = this.witherName.getValue();

      for (int var2 = 0; var2 < 9; var2++) {
         ItemStack var3 = mc.player.getInventory().getStack(var2);
         if (var3.getItem() == Items.NAME_TAG && var3.getName() != null && var3.getName().getString().equals(var1)) {
            return var2;
         }
      }

      return -1;
   }

   public static int getTool(BlockPos pos) {
      int var1 = -1;
      float var2 = 1.0F;

      for (int var3 = 0; var3 < 9; var3++) {
         ItemStack var4 = mc.player.getInventory().getStack(var3);
         if (var4 != ItemStack.EMPTY) {
            float var5 = (float)EnchantmentHelper.getLevel(
               mc.world.getRegistryManager().get(Enchantments.EFFICIENCY.getRegistryRef()).getEntry(Enchantments.EFFICIENCY).get(), var4
            );
            float var6 = var4.getMiningSpeedMultiplier(mc.world.getBlockState(pos));
            if (mc.world.getBlockState(pos).getBlock() instanceof AirBlock) {
               return -1;
            }

            if (var5 + var6 > var2) {
               var2 = var5 + var6;
               var1 = var3;
            }
         }
      }

      return var1;
   }
}
