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

import javax.annotation.Nullable;
import java.util.function.Predicate;
import com.google.common.collect.Maps;
import java.util.function.Function;
import java.util.Comparator;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.ai.util.RandomPos;
import java.util.Optional;
import net.minecraft.server.level.ServerLevel;
import java.util.Map;
import net.minecraft.world.entity.LivingEntity;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.PathfinderMob;

public class PlayTagWithOtherKids extends Behavior<PathfinderMob> {
    public PlayTagWithOtherKids() {
        super(ImmutableMap.<MemoryModuleType<List<LivingEntity>>, MemoryStatus>of(MemoryModuleType.VISIBLE_VILLAGER_BABIES, MemoryStatus.VALUE_PRESENT, (MemoryModuleType<List<LivingEntity>>)MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, (MemoryModuleType<List<LivingEntity>>)MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED, (MemoryModuleType<List<LivingEntity>>)MemoryModuleType.INTERACTION_TARGET, MemoryStatus.REGISTERED));
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final PathfinderMob apg) {
        return zd.getRandom().nextInt(10) == 0 && this.hasFriendsNearby(apg);
    }
    
    @Override
    protected void start(final ServerLevel zd, final PathfinderMob apg, final long long3) {
        final LivingEntity aoy2 = this.seeIfSomeoneIsChasingMe(apg);
        if (aoy2 != null) {
            this.fleeFromChaser(zd, apg, aoy2);
            return;
        }
        final Optional<LivingEntity> optional7 = this.findSomeoneBeingChased(apg);
        if (optional7.isPresent()) {
            chaseKid(apg, optional7.get());
            return;
        }
        this.findSomeoneToChase(apg).ifPresent(aoy -> chaseKid(apg, aoy));
    }
    
    private void fleeFromChaser(final ServerLevel zd, final PathfinderMob apg, final LivingEntity aoy) {
        for (int integer5 = 0; integer5 < 10; ++integer5) {
            final Vec3 dem6 = RandomPos.getLandPos(apg, 20, 8);
            if (dem6 != null && zd.isVillage(new BlockPos(dem6))) {
                apg.getBrain().<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(dem6, 0.6f, 0));
                return;
            }
        }
    }
    
    private static void chaseKid(final PathfinderMob apg, final LivingEntity aoy) {
        final Brain<?> apr3 = apg.getBrain();
        apr3.<LivingEntity>setMemory(MemoryModuleType.INTERACTION_TARGET, aoy);
        apr3.<EntityTracker>setMemory((MemoryModuleType<EntityTracker>)MemoryModuleType.LOOK_TARGET, new EntityTracker(aoy, true));
        apr3.<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(new EntityTracker(aoy, false), 0.6f, 1));
    }
    
    private Optional<LivingEntity> findSomeoneToChase(final PathfinderMob apg) {
        return this.getFriendsNearby(apg).stream().findAny();
    }
    
    private Optional<LivingEntity> findSomeoneBeingChased(final PathfinderMob apg) {
        final Map<LivingEntity, Integer> map3 = this.checkHowManyChasersEachFriendHas(apg);
        return map3.entrySet().stream().sorted(Comparator.comparingInt(Map.Entry::getValue)).filter(entry -> entry.getValue() > 0 && entry.getValue() <= 5).<LivingEntity>map(Map.Entry::getKey).findFirst();
    }
    
    private Map<LivingEntity, Integer> checkHowManyChasersEachFriendHas(final PathfinderMob apg) {
        final Map<LivingEntity, Integer> map3 = Maps.newHashMap();
        final Integer n;
        this.getFriendsNearby(apg).stream().filter(this::isChasingSomeone).forEach(aoy -> n = map3.compute(this.whoAreYouChasing(aoy), (aoy, integer) -> (integer == null) ? 1 : (integer + 1)));
        return map3;
    }
    
    private List<LivingEntity> getFriendsNearby(final PathfinderMob apg) {
        return apg.getBrain().<List<LivingEntity>>getMemory(MemoryModuleType.VISIBLE_VILLAGER_BABIES).get();
    }
    
    private LivingEntity whoAreYouChasing(final LivingEntity aoy) {
        return aoy.getBrain().<LivingEntity>getMemory(MemoryModuleType.INTERACTION_TARGET).get();
    }
    
    @Nullable
    private LivingEntity seeIfSomeoneIsChasingMe(final LivingEntity aoy) {
        return aoy.getBrain().<List<LivingEntity>>getMemory(MemoryModuleType.VISIBLE_VILLAGER_BABIES).get().stream().filter(aoy2 -> this.isFriendChasingMe(aoy, aoy2)).findAny().orElse(null);
    }
    
    private boolean isChasingSomeone(final LivingEntity aoy) {
        return aoy.getBrain().<LivingEntity>getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent();
    }
    
    private boolean isFriendChasingMe(final LivingEntity aoy1, final LivingEntity aoy2) {
        return aoy2.getBrain().<LivingEntity>getMemory(MemoryModuleType.INTERACTION_TARGET).filter(aoy2 -> aoy2 == aoy1).isPresent();
    }
    
    private boolean hasFriendsNearby(final PathfinderMob apg) {
        return apg.getBrain().hasMemoryValue(MemoryModuleType.VISIBLE_VILLAGER_BABIES);
    }
}
