package dev.crucifixbeta.api.utils.player;

import asm.accessors.IVec3d;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.mod.modules.impl.movement.HoleSnap;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.effect.StatusEffects;

@Environment(EnvType.CLIENT)
public class MovementUtil implements Wrapper {
   public static boolean isMoving() {
      return (double)mc.player.input.movementForward != 0.0 || (double)mc.player.input.movementSideways != 0.0 || HoleSnap.INSTANCE.isOn();
   }

   public static boolean isStatic() {
      return mc.player.getVelocity().getX() == 0.0 && mc.player.isOnGround() && mc.player.getVelocity().getZ() == 0.0;
   }

   public static boolean isJumping() {
      return mc.player.input.jumping;
   }

   public static double getDistance2D() {
      double var0 = mc.player.getX() - mc.player.prevX;
      double var2 = mc.player.getZ() - mc.player.prevZ;
      return Math.sqrt(var0 * var0 + var2 * var2);
   }

   public static double getJumpSpeed() {
      double var0 = 0.0;
      if (mc.player.hasStatusEffect(StatusEffects.JUMP_BOOST)) {
         int var2 = mc.player.getActiveStatusEffects().get(StatusEffects.JUMP_BOOST).getAmplifier();
         var0 += (double)(var2 + 1) * 0.1;
      }

      return var0;
   }

   public static double[] directionSpeed(double speed) {
      float var2 = mc.player.input.movementForward;
      float var3 = mc.player.input.movementSideways;
      return directionSpeed(speed, var2, var3);
   }

   private static double[] directionSpeed(double speed, float forward, float side) {
      float var4 = mc.player.prevYaw + (mc.player.getYaw() - mc.player.prevYaw) * mc.getRenderTickCounter().getTickDelta(true);
      if (forward != 0.0F) {
         if (side > 0.0F) {
            var4 += (float)(forward > 0.0F ? -45 : 45);
         } else if (side < 0.0F) {
            var4 += (float)(forward > 0.0F ? 45 : -45);
         }

         side = 0.0F;
         if (forward > 0.0F) {
            forward = 1.0F;
         } else if (forward < 0.0F) {
            forward = -1.0F;
         }
      }

      double var5 = Math.sin(Math.toRadians((double)(var4 + 90.0F)));
      double var7 = Math.cos(Math.toRadians((double)(var4 + 90.0F)));
      double var9 = (double)forward * speed * var7 + (double)side * speed * var5;
      double var11 = (double)forward * speed * var5 - (double)side * speed * var7;
      return new double[]{var9, var11};
   }

   public static double getMotionX() {
      return mc.player.getVelocity().x;
   }

   public static void setMotionX(double x) {
      ((IVec3d)mc.player.getVelocity()).setX(x);
   }

   public static double getMotionY() {
      return mc.player.getVelocity().y;
   }

   public static void setMotionY(double y) {
      ((IVec3d)mc.player.getVelocity()).setY(y);
   }

   public static double getMotionZ() {
      return mc.player.getVelocity().z;
   }

   public static void setMotionZ(double z) {
      ((IVec3d)mc.player.getVelocity()).setZ(z);
   }

   public static double getSpeed(boolean slowness) {
      double var1 = 0.2873;
      return getSpeed(slowness, var1);
   }

   public static double getSpeed(boolean slowness, double defaultSpeed) {
      if (mc.player.hasStatusEffect(StatusEffects.SPEED)) {
         int var3 = mc.player.getActiveStatusEffects().get(StatusEffects.SPEED).getAmplifier();
         defaultSpeed *= 1.0 + 0.2 * (double)(var3 + 1);
      }

      if (slowness && mc.player.hasStatusEffect(StatusEffects.SLOWNESS)) {
         int var4 = mc.player.getActiveStatusEffects().get(StatusEffects.SLOWNESS).getAmplifier();
         defaultSpeed /= 1.0 + 0.2 * (double)(var4 + 1);
      }

      if (mc.player.isSneaking()) {
         defaultSpeed /= 5.0;
      }

      return defaultSpeed;
   }
}
