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

import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.entity.ai.memory.WalkTarget;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.FarmBlock;
import net.minecraft.world.level.block.CropBlock;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.SimpleContainer;
import net.minecraft.core.Vec3i;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.Items;
import net.minecraft.world.entity.npc.VillagerProfession;
import net.minecraft.world.level.GameRules;
import net.minecraft.server.level.ServerLevel;
import com.google.common.collect.Lists;
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 java.util.List;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.npc.Villager;

public class HarvestFarmland extends Behavior<Villager> {
    @Nullable
    private BlockPos aboveFarmlandPos;
    private boolean canPlantStuff;
    private boolean wantsToReapStuff;
    private long nextOkStartTime;
    private int timeWorkedSoFar;
    private final List<BlockPos> validFarmlandAroundVillager;
    
    public HarvestFarmland() {
        super(ImmutableMap.<MemoryModuleType<PositionWrapper>, MemoryStatus>of(MemoryModuleType.LOOK_TARGET, MemoryStatus.VALUE_ABSENT, (MemoryModuleType<PositionWrapper>)MemoryModuleType.WALK_TARGET, MemoryStatus.VALUE_ABSENT, (MemoryModuleType<PositionWrapper>)MemoryModuleType.SECONDARY_JOB_SITE, MemoryStatus.VALUE_PRESENT));
        this.validFarmlandAroundVillager = Lists.newArrayList();
    }
    
    @Override
    protected boolean checkExtraStartConditions(final ServerLevel xd, final Villager axw) {
        if (!xd.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
            return false;
        }
        if (axw.getVillagerData().getProfession() != VillagerProfession.FARMER) {
            return false;
        }
        this.canPlantStuff = axw.hasFarmSeeds();
        this.wantsToReapStuff = false;
        final SimpleContainer ajq4 = axw.getInventory();
        for (int integer5 = ajq4.getContainerSize(), integer6 = 0; integer6 < integer5; ++integer6) {
            final ItemStack ben7 = ajq4.getItem(integer6);
            if (ben7.isEmpty()) {
                this.wantsToReapStuff = true;
                break;
            }
            if (ben7.getItem() == Items.WHEAT_SEEDS || ben7.getItem() == Items.BEETROOT_SEEDS) {
                this.wantsToReapStuff = true;
                break;
            }
        }
        final BlockPos.MutableBlockPos a6 = new BlockPos.MutableBlockPos(axw);
        this.validFarmlandAroundVillager.clear();
        for (int integer7 = -1; integer7 <= 1; ++integer7) {
            for (int integer8 = -1; integer8 <= 1; ++integer8) {
                for (int integer9 = -1; integer9 <= 1; ++integer9) {
                    a6.set(axw.getX() + integer7, axw.getY() + integer8, axw.getZ() + integer9);
                    if (this.validPos(a6, xd)) {
                        this.validFarmlandAroundVillager.add(new BlockPos(a6));
                    }
                }
            }
        }
        this.aboveFarmlandPos = this.getValidFarmland(xd);
        return (this.canPlantStuff || this.wantsToReapStuff) && this.aboveFarmlandPos != null;
    }
    
    @Nullable
    private BlockPos getValidFarmland(final ServerLevel xd) {
        return this.validFarmlandAroundVillager.isEmpty() ? null : this.validFarmlandAroundVillager.get(xd.getRandom().nextInt(this.validFarmlandAroundVillager.size()));
    }
    
    private boolean validPos(final BlockPos fk, final ServerLevel xd) {
        final BlockState byj4 = xd.getBlockState(fk);
        final Block bph5 = byj4.getBlock();
        final Block bph6 = xd.getBlockState(fk.below()).getBlock();
        return (bph5 instanceof CropBlock && ((CropBlock)bph5).isMaxAge(byj4) && this.wantsToReapStuff) || (byj4.isAir() && bph6 instanceof FarmBlock && this.canPlantStuff);
    }
    
