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

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.eventbus.EventListener;
import dev.crucifixbeta.api.events.impl.TimerEvent;
import dev.crucifixbeta.api.events.impl.UpdateEvent;
import dev.crucifixbeta.api.utils.player.MovementUtil;
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 java.util.ArrayList;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.CobwebBlock;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket;
import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket.Action;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;

@Environment(EnvType.CLIENT)
public class FastWeb extends Module {
   public static FastWeb INSTANCE;
   public final EnumSetting<FastWeb.Mode> mode = this.add(new EnumSetting<>("Mode", FastWeb.Mode.Vanilla));
   public final BooleanSetting onlySneak = this.add(new BooleanSetting("OnlySneak", true));
   public final BooleanSetting grim = this.add(new BooleanSetting("Grim", false).setParent());
   public final BooleanSetting abortPacket = this.add(new BooleanSetting("AbortPacket", true, this.grim::isOpen));
   public final SliderSetting xZSlow = this.add(
      new SliderSetting("XZSpeed", 25.0, 0.0, 100.0, 0.1, () -> this.mode.getValue() == FastWeb.Mode.Custom)
         .setSuffix("%")
   );
   public final SliderSetting ySlow = this.add(
      new SliderSetting("YSpeed", 100.0, 0.0, 100.0, 0.1, () -> this.mode.getValue() == FastWeb.Mode.Custom)
         .setSuffix("%")
   );
   private final SliderSetting fastSpeed = this.add(
      new SliderSetting(
         "Speed", 3.0, 0.0, 8.0, () -> this.mode.getValue() == FastWeb.Mode.Vanilla || this.mode.getValue() == FastWeb.Mode.Strict
      )
   );
   private boolean work = false;

   public FastWeb() {
      super("FastWeb", "So you don't need to keep timer on keybind", Module.Category.Movement);
      this.setChinese("\u8718\u86db\u7f51\u52a0\u901f");
      INSTANCE = this;
   }

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

   @EventListener
   public void onUpdate(UpdateEvent event) {
      boolean var2 = this.work = !mc.player.isOnGround()
         && (mc.options.sneakKey.isPressed() || !this.onlySneak.getValue())
         && CrucifixBeta.PLAYER.isInWeb(mc.player);
      if (this.work && this.mode.is(FastWeb.Mode.Vanilla)) {
         MovementUtil.setMotionY(-this.fastSpeed.getValue());
      }

      if (this.grim.getValue() && (mc.options.sneakKey.isPressed() || !this.onlySneak.getValue())) {
         for (BlockPos var4 : this.getIntersectingWebs()) {
            if (this.abortPacket.getValue()) {
               mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(Action.ABORT_DESTROY_BLOCK, var4, Direction.DOWN));
            }

            mc.getNetworkHandler().sendPacket(new PlayerActionC2SPacket(Action.STOP_DESTROY_BLOCK, var4, Direction.DOWN));
         }
      }
   }

   @EventListener(
      priority = -100
   )
   public void onTimer(TimerEvent event) {
      if (this.work && this.mode.getValue() == FastWeb.Mode.Strict) {
         event.set(this.fastSpeed.getValueFloat());
      }
   }

   public List<BlockPos> getIntersectingWebs() {
      byte var1 = 2;
      ArrayList var2 = new ArrayList();

      for (int var3 = var1; var3 > -var1; var3--) {
         for (int var4 = var1; var4 > -var1; var4--) {
            for (int var5 = var1; var5 > -var1; var5--) {
               BlockPos var6 = BlockPos.ofFloored(mc.player.getX() + (double)var3, mc.player.getY() + (double)var4, mc.player.getZ() + (double)var5);
               if ((!(mc.player.getPos().distanceTo(var6.toCenterPos()) > 1.0) || !(mc.player.getEyePos().distanceTo(var6.toCenterPos()) > 1.0))
                  && mc.world.getBlockState(var6).getBlock() instanceof CobwebBlock) {
                  var2.add(var6);
               }
            }
         }
      }

      return var2;
   }
@Environment(EnvType.CLIENT)
   public static enum Mode {
      Vanilla,
      Strict,
      Custom,
      Ignore;

}
}
