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

import net.minecraft.world.entity.ai.village.poi.PoiType;
import java.util.function.Function;
import net.minecraft.world.entity.ai.village.poi.PoiRecord;
import net.minecraft.world.entity.ai.village.poi.PoiManager;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import net.minecraft.world.entity.Entity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
import net.minecraft.core.Vec3i;
import java.util.List;
import java.util.function.Predicate;
import net.minecraft.world.entity.npc.Villager;
import net.minecraft.world.entity.EntityType;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.ai.util.RandomPos;
import javax.annotation.Nullable;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.entity.PathfinderMob;

public class GolemRandomStrollInVillageGoal extends RandomStrollGoal {
    public GolemRandomStrollInVillageGoal(final PathfinderMob apg, final double double2) {
        super(apg, double2, 240, false);
    }
    
    @Nullable
    @Override
    protected Vec3 getPosition() {
        final float float3 = this.mob.level.random.nextFloat();
        if (this.mob.level.random.nextFloat() < 0.3f) {
            return this.getPositionTowardsAnywhere();
        }
        Vec3 dem2;
        if (float3 < 0.7f) {
            dem2 = this.getPositionTowardsVillagerWhoWantsGolem();
            if (dem2 == null) {
                dem2 = this.getPositionTowardsPoi();
            }
        }
        else {
            dem2 = this.getPositionTowardsPoi();
            if (dem2 == null) {
                dem2 = this.getPositionTowardsVillagerWhoWantsGolem();
            }
        }
        return (dem2 == null) ? this.getPositionTowardsAnywhere() : dem2;
    }
    
    @Nullable
    private Vec3 getPositionTowardsAnywhere() {
        return RandomPos.getLandPos(this.mob, 10, 7);
    }
    
    @Nullable
    private Vec3 getPositionTowardsVillagerWhoWantsGolem() {
        final ServerLevel zd2 = (ServerLevel)this.mob.level;
        final List<Villager> list3 = zd2.<Villager>getEntities(EntityType.VILLAGER, this.mob.getBoundingBox().inflate(32.0), this::doesVillagerWantGolem);
        if (list3.isEmpty()) {
            return null;
        }
        final Villager bdp4 = list3.get(this.mob.level.random.nextInt(list3.size()));
        final Vec3 dem5 = bdp4.position();
        return RandomPos.getLandPosTowards(this.mob, 10, 7, dem5);
    }
    
    @Nullable
    private Vec3 getPositionTowardsPoi() {
        final SectionPos go2 = this.getRandomVillageSection();
        if (go2 == null) {
            return null;
        }
        final BlockPos fu3 = this.getRandomPoiWithinSection(go2);
        if (fu3 == null) {
            return null;
        }
        return RandomPos.getLandPosTowards(this.mob, 10, 7, Vec3.atBottomCenterOf(fu3));
    }
    
    @Nullable
    private SectionPos getRandomVillageSection() {
        final ServerLevel zd2 = (ServerLevel)this.mob.level;
        final List<SectionPos> list3 = SectionPos.cube(SectionPos.of(this.mob), 2).filter(go -> zd2.sectionsToVillage(go) == 0).collect(Collectors.toList());
        if (list3.isEmpty()) {
            return null;
        }
        return list3.get(zd2.random.nextInt(list3.size()));
    }
    
    @Nullable
    private BlockPos getRandomPoiWithinSection(final SectionPos go) {
        final ServerLevel zd3 = (ServerLevel)this.mob.level;
        final PoiManager axz4 = zd3.getPoiManager();
        final List<BlockPos> list5 = axz4.getInRange(ayc -> true, go.center(), 8, PoiManager.Occupancy.IS_OCCUPIED).map(PoiRecord::getPos).collect(Collectors.toList());
        if (list5.isEmpty()) {
            return null;
        }
        return list5.get(zd3.random.nextInt(list5.size()));
    }
    
    private boolean doesVillagerWantGolem(final Villager bdp) {
        return bdp.wantsToSpawnGolem(this.mob.level.getGameTime());
    }
}
