package net.minecraft.world.entity.ai.behavior;

import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.util.RandomPos;
import net.minecraft.core.Position;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.core.BlockPos;
import java.util.Map;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.phys.Vec3;
import java.util.function.Function;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.PathfinderMob;

public class SetWalkTargetAwayFrom<T> extends Behavior<PathfinderMob> {
    private final MemoryModuleType<T> walkAwayFromMemory;
    private final float speedModifier;
    private final int desiredDistance;
    private final Function<T, Vec3> toPosition;
    
    public SetWalkTargetAwayFrom(final MemoryModuleType<T> awp, final float float2, final int integer, final boolean boolean4, final Function<T, Vec3> function) {
        super(ImmutableMap.<MemoryModuleType<WalkTarget>, MemoryStatus>of(MemoryModuleType.WALK_TARGET, boolean4 ? MemoryStatus.REGISTERED : MemoryStatus.VALUE_ABSENT, (MemoryModuleType<WalkTarget>)awp, MemoryStatus.VALUE_PRESENT));
        this.walkAwayFromMemory = awp;
        this.speedModifier = float2;
        this.desiredDistance = integer;
        this.toPosition = function;
    }
    
    public static SetWalkTargetAwayFrom<BlockPos> pos(final MemoryModuleType<BlockPos> awp, final float float2, final int integer, final boolean boolean4) {
        return new SetWalkTargetAwayFrom<BlockPos>(awp, float2, integer, boolean4, Vec3::atBottomCenterOf);
    }
    
    public static SetWalkTargetAwayFrom<? extends Entity> entity(final MemoryModuleType<? extends Entity> awp, final float float2, final int integer, final boolean boolean4) {
        return new SetWalkTargetAwayFrom<Entity>(awp, float2, integer, boolean4, Entity::position);
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final PathfinderMob apg) {
        return !this.alreadyWalkingAwayFromPosWithSameSpeed(apg) && apg.position().closerThan(this.getPosToAvoid(apg), this.desiredDistance);
    }
    
    private Vec3 getPosToAvoid(final PathfinderMob apg) {
        return this.toPosition.apply(apg.getBrain().<T>getMemory(this.walkAwayFromMemory).get());
    }
    
    private boolean alreadyWalkingAwayFromPosWithSameSpeed(final PathfinderMob apg) {
        if (!apg.getBrain().hasMemoryValue(MemoryModuleType.WALK_TARGET)) {
            return false;
        }
        final WalkTarget awr3 = apg.getBrain().<WalkTarget>getMemory(MemoryModuleType.WALK_TARGET).get();
        if (awr3.getSpeedModifier() != this.speedModifier) {
            return false;
        }
        final Vec3 dem4 = awr3.getTarget().currentPosition().subtract(apg.position());
        final Vec3 dem5 = this.getPosToAvoid(apg).subtract(apg.position());
        return dem4.dot(dem5) < 0.0;
    }
    
    @Override
    protected void start(final ServerLevel zd, final PathfinderMob apg, final long long3) {
        moveAwayFrom(apg, this.getPosToAvoid(apg), this.speedModifier);
    }
    
    private static void moveAwayFrom(final PathfinderMob apg, final Vec3 dem, final float float3) {
        for (int integer4 = 0; integer4 < 10; ++integer4) {
            final Vec3 dem2 = RandomPos.getLandPosAvoid(apg, 16, 7, dem);
            if (dem2 != null) {
                apg.getBrain().<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(dem2, float3, 0));
                return;
            }
        }
    }
}
