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

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.RotationEvent;
import dev.crucifixbeta.api.events.impl.TickEvent;
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.impl.exploit.Blink;
import dev.crucifixbeta.mod.modules.impl.movement.ElytraFly;
import dev.crucifixbeta.mod.modules.settings.enums.SwingSide;
import dev.crucifixbeta.mod.modules.settings.enums.Timing;
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.item.Items;
import net.minecraft.network.packet.c2s.play.PlayerInteractItemC2SPacket;
import net.minecraft.util.Hand;

@Environment(EnvType.CLIENT)
public class AutoPearl extends Module {
   public static AutoPearl INSTANCE;
   public static boolean throwing;
   public final BooleanSetting inventory = this.add(new BooleanSetting("InventorySwap", true));
   private final EnumSetting<Timing> timing = this.add(new EnumSetting<>("Timing", Timing.All));
   public final EnumSetting<SwingSide> interactSwing = this.add(new EnumSetting<>("Swing", SwingSide.All));
   private final BooleanSetting rotation = this.add(new BooleanSetting("Rotation", true));
   private final BooleanSetting yawStep = this.add(new BooleanSetting("YawStep", false).setParent());
   private final BooleanSetting whenElytra = this.add(new BooleanSetting("FallFlying", true, this.yawStep::isOpen));
   private final SliderSetting steps = this.add(new SliderSetting("Steps", 0.05, 0.0, 1.0, 0.01, this.yawStep::isOpen));
   private final SliderSetting fov = this.add(new SliderSetting("Fov", 20.0, 0.0, 360.0, 0.1, this.yawStep::isOpen));
   private final SliderSetting priority = this.add(new SliderSetting("Priority", 100, 0, 100, this.yawStep::isOpen));
   private final BooleanSetting sync = this.add(new BooleanSetting("Sync", true, this.yawStep::isOpen));

   public AutoPearl() {
      super("AutoPearl", Module.Category.Player);
      this.setChinese("\u6254\u73cd\u73e0");
      INSTANCE = this;
   }

   @Override
   public void onEnable() {
      if (nullCheck()) {
         this.disable();
      } else {
         if (INSTANCE.inventory.getValue()) {
            if (InventoryUtil.findItemInventorySlotFromZero(Items.ENDER_PEARL) == -1) {
               this.disable();
               return;
            }
         } else if (InventoryUtil.findItem(Items.ENDER_PEARL) == -1) {
            this.disable();
            return;
         }

         if (!this.shouldYawStep()) {
            if (!this.inventory.getValue() || EntityUtil.inInventory()) {
               if (!Blink.INSTANCE.isOn() || !Blink.INSTANCE.pauseModule.getValue()) {
                  this.throwPearl(mc.player.getYaw(), mc.player.getPitch());
                  this.disable();
               }
            }
         }
      }
   }

