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

import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Entity;
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 speed;
    private final int closeEnoughDist;
    private final int tooFarDistance;
    private final int tooLongUnreachableDuration;
    
    public SetWalkTargetFromBlockMemory(final MemoryModuleType<GlobalPos> arl, 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>)arl, MemoryStatus.VALUE_PRESENT));
        this.memoryType = arl;
        this.speed = float2;
        this.closeEnoughDist = integer3;
        this.tooFarDistance = integer4;
        this.tooLongUnreachableDuration = integer5;
    }
    
    private void dropPOI(final Villager axw, final long long2) {
        final Brain<?> alp5 = axw.getBrain();
        axw.releasePoi(this.memoryType);
        alp5.<GlobalPos>eraseMemory(this.memoryType);
        alp5.<Long>setMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE, long2);
    }
    
    @Override
    protected void start(final ServerLevel xd, final Villager axw, final long long3) {
        final Brain<?> alp6 = axw.getBrain();
        Vec3 cvl8;
        int integer9;
        int integer10;
        final Brain brain;
        alp6.<GlobalPos>getMemory(this.memoryType).ifPresent(fr -> {
            if (this.tiredOfTryingToFindTarget(xd, axw)) {
                this.dropPOI(axw, long3);
            }
            else if (this.tooFar(xd, axw, fr)) {
                cvl8 = null;
                integer9 = 0;
                integer10 = 1000;
                while (integer9 < 1000) {
                    if (cvl8 != null) {
                        if (!this.tooFar(xd, axw, GlobalPos.of(axw.dimension, new BlockPos(cvl8)))) {
                            break;
                        }
                    }
                    cvl8 = RandomPos.getPosTowards(axw, 15, 7, new Vec3(fr.pos()));
                    ++integer9;
                }
                if (integer9 == 1000) {
                    this.dropPOI(axw, long3);
                }
                else {
                    brain.setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(cvl8, this.speed, this.closeEnoughDist));
                }
            }
            else if (!this.closeEnough(xd, axw, fr)) {
                brain.setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(fr.pos(), this.speed, this.closeEnoughDist));
            }
        });
    }
    
    private boolean tiredOfTryingToFindTarget(final ServerLevel xd, final Villager axw) {
        final Optional<Long> optional4 = axw.getBrain().<Long>getMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
        return optional4.isPresent() && xd.getGameTime() - optional4.get() > this.tooLongUnreachableDuration;
    }
    
    private boolean tooFar(final ServerLevel xd, final Villager axw, final GlobalPos fr) {
        return fr.dimension() != xd.getDimension().getType() || fr.pos().distManhattan(new BlockPos(axw)) > this.tooFarDistance;
    }
    
    private boolean closeEnough(final ServerLevel xd, final Villager axw, final GlobalPos fr) {
        return fr.dimension() == xd.getDimension().getType() && fr.pos().distManhattan(new BlockPos(axw)) <= this.closeEnoughDist;
    }
}
