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

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.api.utils.player.MovementUtil;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.movement.ElytraFly;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.EnumSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import java.util.HashMap;
import java.util.Map.Entry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.component.type.ItemEnchantmentsComponent;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.enchantment.Enchantments;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ArmorItem;
import net.minecraft.item.ElytraItem;
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.PlayerInteractItemC2SPacket;
import net.minecraft.screen.slot.SlotActionType;
import net.minecraft.util.Hand;

@Environment(EnvType.CLIENT)
public class AutoArmor extends Module {
   public static AutoArmor INSTANCE;
   private final EnumSetting<AutoArmor.EnchantPriority> head = this.add(new EnumSetting<>("Head", AutoArmor.EnchantPriority.Protection));
   private final EnumSetting<AutoArmor.EnchantPriority> body = this.add(new EnumSetting<>("Body", AutoArmor.EnchantPriority.Protection));
   private final EnumSetting<AutoArmor.EnchantPriority> tights = this.add(new EnumSetting<>("Tights", AutoArmor.EnchantPriority.Protection));
   private final EnumSetting<AutoArmor.EnchantPriority> feet = this.add(new EnumSetting<>("Feet", AutoArmor.EnchantPriority.Protection));
   private final BooleanSetting ignoreCurse = this.add(new BooleanSetting("IgnoreCurse", true));
   private final BooleanSetting noMove = this.add(new BooleanSetting("NoMove", false));
   private final SliderSetting delay = this.add(new SliderSetting("Delay", 3.0, 0.0, 10.0, 1.0));
   private final BooleanSetting autoElytra = this.add(new BooleanSetting("AutoElytra", true));
   private final EnumSetting<AutoArmor.HotbarSwapMode> hotbarSwap = this.add(new EnumSetting<>("HotbarSwap", AutoArmor.HotbarSwapMode.Swap));
   private final EnumSetting<AutoArmor.InventorySwapMode> inventorySwap = this.add(
      new EnumSetting<>("InventorySwap", AutoArmor.InventorySwapMode.ClickSlot)
   );
   private int tickDelay = 0;

   public AutoArmor() {
      super("AutoArmor", Module.Category.Player);
      this.setChinese("\u81ea\u52a8\u7a7f\u7532");
      INSTANCE = this;
   }