   @EventListener
   public void onUpdate(TickEvent event) {
      if (!nullCheck()) {
         if ((!this.timing.is(Timing.Pre) || !event.isPost()) && (!this.timing.is(Timing.Post) || !event.isPre())) {
            if (!Blink.INSTANCE.isOn() || !Blink.INSTANCE.pauseModule.getValue()) {
               if (!this.shouldYawStep()) {
                  this.throwPearl(mc.player.getYaw(), mc.player.getPitch());
                  this.disable();
               } else if (CrucifixBeta.ROTATION.inFov(mc.player.getYaw(), mc.player.getPitch(), this.fov.getValueFloat())) {
                  if (this.sync.getValue()) {
                     this.throwPearl(mc.player.getYaw(), mc.player.getPitch());
                  } else {
                     throwing = true;
                     if (mc.player.getMainHandStack().getItem() == Items.ENDER_PEARL) {
                        sendSequencedPacket(
                           id -> new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, id, CrucifixBeta.ROTATION.getLastYaw(), CrucifixBeta.ROTATION.getLastPitch())
                        );
                        EntityUtil.swingHand(Hand.MAIN_HAND, this.interactSwing.getValue());
                     } else {
                        int var2;
                        if (this.inventory.getValue() && (var2 = InventoryUtil.findItemInventorySlotFromZero(Items.ENDER_PEARL)) != -1) {
                           InventoryUtil.inventorySwap(var2, mc.player.getInventory().selectedSlot);
                           sendSequencedPacket(
                              id -> new PlayerInteractItemC2SPacket(
                                    Hand.MAIN_HAND, id, CrucifixBeta.ROTATION.getLastYaw(), CrucifixBeta.ROTATION.getLastPitch()
                                 )
                           );
                           EntityUtil.swingHand(Hand.MAIN_HAND, this.interactSwing.getValue());
                           InventoryUtil.inventorySwap(var2, mc.player.getInventory().selectedSlot);
                           EntityUtil.syncInventory();
                        } else {
                           var2 = InventoryUtil.findItem(Items.ENDER_PEARL);
                           if (var2 != -1) {
                              int var3 = mc.player.getInventory().selectedSlot;
                              InventoryUtil.switchToSlot(var2);
                              sendSequencedPacket(
                                 id -> new PlayerInteractItemC2SPacket(
                                       Hand.MAIN_HAND, id, CrucifixBeta.ROTATION.getLastYaw(), CrucifixBeta.ROTATION.getLastPitch()
                                    )
                              );
                              EntityUtil.swingHand(Hand.MAIN_HAND, this.interactSwing.getValue());
                              InventoryUtil.switchToSlot(var3);
                           }
                        }
                     }

                     throwing = false;
                  }

                  this.disable();
               }
            }
         }
      }
   }

   @EventListener
   public void onRotate(RotationEvent event) {
      if (this.shouldYawStep()) {
         event.setRotation(mc.player.getYaw(), mc.player.getPitch(), this.steps.getValueFloat(), this.priority.getValueFloat());
      }
   }

   private boolean shouldYawStep() {
      return this.whenElytra.getValue() || !mc.player.isFallFlying() && (!ElytraFly.INSTANCE.isOn() || !ElytraFly.INSTANCE.isFallFlying())
         ? this.yawStep.getValue()
         : false;
   }

   public void throwPearl(float yaw, float pitch) {
      throwing = true;
      if (mc.player.getMainHandStack().getItem() == Items.ENDER_PEARL) {
         if (this.rotation.getValue()) {
            CrucifixBeta.ROTATION.snapAt(yaw, pitch);
         }

         sendSequencedPacket(id -> new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, id, yaw, pitch));
         EntityUtil.swingHand(Hand.MAIN_HAND, this.interactSwing.getValue());
         if (this.rotation.getValue()) {
            CrucifixBeta.ROTATION.snapBack();
         }
      } else {
         int var3;
         if (this.inventory.getValue() && (var3 = InventoryUtil.findItemInventorySlotFromZero(Items.ENDER_PEARL)) != -1) {
            InventoryUtil.inventorySwap(var3, mc.player.getInventory().selectedSlot);
            if (this.rotation.getValue()) {
               CrucifixBeta.ROTATION.snapAt(yaw, pitch);
            }

            sendSequencedPacket(id -> new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, id, yaw, pitch));
            EntityUtil.swingHand(Hand.MAIN_HAND, this.interactSwing.getValue());
            InventoryUtil.inventorySwap(var3, mc.player.getInventory().selectedSlot);
            EntityUtil.syncInventory();
            if (this.rotation.getValue()) {
               CrucifixBeta.ROTATION.snapBack();
            }
         } else {
            var3 = InventoryUtil.findItem(Items.ENDER_PEARL);
            if (var3 != -1) {
               int var4 = mc.player.getInventory().selectedSlot;
               InventoryUtil.switchToSlot(var3);
               if (this.rotation.getValue()) {
                  CrucifixBeta.ROTATION.snapAt(yaw, pitch);
               }

               sendSequencedPacket(id -> new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, id, yaw, pitch));
               EntityUtil.swingHand(Hand.MAIN_HAND, this.interactSwing.getValue());
               InventoryUtil.switchToSlot(var4);
               if (this.rotation.getValue()) {
                  CrucifixBeta.ROTATION.snapBack();
               }
            }
         }
      }

      throwing = false;
   }

   static {

      throwing = false;
   }
}
