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

import java.util.function.Predicate;
import java.util.Optional;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.AgableMob;
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.EntityType;
import net.minecraft.world.entity.animal.Animal;

public class AnimalMakeLove extends Behavior<Animal> {
    private final EntityType<? extends Animal> partnerType;
    private final float speedModifier;
    private long spawnChildAtTime;
    
    public AnimalMakeLove(final EntityType<? extends Animal> aoq, final float float2) {
        super(ImmutableMap.<MemoryModuleType<List<LivingEntity>>, MemoryStatus>of(MemoryModuleType.VISIBLE_LIVING_ENTITIES, MemoryStatus.VALUE_PRESENT, (MemoryModuleType<List<LivingEntity>>)MemoryModuleType.BREED_TARGET, MemoryStatus.VALUE_ABSENT, (MemoryModuleType<List<LivingEntity>>)MemoryModuleType.WALK_TARGET, MemoryStatus.REGISTERED, (MemoryModuleType<List<LivingEntity>>)MemoryModuleType.LOOK_TARGET, MemoryStatus.REGISTERED), 325);
        this.partnerType = aoq;
        this.speedModifier = float2;
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final Animal ayk) {
        return ayk.isInLove() && this.findValidBreedPartner(ayk).isPresent();
    }
    
    @Override
    protected void start(final ServerLevel zd, final Animal ayk, final long long3) {
        final Animal ayk2 = (Animal)this.findValidBreedPartner(ayk).get();
        ayk.getBrain().<AgableMob>setMemory(MemoryModuleType.BREED_TARGET, ayk2);
        ayk2.getBrain().<AgableMob>setMemory(MemoryModuleType.BREED_TARGET, ayk);
        BehaviorUtils.lockGazeAndWalkToEachOther(ayk, ayk2, this.speedModifier);
        final int integer7 = 275 + ayk.getRandom().nextInt(50);
        this.spawnChildAtTime = long3 + integer7;
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel zd, final Animal ayk, final long long3) {
        if (!this.hasBreedTargetOfRightType(ayk)) {
            return false;
        }
        final Animal ayk2 = this.getBreedTarget(ayk);
        return ayk2.isAlive() && ayk.canMate(ayk2) && BehaviorUtils.entityIsVisible(ayk.getBrain(), ayk2) && long3 <= this.spawnChildAtTime;
    }
    
    @Override
    protected void stop(final ServerLevel zd, final Animal ayk, final long long3) {
        final Animal ayk2 = this.getBreedTarget(ayk);
        BehaviorUtils.lockGazeAndWalkToEachOther(ayk, ayk2, this.speedModifier);
        if (!ayk.closerThan(ayk2, 3.0)) {
            return;
        }
        if (long3 >= this.spawnChildAtTime) {
            ayk.spawnChildFromBreeding(zd, ayk2);
            ayk.getBrain().<AgableMob>eraseMemory(MemoryModuleType.BREED_TARGET);
            ayk2.getBrain().<AgableMob>eraseMemory(MemoryModuleType.BREED_TARGET);
        }
    }
    
    @Override
    protected void stop(final ServerLevel zd, final Animal ayk, final long long3) {
        ayk.getBrain().<AgableMob>eraseMemory(MemoryModuleType.BREED_TARGET);
        ayk.getBrain().<WalkTarget>eraseMemory(MemoryModuleType.WALK_TARGET);
        ayk.getBrain().<PositionTracker>eraseMemory(MemoryModuleType.LOOK_TARGET);
        this.spawnChildAtTime = 0L;
    }
    
    private Animal getBreedTarget(final Animal ayk) {
        return ayk.getBrain().<Animal>getMemory((MemoryModuleType<Animal>)MemoryModuleType.BREED_TARGET).get();
    }
    
    private boolean hasBreedTargetOfRightType(final Animal ayk) {
        final Brain<?> apr3 = ayk.getBrain();
        return apr3.hasMemoryValue(MemoryModuleType.BREED_TARGET) && apr3.<AgableMob>getMemory(MemoryModuleType.BREED_TARGET).get().getType() == this.partnerType;
    }
    
    private Optional<? extends Animal> findValidBreedPartner(final Animal ayk) {
        return ayk.getBrain().<List<LivingEntity>>getMemory(MemoryModuleType.VISIBLE_LIVING_ENTITIES).get().stream().filter(aoy -> aoy.getType() == this.partnerType).map(aoy -> aoy).filter(ayk::canMate).findFirst();
    }
}
