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 xd, final PathfinderMob alg) {
        return xd.getRandom().nextInt(10) == 0 && this.hasFriendsNearby(alg);
    }
    
    @Override
    protected void start(final ServerLevel xd, final PathfinderMob alg, final long long3) {
        final LivingEntity akz2 = this.seeIfSomeoneIsChasingMe(alg);
        if (akz2 != null) {
            this.fleeFromChaser(xd, alg, akz2);
            return;
        }
        final Optional<LivingEntity> optional7 = this.findSomeoneBeingChased(alg);
        if (optional7.isPresent()) {
            chaseKid(alg, optional7.get());
            return;
        }
        this.findSomeoneToChase(alg).ifPresent(akz -> chaseKid(alg, akz));
    }
    
    private void fleeFromChaser(final ServerLevel xd, final PathfinderMob alg, final LivingEntity akz) {
        for (int integer5 = 0; integer5 < 10; ++integer5) {
            final Vec3 cvl6 = RandomPos.getLandPos(alg, 20, 8);
            if (cvl6 != null && xd.isVillage(new BlockPos(cvl6))) {
                alg.getBrain().<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(cvl6, 0.6f, 0));
                return;
            }
        }
    }
    
    private static void chaseKid(final PathfinderMob alg, final LivingEntity akz) {
        final Brain<?> alp3 = alg.getBrain();
        alp3.<LivingEntity>setMemory(MemoryModuleType.INTERACTION_TARGET, akz);
        alp3.<EntityPosWrapper>setMemory((MemoryModuleType<EntityPosWrapper>)MemoryModuleType.LOOK_TARGET, new EntityPosWrapper(akz));
        alp3.<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(new EntityPosWrapper(akz), 0.6f, 1));
    }
    
    private Optional<LivingEntity> findSomeoneToChase(final PathfinderMob alg) {
        return this.getFriendsNearby(alg).stream().findAny();
    }
    
    private Optional<LivingEntity> findSomeoneBeingChased(final PathfinderMob alg) {
        final Map<LivingEntity, Integer> map3 = this.checkHowManyChasersEachFriendHas(alg);
        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 alg) {
        final Map<LivingEntity, Integer> map3 = Maps.newHashMap();
        final Integer n;
        this.getFriendsNearby(alg).stream().filter(this::isChasingSomeone).forEach(akz -> n = map3.compute(this.whoAreYouChasing(akz), (akz, integer) -> (integer == null) ? 1 : (integer + 1)));
        return map3;
    }
    
    private List<LivingEntity> getFriendsNearby(final PathfinderMob alg) {
        return alg.getBrain().<List<LivingEntity>>getMemory(MemoryModuleType.VISIBLE_VILLAGER_BABIES).get();
    }
    
    private LivingEntity whoAreYouChasing(final LivingEntity akz) {
        return akz.getBrain().<LivingEntity>getMemory(MemoryModuleType.INTERACTION_TARGET).get();
    }
    
    @Nullable
    private LivingEntity seeIfSomeoneIsChasingMe(final LivingEntity akz) {
        return akz.getBrain().<List<LivingEntity>>getMemory(MemoryModuleType.VISIBLE_VILLAGER_BABIES).get().stream().filter(akz2 -> this.isFriendChasingMe(akz, akz2)).findAny().orElse(null);
    }
    
    private boolean isChasingSomeone(final LivingEntity akz) {
        return akz.getBrain().<LivingEntity>getMemory(MemoryModuleType.INTERACTION_TARGET).isPresent();
    }
    
    private boolean isFriendChasingMe(final LivingEntity akz1, final LivingEntity akz2) {
        return akz2.getBrain().<LivingEntity>getMemory(MemoryModuleType.INTERACTION_TARGET).filter(akz2 -> akz2 == akz1).isPresent();
    }
    
    private boolean hasFriendsNearby(final PathfinderMob alg) {
        return alg.getBrain().hasMemoryValue(MemoryModuleType.VISIBLE_VILLAGER_BABIES);
    }
}
