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

import asm.accessors.IBundlePacket;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.PacketEvent;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import dev.crucifixbeta.mod.modules.settings.impl.SliderSetting;
import java.util.ArrayList;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.LivingEntity;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.BundleS2CPacket;
import net.minecraft.network.packet.s2c.play.EntityAnimationS2CPacket;

@Environment(EnvType.CLIENT)
public class AnimationsModule extends Module {
   public static AnimationsModule INSTANCE;
   public final BooleanSetting noSwitchAnimation = this.add(new BooleanSetting("NoSwitchAnimation", false));
   public final BooleanSetting oldSwingAnimation = this.add(new BooleanSetting("OldSwingAnimation", false));
   public final BooleanSetting swingSpeed = this.add(new BooleanSetting("SwingSpeed", false));
   public final SliderSetting swingFactor = this.add(new SliderSetting("SwingFactor", 6, 1, 20, () -> this.swingSpeed.getValue()));
   public final BooleanSetting selfOnly = this.add(new BooleanSetting("SelfOnly", true, () -> this.swingSpeed.getValue()));
   public final BooleanSetting eatTransform = this.add(new BooleanSetting("EatTransform", false));
   public final SliderSetting eatTransformFactor = this.add(
      new SliderSetting("EatTransformFactor", 1.0, 0.0, 1.0, 0.01, () -> this.eatTransform.getValue())
   );
   public final BooleanSetting noLimbSwing = this.add(new BooleanSetting("NoLimbSwing", false));
   public final BooleanSetting noInterpolation = this.add(new BooleanSetting("NoInterpolation", false, () -> this.noLimbSwing.getValue()));

   public AnimationsModule() {
      super("Animations", Module.Category.Render);
      this.setChinese("\u52a8\u753b");
      INSTANCE = this;
   }

   public boolean shouldNoSwitchAnimation() {
      return this.isOn() && this.noSwitchAnimation.getValue();
   }

   public boolean shouldOldSwingAnimation() {
      return this.isOn() && this.oldSwingAnimation.getValue();
   }

   public boolean shouldModifySwingSpeed(LivingEntity entity) {
      return this.isOn() && this.swingSpeed.getValue() && (!this.selfOnly.getValue() || entity == mc.player);
   }

   public int getSwingSpeed() {
      return this.swingFactor.getValueInt();
   }

   public boolean shouldTransformEat() {
      return this.isOn() && this.eatTransform.getValue();
   }

   public float getEatTransformFactor() {
      return this.eatTransformFactor.getValueFloat();
   }

   public boolean shouldCancelLimbSwing() {
      return this.isOn() && this.noLimbSwing.getValue();
   }

   public boolean shouldNoInterpolation() {
      return this.shouldCancelLimbSwing() && this.noInterpolation.getValue();
   }

   @EventListener
   public void onPacketReceive(PacketEvent.Receive event) {
      if (mc.player != null && this.shouldOldSwingAnimation()) {
         Packet var2 = event.getPacket();
         if (var2 instanceof BundleS2CPacket var3) {
            ArrayList var4 = new ArrayList();

            for (Packet var6 : var3.getPackets()) {
               if (!this.isSelfSwingPacket(var6)) {
                  var4.add(var6);
               }
            }

            ((IBundlePacket)var3).setPackets(var4);
         } else if (this.isSelfSwingPacket(var2)) {
            event.cancel();
         }
      }
   }

   private boolean isSelfSwingPacket(Packet<?> packet) {
      if (packet instanceof EntityAnimationS2CPacket var2
         && mc.player != null
         && var2.getEntityId() == mc.player.getId()
         && (var2.getAnimationId() == 0 || var2.getAnimationId() == 3)) {
         return true;
      }

      return false;
   }
}
