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

import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.KeyboardInputEvent;
import dev.crucifixbeta.api.events.impl.MoveEvent;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.world.BlockUtil;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.settings.impl.BooleanSetting;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.util.math.Box;

@Environment(EnvType.CLIENT)
public class SafeWalk extends Module {
   public static SafeWalk INSTANCE;
   private final BooleanSetting legit = this.add(new BooleanSetting("Legit", true));
   private final BooleanSetting onlyInsideBlock = this.add(new BooleanSetting("OnlyInsideBlock", false));

   public SafeWalk() {
      super("SafeWalk", Module.Category.Movement);
      this.setChinese("\u8fb9\u7f18\u884c\u8d70");
      INSTANCE = this;
   }

   @EventListener(
      priority = -200
   )
   public void keyboard(KeyboardInputEvent event) {
      if (mc.player.isOnGround() && this.legit.getValue() && this.shouldSafeWalk()) {
         if (this.isOffsetBBEmpty(0.3, -1.0, 0.0)) {
            mc.player.input.sneaking = true;
         } else if (this.isOffsetBBEmpty(0.0, -1.0, 0.3)) {
            mc.player.input.sneaking = true;
         } else if (this.isOffsetBBEmpty(0.3, -1.0, 0.3)) {
            mc.player.input.sneaking = true;
         } else if (this.isOffsetBBEmpty(-0.3, -1.0, 0.0)) {
            mc.player.input.sneaking = true;
         } else if (this.isOffsetBBEmpty(0.0, -1.0, -0.3)) {
            mc.player.input.sneaking = true;
         } else if (this.isOffsetBBEmpty(-0.3, -1.0, -0.3)) {
            mc.player.input.sneaking = true;
         }
      }
   }

   @EventListener(
      priority = -100
   )
   public void onMove(MoveEvent event) {
      if (mc.player.isOnGround() && !this.legit.getValue() && this.shouldSafeWalk()) {
         double var2 = event.getX();
         double var4 = event.getY();
         double var6 = event.getZ();
         double var8 = 0.05;

         while (var2 != 0.0 && this.isOffsetBBEmpty(var2, -1.0, 0.0)) {
            if (var2 < var8 && var2 >= -var8) {
               var2 = 0.0;
            } else if (var2 > 0.0) {
               var2 -= var8;
            } else {
               var2 += var8;
            }
         }

         while (var6 != 0.0 && this.isOffsetBBEmpty(0.0, -1.0, var6)) {
            if (var6 < var8 && var6 >= -var8) {
               var6 = 0.0;
            } else if (var6 > 0.0) {
               var6 -= var8;
            } else {
               var6 += var8;
            }
         }

         while (var2 != 0.0 && var6 != 0.0 && this.isOffsetBBEmpty(var2, -1.0, var6)) {
            if (var2 < var8 && var2 >= -var8) {
               double var10000 = 0.0;
            } else {
               var2 = var2 > 0.0 ? var2 - var8 : var2 + var8;
            }

            if (var6 < var8 && var6 >= -var8) {
               var6 = 0.0;
            } else if (var6 > 0.0) {
               var6 -= var8;
            } else {
               var6 += var8;
            }
         }

         event.setX(var2);
         event.setY(var4);
         event.setZ(var6);
      }
   }

   public boolean shouldSafeWalk() {
      return !this.onlyInsideBlock.getValue() || EntityUtil.isInsideBlock();
   }

   public boolean isOffsetBBEmpty(double offsetX, double offsetY, double offsetZ) {
      Box var7 = mc.player.getBoundingBox();
      Box var8 = new Box(var7.minX, var7.minY, var7.maxZ, var7.maxX, var7.minY + 0.5, var7.maxZ);
      return !BlockUtil.canCollide(mc.player, var8.offset(offsetX, offsetY, offsetZ));
   }
}
