package dev.crucifixbeta.api.utils.combat;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.math.MathUtil;
import dev.crucifixbeta.api.utils.math.Timer;
import dev.crucifixbeta.api.utils.player.EntityUtil;
import dev.crucifixbeta.api.utils.world.BlockUtil;
import dev.crucifixbeta.mod.modules.impl.client.AntiCheat;
import java.util.ArrayList;
import java.util.List;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.decoration.EndCrystalEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;

@Environment(EnvType.CLIENT)
public class CombatUtil implements Wrapper {
   public static final Timer breakTimer = new Timer();
   public static boolean terrainIgnore = false;
   public static BlockPos modifyPos;
   public static BlockState modifyBlockState = Blocks.AIR.getDefaultState();

   public static List<PlayerEntity> getEnemies(double range) {
      ArrayList var2 = new ArrayList();

      for (AbstractClientPlayerEntity var4 : CrucifixBeta.THREAD.getPlayers()) {
         if (isValid(var4, range)) {
            var2.add(var4);
         }
      }

      return var2;
   }

   public static void attackCrystal(BlockPos pos, boolean rotate, boolean eatingPause) {
      attackCrystal(new Box(pos), rotate, eatingPause);
   }

   public static void attackCrystal(Box box, boolean rotate, boolean eatingPause) {
      for (EndCrystalEntity var4 : BlockUtil.getEndCrystals(box)) {
         attackWithDelay(var4, rotate, eatingPause);
      }
   }

   public static void attackWithDelay(Entity entity, boolean rotate, boolean usingPause) {
      if (breakTimer.passed((long)(AntiCheat.INSTANCE.attackDelay.getValue() * 1000.0))) {
         if (!usingPause || !mc.player.isUsingItem()) {
            attack(entity, rotate);
         }
      }
   }

   public static void attack(Entity entity, boolean rotate) {
      if (entity != null) {
         Vec3d var2 = MathUtil.getClosestPointToBox(mc.player.getEyePos(), entity.getBoundingBox());
         if (mc.player.getEyePos().distanceTo(var2) > AntiCheat.INSTANCE.ieRange.getValue()) {
            return;
         }

         breakTimer.reset();
         if (rotate && AntiCheat.INSTANCE.attackRotate.getValue()) {
            CrucifixBeta.ROTATION.lookAt(var2);
         }

         mc.getNetworkHandler().sendPacket(PlayerInteractEntityC2SPacket.attack(entity, mc.player.isSneaking()));
         mc.player.resetLastAttackedTicks();
         EntityUtil.swingHand(Hand.MAIN_HAND, AntiCheat.INSTANCE.attackSwing.getValue());
         if (rotate && AntiCheat.INSTANCE.attackRotate.getValue()) {
            CrucifixBeta.ROTATION.snapBack();
         }
      }
   }

   public static boolean isntValid(Entity entity, double range) {
      return !isValid(entity, range);
   }

   public static boolean isValid(Entity entity, double range) {
      PlayerEntity var3;
      boolean var4 = entity == null
         || !entity.isAlive()
         || entity.equals(mc.player)
         || entity instanceof PlayerEntity && CrucifixBeta.FRIEND.isFriend(var3 = (PlayerEntity)entity)
         || mc.player.getPos().distanceTo(entity.getPos()) > range;
      return !var4;
   }

   public static boolean isValid(Entity entity) {
      PlayerEntity var1;
      boolean var2 = entity == null
         || !entity.isAlive()
         || entity.equals(mc.player)
         || entity instanceof PlayerEntity && CrucifixBeta.FRIEND.isFriend(var1 = (PlayerEntity)entity);
      return !var2;
   }

   public static PlayerEntity getClosestEnemy(double getDistance) {
      PlayerEntity var2 = null;

      for (PlayerEntity var4 : getEnemies(getDistance)) {
         if (var2 == null) {
            var2 = var4;
         } else if (mc.player.squaredDistanceTo(var4.getPos()) < mc.player.squaredDistanceTo(var2)) {
            var2 = var4;
         }
      }

      return var2;
   }
}
