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

import net.minecraft.world.entity.LivingEntity;
import java.util.Optional;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.util.RandomPos;
import net.minecraft.core.Vec3i;
import net.minecraft.world.phys.Vec3;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.Brain;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.core.GlobalPos;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.npc.Villager;

public class SetWalkTargetFromBlockMemory extends Behavior<Villager> {
    private final MemoryModuleType<GlobalPos> memoryType;
    private final float speedModifier;
    private final int closeEnoughDist;
    private final int tooFarDistance;
    private final int tooLongUnreachableDuration;
    
    public SetWalkTargetFromBlockMemory(final MemoryModuleType<GlobalPos> awp, final float float2, final int integer3, final int integer4, final int integer5) {
        super(ImmutableMap.<MemoryModuleType<Long>, MemoryStatus>of(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, MemoryStatus.REGISTERED, (MemoryModuleType<Long>)MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, (MemoryModuleType<Long>)awp, MemoryStatus.VALUE_PRESENT));
        this.memoryType = awp;
        this.speedModifier = float2;
        this.closeEnoughDist = integer3;
        this.tooFarDistance = integer4;
        this.tooLongUnreachableDuration = integer5;
    }
    
    private void dropPOI(final Villager bdp, final long long2) {
        final Brain<?> apr5 = bdp.getBrain();
        bdp.releasePoi(this.memoryType);
        apr5.<GlobalPos>eraseMemory(this.memoryType);
        apr5.<Long>setMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, long2);
    }
    
    @Override
    protected void start(final ServerLevel zd, final Villager bdp, final long long3) {
        final Brain<?> apr6 = bdp.getBrain();
        Vec3 dem8;
        int integer9;
        int integer10;
        final Brain brain;
        apr6.<GlobalPos>getMemory(this.memoryType).ifPresent(gc -> {
            if (this.tiredOfTryingToFindTarget(zd, bdp)) {
                this.dropPOI(bdp, long3);
            }
            else if (this.tooFar(zd, bdp, gc)) {
                dem8 = null;
                integer9 = 0;
                integer10 = 1000;
                while (integer9 < 1000) {
                    if (dem8 != null) {
                        if (!this.tooFar(zd, bdp, GlobalPos.of(zd.dimension(), new BlockPos(dem8)))) {
                            break;
                        }
                    }
                    dem8 = RandomPos.getPosTowards(bdp, 15, 7, Vec3.atBottomCenterOf(gc.pos()));
                    ++integer9;
                }
                if (integer9 == 1000) {
                    this.dropPOI(bdp, long3);
                }
                else {
                    brain.setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(dem8, this.speedModifier, this.closeEnoughDist));
                }
            }
            else if (!this.closeEnough(zd, bdp, gc)) {
                brain.setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(gc.pos(), this.speedModifier, this.closeEnoughDist));
            }
        });
    }
    
    private boolean tiredOfTryingToFindTarget(final ServerLevel zd, final Villager bdp) {
        final Optional<Long> optional4 = bdp.getBrain().<Long>getMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
        return optional4.isPresent() && zd.getGameTime() - optional4.get() > this.tooLongUnreachableDuration;
    }
    
    private boolean tooFar(final ServerLevel zd, final Villager bdp, final GlobalPos gc) {
        return gc.dimension() != zd.dimension() || gc.pos().distManhattan(bdp.blockPosition()) > this.tooFarDistance;
    }
    
    private boolean closeEnough(final ServerLevel zd, final Villager bdp, final GlobalPos gc) {
        return gc.dimension() == zd.dimension() && gc.pos().distManhattan(bdp.blockPosition()) <= this.closeEnoughDist;
    }
}
