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

import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.PacketEvent;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.player.InventoryUtil;
import dev.crucifixbeta.mod.modules.Module;
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 net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.decoration.EndCrystalEntity;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.item.SwordItem;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket.InteractType;

@Environment(EnvType.CLIENT)
public class AntiWeak extends Module {
   private final EnumSetting<AntiWeak.SwapMode> swapMode = this.add(new EnumSetting<>("SwapMode", AntiWeak.SwapMode.Inventory));
   private final SliderSetting delay = this.add(new SliderSetting("Delay", 100, 0, 500).setSuffix("ms"));
   private final BooleanSetting onlyCrystal = this.add(new BooleanSetting("OnlyCrystal", true));
   private final Timer delayTimer = new Timer();
   boolean ignore = false;
   private PlayerInteractEntityC2SPacket lastPacket = null;

   public AntiWeak() {
      super("AntiWeak", Module.Category.Combat);
      this.setChinese("\u53cd\u865a\u5f31");
   }

   @Override
   public String getInfo() {
      return this.swapMode.getValue().name();
   }

   @EventListener(
      priority = 200
   )
   public void onPacketSend(PacketEvent.Send event) {
      if (!nullCheck()) {
         if (!event.isCancelled()) {
            if (!this.ignore) {
               if (mc.player.getStatusEffect(StatusEffects.WEAKNESS) != null) {
                  if (!(mc.player.getMainHandStack().getItem() instanceof SwordItem)) {
                     if (this.delayTimer.passedMs(this.delay.getValue())) {
                        Packet var2 = event.getPacket();
                        PlayerInteractEntityC2SPacket var3;
                        if (var2 instanceof PlayerInteractEntityC2SPacket
                           && Criticals.getInteractType(var3 = (PlayerInteractEntityC2SPacket)var2) == InteractType.ATTACK) {
                           if (this.onlyCrystal.getValue() && !(Criticals.getEntity(var3) instanceof EndCrystalEntity)) {
                              return;
                           }

                           this.lastPacket = var3;
                           this.delayTimer.reset();
                           this.ignore = true;
                           this.doAnti();
                           this.ignore = false;
                           event.cancel();
                        }
                     }
                  }
               }
            }
         }
      }
   }

   private void doAnti() {
      if (this.lastPacket != null) {
         int var1 = this.swapMode.getValue() != AntiWeak.SwapMode.Inventory
            ? InventoryUtil.findClass(SwordItem.class)
            : InventoryUtil.findClassInventorySlot(SwordItem.class);
         if (var1 != -1) {
            int var2 = mc.player.getInventory().selectedSlot;
            if (this.swapMode.getValue() != AntiWeak.SwapMode.Inventory) {
               InventoryUtil.switchToSlot(var1);
            } else {
               InventoryUtil.inventorySwap(var1, mc.player.getInventory().selectedSlot);
            }

            mc.getNetworkHandler().sendPacket(this.lastPacket);
            if (this.swapMode.getValue() != AntiWeak.SwapMode.Inventory) {
               if (this.swapMode.getValue() != AntiWeak.SwapMode.Normal) {
                  InventoryUtil.switchToSlot(var2);
               }
            } else {
               InventoryUtil.inventorySwap(var1, mc.player.getInventory().selectedSlot);
               EntityUtil.syncInventory();
            }
         }
      }
   }
@Environment(EnvType.CLIENT)
   public static enum SwapMode {
      Normal,
      Silent,
      Inventory;

}
}