   @EventListener
   public void onUpdate(UpdateEvent event) {
      if (EntityUtil.inInventory()) {
         if (mc.player.playerScreenHandler == mc.player.currentScreenHandler) {
            if (!MovementUtil.isMoving() || !this.noMove.getValue()) {
               if (this.tickDelay > 0) {
                  this.tickDelay--;
               } else {
                  this.tickDelay = this.delay.getValueInt();
                  HashMap<EquipmentSlot, int[]> var2 = new HashMap<>(4);
                  var2.put(EquipmentSlot.FEET, new int[]{36, this.getProtection(mc.player.getInventory().getStack(36)), -1, -1});
                  var2.put(EquipmentSlot.LEGS, new int[]{37, this.getProtection(mc.player.getInventory().getStack(37)), -1, -1});
                  var2.put(EquipmentSlot.CHEST, new int[]{38, this.getProtection(mc.player.getInventory().getStack(38)), -1, -1});
                  var2.put(EquipmentSlot.HEAD, new int[]{39, this.getProtection(mc.player.getInventory().getStack(39)), -1, -1});

                  for (int var3 = 0; var3 < 36; var3++) {
                     if ((
                           mc.player.getInventory().getStack(var3).getItem() instanceof ArmorItem
                              || mc.player.getInventory().getStack(var3).getItem() == Items.ELYTRA
                        )
                        && (
                           mc.player.getInventory().getStack(var3).getItem() != Items.ELYTRA
                              || (!ElytraFly.INSTANCE.isOff() || !this.autoElytra.getValue())
                                 && (!ElytraFly.INSTANCE.isOn() || !ElytraFly.INSTANCE.packet.getValue())
                        )) {
                        int var4 = this.getProtection(mc.player.getInventory().getStack(var3));
                        EquipmentSlot var5 = mc.player.getInventory().getStack(var3).getItem() instanceof ElytraItem
                           ? EquipmentSlot.CHEST
                           : ((ArmorItem)mc.player.getInventory().getStack(var3).getItem()).getSlotType();

                        for (Entry<EquipmentSlot, int[]> var7 : var2.entrySet()) {
                           if (this.autoElytra.getValue() && ElytraFly.INSTANCE.isOn() && var7.getKey() == EquipmentSlot.CHEST) {
                              if ((
                                    mc.player.getInventory().getStack(38).isEmpty()
                                       || !(mc.player.getInventory().getStack(38).getItem() instanceof ElytraItem)
                                       || !ElytraItem.isUsable(mc.player.getInventory().getStack(38))
                                 )
                                 && (
                                    ((int[])var7.getValue())[2] == -1
                                       || mc.player.getInventory().getStack(((int[])var7.getValue())[2]).isEmpty()
                                       || !(mc.player.getInventory().getStack(((int[])var7.getValue())[2]).getItem() instanceof ElytraItem)
                                       || !ElytraItem.isUsable(mc.player.getInventory().getStack(((int[])var7.getValue())[2]))
                                 )
                                 && !mc.player.getInventory().getStack(var3).isEmpty()
                                 && mc.player.getInventory().getStack(var3).getItem() instanceof ElytraItem
                                 && ElytraItem.isUsable(mc.player.getInventory().getStack(var3))) {
                                 ((int[])var7.getValue())[2] = var3;
                              }
                           } else if (var4 > 0 && var7.getKey() == var5 && var4 > ((int[])var7.getValue())[1] && var4 > ((int[])var7.getValue())[3]) {
                              ((int[])var7.getValue())[2] = var3;
                              ((int[])var7.getValue())[3] = var4;
                           }
                        }
                     }
                  }

                  for (Entry<EquipmentSlot, int[]> var9 : var2.entrySet()) {
                     if (((int[])var9.getValue())[2] != -1) {
                        if (((int[])var9.getValue())[2] < 9) {
                           switch ((AutoArmor.HotbarSwapMode)this.hotbarSwap.getValue()) {
                              case Swap:
                                 int var11 = 44 - ((int[])var9.getValue())[0];
                                 mc.interactionManager
                                    .clickSlot(mc.player.currentScreenHandler.syncId, var11, ((int[])var9.getValue())[2], SlotActionType.SWAP, mc.player);
                                 EntityUtil.syncInventory();
                                 break;
                              case Switch:
                                 int var10 = mc.player.getInventory().selectedSlot;
                                 InventoryUtil.switchToSlot(((int[])var9.getValue())[2]);
                                 sendSequencedPacket(
                                    id -> new PlayerInteractItemC2SPacket(
                                          Hand.MAIN_HAND, id, CrucifixBeta.ROTATION.getLastYaw(), CrucifixBeta.ROTATION.getLastPitch()
                                       )
                                 );
                                 InventoryUtil.switchToSlot(var10);
                           }
                        } else if (mc.player.playerScreenHandler == mc.player.currentScreenHandler) {
                           int var12 = 44 - ((int[])var9.getValue())[0];
                           int var13 = ((int[])var9.getValue())[2];
                           switch ((AutoArmor.InventorySwapMode)this.inventorySwap.getValue()) {
                              case ClickSlot:
                                 mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, var13, 0, SlotActionType.PICKUP, mc.player);
                                 mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, var12, 0, SlotActionType.PICKUP, mc.player);
                                 if (((int[])var9.getValue())[1] != -1) {
                                    mc.interactionManager.clickSlot(mc.player.currentScreenHandler.syncId, var13, 0, SlotActionType.PICKUP, mc.player);
                                 }
                                 break;
                              case Pick:
                                 mc.getNetworkHandler().sendPacket(new PickFromInventoryC2SPacket(var13));
                                 sendSequencedPacket(
                                    id -> new PlayerInteractItemC2SPacket(
                                          Hand.MAIN_HAND, id, CrucifixBeta.ROTATION.getLastYaw(), CrucifixBeta.ROTATION.getLastPitch()
                                       )
                                 );
                                 mc.getNetworkHandler().sendPacket(new PickFromInventoryC2SPacket(var13));
                           }

                           EntityUtil.syncInventory();
                        }

                        return;
                     }
                  }
               }
            }
         }
      }
   }

   private int getProtection(ItemStack is) {
      if (is.getItem() instanceof ArmorItem || is.getItem() == Items.ELYTRA) {
         int var2 = 0;
         EquipmentSlot var5;
         if (is.getItem() instanceof ArmorItem var4) {
            var5 = var4.getSlotType();
         } else {
            var5 = EquipmentSlot.BODY;
         }

         if (is.getItem() instanceof ElytraItem) {
            if (!ElytraItem.isUsable(is)) {
               return 0;
            }

            var2 = 1;
         }

         byte var8 = 1;
         byte var6 = 1;
         switch (var5) {
            case HEAD:
               if (this.head.is(AutoArmor.EnchantPriority.Protection)) {
                  var6 *= 2;
               } else {
                  var8 *= 2;
               }
               break;
            case BODY:
               if (this.body.is(AutoArmor.EnchantPriority.Protection)) {
                  var6 *= 2;
               } else {
                  var8 *= 2;
               }
               break;
            case LEGS:
               if (this.tights.is(AutoArmor.EnchantPriority.Protection)) {
                  var6 *= 2;
               } else {
                  var8 *= 2;
               }
               break;
            case FEET:
               if (this.feet.is(AutoArmor.EnchantPriority.Protection)) {
                  var6 *= 2;
               } else {
                  var8 *= 2;
               }
         }

         if (is.hasEnchantments()) {
            ItemEnchantmentsComponent var7 = EnchantmentHelper.getEnchantments(is);
            if (var7.getEnchantments()
               .contains(mc.world.getRegistryManager().get(Enchantments.PROTECTION.getRegistryRef()).getEntry(Enchantments.PROTECTION).get())) {
               var2 += var7.getLevel(mc.world.getRegistryManager().get(Enchantments.PROTECTION.getRegistryRef()).getEntry(Enchantments.PROTECTION).get())
                  * var6;
            }

            if (var7.getEnchantments()
               .contains(mc.world.getRegistryManager().get(Enchantments.BLAST_PROTECTION.getRegistryRef()).getEntry(Enchantments.BLAST_PROTECTION).get())) {
               var2 += var7.getLevel(
                     mc.world.getRegistryManager().get(Enchantments.BLAST_PROTECTION.getRegistryRef()).getEntry(Enchantments.BLAST_PROTECTION).get()
                  )
                  * var8;
            }

            if (var7.getEnchantments()
                  .contains(mc.world.getRegistryManager().get(Enchantments.BLAST_PROTECTION.getRegistryRef()).getEntry(Enchantments.BINDING_CURSE).get())
               && this.ignoreCurse.getValue()) {
               var2 = -999;
            }
         }

         return (is.getItem() instanceof ArmorItem ? ((ArmorItem)is.getItem()).getProtection() : 0) + var2;
      } else {
         return !is.isEmpty() ? 0 : -1;
      }
   }
@Environment(EnvType.CLIENT)
   private static enum EnchantPriority {
      Blast,
      Protection;

}

   @Environment(EnvType.CLIENT)
   public static enum HotbarSwapMode {
      Swap,
      Switch;

}

   @Environment(EnvType.CLIENT)
   public static enum InventorySwapMode {
      ClickSlot,
      Pick;

}
}