    @Override
    protected void start(final ServerLevel xd, final Villager axw, final long long3) {
        if (long3 > this.nextOkStartTime && this.aboveFarmlandPos != null) {
            axw.getBrain().<BlockPosWrapper>setMemory((MemoryModuleType<BlockPosWrapper>)MemoryModuleType.LOOK_TARGET, new BlockPosWrapper(this.aboveFarmlandPos));
            axw.getBrain().<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(new BlockPosWrapper(this.aboveFarmlandPos), 0.5f, 1));
        }
    }
    
    @Override
    protected void stop(final ServerLevel xd, final Villager axw, final long long3) {
        axw.getBrain().<PositionWrapper>eraseMemory(MemoryModuleType.LOOK_TARGET);
        axw.getBrain().<WalkTarget>eraseMemory(MemoryModuleType.WALK_TARGET);
        this.timeWorkedSoFar = 0;
        this.nextOkStartTime = long3 + 40L;
    }
    
    @Override
    protected void tick(final ServerLevel xd, final Villager axw, final long long3) {
        if (this.aboveFarmlandPos != null && long3 > this.nextOkStartTime) {
            final BlockState byj6 = xd.getBlockState(this.aboveFarmlandPos);
            final Block bph7 = byj6.getBlock();
            final Block bph8 = xd.getBlockState(this.aboveFarmlandPos.below()).getBlock();
            if (bph7 instanceof CropBlock && ((CropBlock)bph7).isMaxAge(byj6) && this.wantsToReapStuff) {
                xd.destroyBlock(this.aboveFarmlandPos, true, axw);
            }
            if (byj6.isAir() && bph8 instanceof FarmBlock && this.canPlantStuff) {
                final SimpleContainer ajq9 = axw.getInventory();
                int integer10 = 0;
                while (integer10 < ajq9.getContainerSize()) {
                    final ItemStack ben11 = ajq9.getItem(integer10);
                    boolean boolean12 = false;
                    if (!ben11.isEmpty()) {
                        if (ben11.getItem() == Items.WHEAT_SEEDS) {
                            xd.setBlock(this.aboveFarmlandPos, Blocks.WHEAT.defaultBlockState(), 3);
                            boolean12 = true;
                        }
                        else if (ben11.getItem() == Items.POTATO) {
                            xd.setBlock(this.aboveFarmlandPos, Blocks.POTATOES.defaultBlockState(), 3);
                            boolean12 = true;
                        }
                        else if (ben11.getItem() == Items.CARROT) {
                            xd.setBlock(this.aboveFarmlandPos, Blocks.CARROTS.defaultBlockState(), 3);
                            boolean12 = true;
                        }
                        else if (ben11.getItem() == Items.BEETROOT_SEEDS) {
                            xd.setBlock(this.aboveFarmlandPos, Blocks.BEETROOTS.defaultBlockState(), 3);
                            boolean12 = true;
                        }
                    }
                    if (boolean12) {
                        xd.playSound(null, this.aboveFarmlandPos.getX(), this.aboveFarmlandPos.getY(), this.aboveFarmlandPos.getZ(), SoundEvents.CROP_PLANTED, SoundSource.BLOCKS, 1.0f, 1.0f);
                        ben11.shrink(1);
                        if (ben11.isEmpty()) {
                            ajq9.setItem(integer10, ItemStack.EMPTY);
                            break;
                        }
                        break;
                    }
                    else {
                        ++integer10;
                    }
                }
            }
            if (bph7 instanceof CropBlock && !((CropBlock)bph7).isMaxAge(byj6)) {
                this.validFarmlandAroundVillager.remove(this.aboveFarmlandPos);
                this.aboveFarmlandPos = this.getValidFarmland(xd);
                if (this.aboveFarmlandPos != null) {
                    this.nextOkStartTime = long3 + 20L;
                    axw.getBrain().<WalkTarget>setMemory(MemoryModuleType.WALK_TARGET, new WalkTarget(new BlockPosWrapper(this.aboveFarmlandPos), 0.5f, 1));
                    axw.getBrain().<BlockPosWrapper>setMemory((MemoryModuleType<BlockPosWrapper>)MemoryModuleType.LOOK_TARGET, new BlockPosWrapper(this.aboveFarmlandPos));
                }
            }
        }
        ++this.timeWorkedSoFar;
    }
    
    @Override
    protected boolean canStillUse(final ServerLevel xd, final Villager axw, final long long3) {
        return this.timeWorkedSoFar < 200;
    }
}
