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

import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.tags.Tag;
import net.minecraft.tags.BlockTags;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.network.protocol.game.DebugPackets;
import net.minecraft.core.Position;
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.village.poi.PoiType;
import java.util.function.Predicate;
import net.minecraft.core.GlobalPos;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.LivingEntity;

public class ValidateNearbyPoi extends Behavior<LivingEntity> {
    private final MemoryModuleType<GlobalPos> memoryType;
    private final Predicate<PoiType> poiPredicate;
    
    public ValidateNearbyPoi(final PoiType ayc, final MemoryModuleType<GlobalPos> awp) {
        super(ImmutableMap.<MemoryModuleType<GlobalPos>, MemoryStatus>of(awp, MemoryStatus.VALUE_PRESENT));
        this.poiPredicate = ayc.getPredicate();
        this.memoryType = awp;
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final LivingEntity aoy) {
        final GlobalPos gc4 = aoy.getBrain().<GlobalPos>getMemory(this.memoryType).get();
        return zd.dimension() == gc4.dimension() && gc4.pos().closerThan(aoy.position(), 16.0);
    }
    
    @Override
    protected void start(final ServerLevel zd, final LivingEntity aoy, final long long3) {
        final Brain<?> apr6 = aoy.getBrain();
        final GlobalPos gc7 = apr6.<GlobalPos>getMemory(this.memoryType).get();
        final BlockPos fu8 = gc7.pos();
        final ServerLevel zd2 = zd.getServer().getLevel(gc7.dimension());
        if (zd2 == null || this.poiDoesntExist(zd2, fu8)) {
            apr6.<GlobalPos>eraseMemory(this.memoryType);
        }
        else if (this.bedIsOccupied(zd2, fu8, aoy)) {
            apr6.<GlobalPos>eraseMemory(this.memoryType);
            zd.getPoiManager().release(fu8);
            DebugPackets.sendPoiTicketCountPacket(zd, fu8);
        }
    }
    
    private boolean bedIsOccupied(final ServerLevel zd, final BlockPos fu, final LivingEntity aoy) {
        final BlockState cfj5 = zd.getBlockState(fu);
        return cfj5.getBlock().is(BlockTags.BEDS) && cfj5.<Boolean>getValue((Property<Boolean>)BedBlock.OCCUPIED) && !aoy.isSleeping();
    }
    
    private boolean poiDoesntExist(final ServerLevel zd, final BlockPos fu) {
        return !zd.getPoiManager().exists(fu, this.poiPredicate);
    }
}
