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

import net.minecraft.core.GlobalPos;
import net.minecraft.world.entity.AgableMob;
import net.minecraft.world.level.pathfinder.Path;
import net.minecraft.world.entity.ai.village.poi.PoiType;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.EntityType;
import java.util.Optional;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.server.level.ServerLevel;
import java.util.Map;
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.npc.Villager;

public class MakeLove extends Behavior<Villager> {
    private long birthTimestamp;
    
    public MakeLove() {
        super(ImmutableMap.<MemoryModuleType<Villager>, MemoryStatus>of(MemoryModuleType.BREED_TARGET, MemoryStatus.VALUE_PRESENT, (MemoryModuleType<Villager>)MemoryModuleType.VISIBLE_LIVING_ENTITIES, MemoryStatus.VALUE_PRESENT), 350, 350);
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel xd, final Villager axw) {
        return this.isBreedingPossible(axw);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel xd, final Villager axw, final long long3) {
        return long3 <= this.birthTimestamp && this.isBreedingPossible(axw);
    }
    
    @Override
    protected void start(final ServerLevel xd, final Villager axw, final long long3) {
        final Villager axw2 = this.getBreedingTarget(axw);
        BehaviorUtils.lockGazeAndWalkToEachOther(axw, axw2);
        xd.broadcastEntityEvent(axw2, (byte)18);
        xd.broadcastEntityEvent(axw, (byte)18);
        final int integer7 = 275 + axw.getRandom().nextInt(50);
        this.birthTimestamp = long3 + integer7;
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        final Villager axw2 = this.getBreedingTarget(axw);
        if (axw.distanceToSqr(axw2) > 5.0) {
            return;
        }
        BehaviorUtils.lockGazeAndWalkToEachOther(axw, axw2);
        if (long3 >= this.birthTimestamp) {
            axw.eatAndDigestFood();
            axw2.eatAndDigestFood();
            this.tryToGiveBirth(xd, axw, axw2);
        }
        else if (axw.getRandom().nextInt(35) == 0) {
            xd.broadcastEntityEvent(axw2, (byte)12);
            xd.broadcastEntityEvent(axw, (byte)12);
        }
    }
    
    private void tryToGiveBirth(final ServerLevel xd, final Villager axw2, final Villager axw3) {
        final Optional<BlockPos> optional5 = this.takeVacantBed(xd, axw2);
        if (!optional5.isPresent()) {
            xd.broadcastEntityEvent(axw3, (byte)13);
            xd.broadcastEntityEvent(axw2, (byte)13);
        }
        else {
            final Optional<Villager> optional6 = this.breed(axw2, axw3);
            if (optional6.isPresent()) {
                this.giveBedToChild(xd, optional6.get(), optional5.get());
            }
            else {
                xd.getPoiManager().release(optional5.get());
                DebugPackets.sendPoiTicketCountPacket(xd, optional5.get());
            }
        }
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        axw.getBrain().<Villager>eraseMemory(MemoryModuleType.BREED_TARGET);
    }
    
    private Villager getBreedingTarget(final Villager axw) {
        return axw.getBrain().<Villager>getMemory(MemoryModuleType.BREED_TARGET).get();
    }
    
    private boolean isBreedingPossible(final Villager axw) {
        final Brain<Villager> alp3 = axw.getBrain();
        if (!alp3.<Villager>getMemory(MemoryModuleType.BREED_TARGET).isPresent()) {
            return false;
        }
        final Villager axw2 = this.getBreedingTarget(axw);
        return BehaviorUtils.targetIsValid(alp3, MemoryModuleType.BREED_TARGET, EntityType.VILLAGER) && axw.canBreed() && axw2.canBreed();
    }
    
    private Optional<BlockPos> takeVacantBed(final ServerLevel xd, final Villager axw) {
        return xd.getPoiManager().take(PoiType.HOME.getPredicate(), fk -> this.canReach(axw, fk), new BlockPos(axw), 48);
    }
    
    private boolean canReach(final Villager axw, final BlockPos fk) {
        final Path cqq4 = axw.getNavigation().createPath(fk, PoiType.HOME.getValidRange());
        return cqq4 != null && cqq4.canReach();
    }
    
    private Optional<Villager> breed(final Villager axw1, final Villager axw2) {
        final Villager axw3 = axw1.getBreedOffspring((AgableMob)axw2);
        if (axw3 == null) {
            return Optional.<Villager>empty();
        }
        axw1.setAge(6000);
        axw2.setAge(6000);
        axw3.setAge(-24000);
        axw3.moveTo(axw1.getX(), axw1.getY(), axw1.getZ(), 0.0f, 0.0f);
        axw1.level.addFreshEntity(axw3);
        axw1.level.broadcastEntityEvent(axw3, (byte)12);
        return Optional.<Villager>of(axw3);
    }
    
    private void giveBedToChild(final ServerLevel xd, final Villager axw, final BlockPos fk) {
        final GlobalPos fr5 = GlobalPos.of(xd.getDimension().getType(), fk);
        axw.getBrain().<GlobalPos>setMemory(MemoryModuleType.HOME, fr5);
    }
}
