package net.minecraft.world.entity.projectile;

import net.minecraft.world.item.Items;
import net.minecraft.world.item.ArrowItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.Item;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.util.Mth;
import javax.annotation.Nullable;
import java.util.Optional;
import java.util.Iterator;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.level.ClipContext;
import java.util.function.Predicate;
import net.minecraft.world.entity.Entity;

public final class ProjectileUtil {
    public static HitResult getHitResult(final Entity aom, final Predicate<Entity> predicate, final ClipContext.Block a) {
        final Vec3 dem4 = aom.getDeltaMovement();
        final Level bqb5 = aom.level;
        final Vec3 dem5 = aom.position();
        Vec3 dem6 = dem5.add(dem4);
        HitResult dej8 = bqb5.clip(new ClipContext(dem5, dem6, a, ClipContext.Fluid.NONE, aom));
        if (dej8.getType() != HitResult.Type.MISS) {
            dem6 = dej8.getLocation();
        }
        final HitResult dej9 = getEntityHitResult(bqb5, aom, dem5, dem6, aom.getBoundingBox().expandTowards(aom.getDeltaMovement()).inflate(1.0), predicate);
        if (dej9 != null) {
            dej8 = dej9;
        }
        return dej8;
    }
    
    @Nullable
    public static EntityHitResult getEntityHitResult(final Entity aom, final Vec3 dem2, final Vec3 dem3, final AABB deg, final Predicate<Entity> predicate, final double double6) {
        final Level bqb8 = aom.level;
        double double7 = double6;
        Entity aom2 = null;
        Vec3 dem4 = null;
        for (final Entity aom3 : bqb8.getEntities(aom, deg, predicate)) {
            final AABB deg2 = aom3.getBoundingBox().inflate(aom3.getPickRadius());
            final Optional<Vec3> optional16 = deg2.clip(dem2, dem3);
            if (deg2.contains(dem2)) {
                if (double7 < 0.0) {
                    continue;
                }
                aom2 = aom3;
                dem4 = optional16.orElse(dem2);
                double7 = 0.0;
            }
            else {
                if (!optional16.isPresent()) {
                    continue;
                }
                final Vec3 dem5 = optional16.get();
                final double double8 = dem2.distanceToSqr(dem5);
                if (double8 >= double7 && double7 != 0.0) {
                    continue;
                }
                if (aom3.getRootVehicle() == aom.getRootVehicle()) {
                    if (double7 != 0.0) {
                        continue;
                    }
                    aom2 = aom3;
                    dem4 = dem5;
                }
                else {
                    aom2 = aom3;
                    dem4 = dem5;
                    double7 = double8;
                }
            }
        }
        if (aom2 == null) {
            return null;
        }
        return new EntityHitResult(aom2, dem4);
    }
    
    @Nullable
    public static EntityHitResult getEntityHitResult(final Level bqb, final Entity aom, final Vec3 dem3, final Vec3 dem4, final AABB deg, final Predicate<Entity> predicate) {
        double double7 = Double.MAX_VALUE;
        Entity aom2 = null;
        for (final Entity aom3 : bqb.getEntities(aom, deg, predicate)) {
            final AABB deg2 = aom3.getBoundingBox().inflate(0.30000001192092896);
            final Optional<Vec3> optional13 = deg2.clip(dem3, dem4);
            if (optional13.isPresent()) {
                final double double8 = dem3.distanceToSqr(optional13.get());
                if (double8 >= double7) {
                    continue;
                }
                aom2 = aom3;
                double7 = double8;
            }
        }
        if (aom2 == null) {
            return null;
        }
        return new EntityHitResult(aom2);
    }
    
    public static final void rotateTowardsMovement(final Entity aom, final float float2) {
        final Vec3 dem3 = aom.getDeltaMovement();
        if (dem3.lengthSqr() == 0.0) {
            return;
        }
        final float float3 = Mth.sqrt(Entity.getHorizontalDistanceSqr(dem3));
        aom.yRot = (float)(Mth.atan2(dem3.z, dem3.x) * 57.2957763671875) + 90.0f;
        aom.xRot = (float)(Mth.atan2(float3, dem3.y) * 57.2957763671875) - 90.0f;
        while (aom.xRot - aom.xRotO < -180.0f) {
            aom.xRotO -= 360.0f;
        }
        while (aom.xRot - aom.xRotO >= 180.0f) {
            aom.xRotO += 360.0f;
        }
        while (aom.yRot - aom.yRotO < -180.0f) {
            aom.yRotO -= 360.0f;
        }
        while (aom.yRot - aom.yRotO >= 180.0f) {
            aom.yRotO += 360.0f;
        }
        aom.xRot = Mth.lerp(float2, aom.xRotO, aom.xRot);
        aom.yRot = Mth.lerp(float2, aom.yRotO, aom.yRot);
    }
    
    public static InteractionHand getWeaponHoldingHand(final LivingEntity aoy, final Item bke) {
        return (aoy.getMainHandItem().getItem() == bke) ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND;
    }
    
    public static AbstractArrow getMobArrow(final LivingEntity aoy, final ItemStack bki, final float float3) {
        final ArrowItem bih4 = (ArrowItem)((bki.getItem() instanceof ArrowItem) ? bki.getItem() : Items.ARROW);
        final AbstractArrow beg5 = bih4.createArrow(aoy.level, bki, aoy);
        beg5.setEnchantmentEffectsFromEntity(aoy, float3);
        if (bki.getItem() == Items.TIPPED_ARROW && beg5 instanceof Arrow) {
            ((Arrow)beg5).setEffectsFromItem(bki);
        }
        return beg5;
    }
}
