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

import java.util.List;
import com.google.common.collect.ImmutableList;
import java.util.Set;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.schedule.Activity;
import net.minecraft.world.level.block.state.BlockState;
import java.util.Optional;
import net.minecraft.world.entity.ai.Brain;
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.Position;
import net.minecraft.server.level.ServerLevel;
import java.util.Map;
import net.minecraft.core.GlobalPos;
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.LivingEntity;

public class SleepInBed extends Behavior<LivingEntity> {
    private long nextOkStartTime;
    
    public SleepInBed() {
        super(ImmutableMap.<MemoryModuleType<GlobalPos>, MemoryStatus>of(MemoryModuleType.HOME, MemoryStatus.VALUE_PRESENT, (MemoryModuleType<GlobalPos>)MemoryModuleType.LAST_WOKEN, MemoryStatus.REGISTERED));
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel zd, final LivingEntity aoy) {
        if (aoy.isPassenger()) {
            return false;
        }
        final Brain<?> apr4 = aoy.getBrain();
        final GlobalPos gc5 = apr4.<GlobalPos>getMemory(MemoryModuleType.HOME).get();
        if (zd.dimension() != gc5.dimension()) {
            return false;
        }
        final Optional<Long> optional6 = apr4.<Long>getMemory(MemoryModuleType.LAST_WOKEN);
        if (optional6.isPresent()) {
            final long long7 = zd.getGameTime() - optional6.get();
            if (long7 > 0L && long7 < 100L) {
                return false;
            }
        }
        final BlockState cfj7 = zd.getBlockState(gc5.pos());
        return gc5.pos().closerThan(aoy.position(), 2.0) && cfj7.getBlock().is(BlockTags.BEDS) && !cfj7.<Boolean>getValue((Property<Boolean>)BedBlock.OCCUPIED);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel zd, final LivingEntity aoy, final long long3) {
        final Optional<GlobalPos> optional6 = aoy.getBrain().<GlobalPos>getMemory(MemoryModuleType.HOME);
        if (!optional6.isPresent()) {
            return false;
        }
        final BlockPos fu7 = optional6.get().pos();
        return aoy.getBrain().isActive(Activity.REST) && aoy.getY() > fu7.getY() + 0.4 && fu7.closerThan(aoy.position(), 1.14);
    }
    
    @Override
    protected void start(final ServerLevel zd, final LivingEntity aoy, final long long3) {
        if (long3 > this.nextOkStartTime) {
            aoy.getBrain().<Set<GlobalPos>>getMemory(MemoryModuleType.OPENED_DOORS).ifPresent(set -> InteractWithDoor.closeAllOpenedDoors(zd, ImmutableList.of(), 0, aoy, aoy.getBrain()));
            aoy.startSleeping(aoy.getBrain().<GlobalPos>getMemory(MemoryModuleType.HOME).get().pos());
        }
    }
    
    @Override
    protected boolean timedOut(final long long1) {
        return false;
    }
    
    @Override
    protected void stop(final ServerLevel zd, final LivingEntity aoy, final long long3) {
        if (aoy.isSleeping()) {
            aoy.stopSleeping();
            this.nextOkStartTime = long3 + 40L;
        }
    }
}
