package dev.crucifixbeta.api.utils.world;

import dev.crucifixbeta.api.utils.Wrapper;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.projectile.ProjectileUtil;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import net.minecraft.world.RaycastContext.FluidHandling;
import net.minecraft.world.RaycastContext.ShapeType;

@Environment(EnvType.CLIENT)
public class InteractUtil implements Wrapper {
   public static HitResult getRtxTarget(float yaw, float pitch, double x, double y, double z) {
      HitResult var8 = rayTrace(5.0, yaw, pitch, x, y, z);
      Vec3d var9 = new Vec3d(x, y, z);
      double var10 = 25.0;
      if (var8 != null) {
         var10 = var8.getPos().squaredDistanceTo(var9);
      }

      Vec3d var12 = getRotationVector(pitch, yaw);
      Vec3d var13 = var9.add(var12.x * 5.0, var12.y * 5.0, var12.z * 5.0);
      EntityHitResult var15 = ProjectileUtil.raycast(
         mc.player,
         var9,
         var13,
         new Box(x - 0.3, y, z - 0.3, x + 0.3, y + 1.8, z + 0.3).stretch(var12.multiply(5.0)).expand(1.0, 1.0, 1.0),
         entity -> !entity.isSpectator() && entity.canHit(),
         var10
      );
      if (var15 != null) {
         Entity var16 = var15.getEntity();
         Vec3d var17 = var15.getPos();
         double var18 = var9.squaredDistanceTo(var17);
         if ((var18 < var10 || var8 == null) && var16 instanceof LivingEntity) {
            return var15;
         }
      }

      return var8;
   }

   public static HitResult rayTrace(double dst, float yaw, float pitch, double x, double y, double z) {
      Vec3d var10 = new Vec3d(x, y, z);
      Vec3d var11 = getRotationVector(pitch, yaw);
      Vec3d var12 = var10.add(var11.x * dst, var11.y * dst, var11.z * dst);
      return mc.world.raycast(new RaycastContext(var10, var12, ShapeType.OUTLINE, FluidHandling.NONE, mc.player));
   }

   private static Vec3d getRotationVector(float yaw, float pitch) {
      return new Vec3d(
         (double)(MathHelper.sin(-pitch * (float) (Math.PI / 180.0)) * MathHelper.cos(yaw * (float) (Math.PI / 180.0))),
         (double)(-MathHelper.sin(yaw * (float) (Math.PI / 180.0))),
         (double)(MathHelper.cos(-pitch * (float) (Math.PI / 180.0)) * MathHelper.cos(yaw * (float) (Math.PI / 180.0)))
      );
   }
}
