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.tags.BlockTags;
import net.minecraft.core.Position;
import net.minecraft.core.SerializableLong;
import java.util.Objects;
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 xd, final LivingEntity akz) {
        if (akz.isPassenger()) {
            return false;
        }
        final Brain<?> alp4 = akz.getBrain();
        final GlobalPos fr5 = alp4.<GlobalPos>getMemory(MemoryModuleType.HOME).get();
        if (!Objects.equals(xd.getDimension().getType(), fr5.dimension())) {
            return false;
        }
        final Optional<SerializableLong> optional6 = alp4.<SerializableLong>getMemory(MemoryModuleType.LAST_WOKEN);
        if (optional6.isPresent() && xd.getGameTime() - optional6.get().value() < 100L) {
            return false;
        }
        final BlockState byj7 = xd.getBlockState(fr5.pos());
        return fr5.pos().closerThan(akz.position(), 2.0) && byj7.getBlock().is(BlockTags.BEDS) && !byj7.<Boolean>getValue((Property<Boolean>)BedBlock.OCCUPIED);
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel xd, final LivingEntity akz, final long long3) {
        final Optional<GlobalPos> optional6 = akz.getBrain().<GlobalPos>getMemory(MemoryModuleType.HOME);
        if (!optional6.isPresent()) {
            return false;
        }
        final BlockPos fk7 = optional6.get().pos();
        return akz.getBrain().isActive(Activity.REST) && akz.getY() > fk7.getY() + 0.4 && fk7.closerThan(akz.position(), 1.14);
    }
    
    @Override
    protected void start(final ServerLevel xd, final LivingEntity akz, final long long3) {
        if (long3 > this.nextOkStartTime) {
            akz.getBrain().<Set<GlobalPos>>getMemory(MemoryModuleType.OPENED_DOORS).ifPresent(set -> InteractWithDoor.closeAllOpenedDoors(xd, ImmutableList.of(), 0, akz, akz.getBrain()));
            akz.startSleeping(akz.getBrain().<GlobalPos>getMemory(MemoryModuleType.HOME).get().pos());
        }
    }
    
    @Override
    protected boolean timedOut(final long long1) {
        return false;
    }
    
    @Override
    protected void stop(final ServerLevel xd, final LivingEntity akz, final long long3) {
        if (akz.isSleeping()) {
            akz.stopSleeping();
            this.nextOkStartTime = long3 + 40L;
        }
    }
}
