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

import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkStatus;
import javax.annotation.Nullable;
import net.minecraft.world.phys.Vec3;
import java.util.Random;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.core.particles.ItemParticleOption;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.level.block.Block;

public class RemoveBlockGoal extends MoveToBlockGoal {
    private final Block blockToRemove;
    private final Mob removerMob;
    private int ticksSinceReachedGoal;
    
    public RemoveBlockGoal(final Block bvr, final PathfinderMob apg, final double double3, final int integer) {
        super(apg, double3, 24, integer);
        this.blockToRemove = bvr;
        this.removerMob = apg;
    }
    
    @Override
    public boolean canUse() {
        if (!this.removerMob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
            return false;
        }
        if (this.nextStartTick > 0) {
            --this.nextStartTick;
            return false;
        }
        if (this.tryFindBlock()) {
            this.nextStartTick = 20;
            return true;
        }
        this.nextStartTick = this.nextStartTick(this.mob);
        return false;
    }
    
    private boolean tryFindBlock() {
        return (this.blockPos != null && this.isValidTarget(this.mob.level, this.blockPos)) || this.findNearestBlock();
    }
    
    @Override
    public void stop() {
        super.stop();
        this.removerMob.fallDistance = 1.0f;
    }
    
    @Override
    public void start() {
        super.start();
        this.ticksSinceReachedGoal = 0;
    }
    
    public void playDestroyProgressSound(final LevelAccessor bqc, final BlockPos fu) {
    }
    
    public void playBreakSound(final Level bqb, final BlockPos fu) {
    }
    
    @Override
    public void tick() {
        super.tick();
        final Level bqb2 = this.removerMob.level;
        final BlockPos fu3 = this.removerMob.blockPosition();
        final BlockPos fu4 = this.getPosWithBlock(fu3, bqb2);
        final Random random5 = this.removerMob.getRandom();
        if (this.isReachedTarget() && fu4 != null) {
            if (this.ticksSinceReachedGoal > 0) {
                final Vec3 dem6 = this.removerMob.getDeltaMovement();
                this.removerMob.setDeltaMovement(dem6.x, 0.3, dem6.z);
                if (!bqb2.isClientSide) {
                    final double double7 = 0.08;
                    ((ServerLevel)bqb2).<ItemParticleOption>sendParticles(new ItemParticleOption(ParticleTypes.ITEM, new ItemStack(Items.EGG)), fu4.getX() + 0.5, fu4.getY() + 0.7, fu4.getZ() + 0.5, 3, (random5.nextFloat() - 0.5) * 0.08, (random5.nextFloat() - 0.5) * 0.08, (random5.nextFloat() - 0.5) * 0.08, 0.15000000596046448);
                }
            }
            if (this.ticksSinceReachedGoal % 2 == 0) {
                final Vec3 dem6 = this.removerMob.getDeltaMovement();
                this.removerMob.setDeltaMovement(dem6.x, -0.3, dem6.z);
                if (this.ticksSinceReachedGoal % 6 == 0) {
                    this.playDestroyProgressSound(bqb2, this.blockPos);
                }
            }
            if (this.ticksSinceReachedGoal > 60) {
                bqb2.removeBlock(fu4, false);
                if (!bqb2.isClientSide) {
                    for (int integer6 = 0; integer6 < 20; ++integer6) {
                        final double double7 = random5.nextGaussian() * 0.02;
                        final double double8 = random5.nextGaussian() * 0.02;
                        final double double9 = random5.nextGaussian() * 0.02;
                        ((ServerLevel)bqb2).<SimpleParticleType>sendParticles(ParticleTypes.POOF, fu4.getX() + 0.5, fu4.getY(), fu4.getZ() + 0.5, 1, double7, double8, double9, 0.15000000596046448);
                    }
                    this.playBreakSound(bqb2, fu4);
                }
            }
            ++this.ticksSinceReachedGoal;
        }
    }
    
    @Nullable
    private BlockPos getPosWithBlock(final BlockPos fu, final BlockGetter bpg) {
        if (bpg.getBlockState(fu).is(this.blockToRemove)) {
            return fu;
        }
        final BlockPos[] array;
        final BlockPos[] arr4 = array = new BlockPos[] { fu.below(), fu.west(), fu.east(), fu.north(), fu.south(), fu.below().below() };
        for (final BlockPos fu2 : array) {
            if (bpg.getBlockState(fu2).is(this.blockToRemove)) {
                return fu2;
            }
        }
        return null;
    }
    
    @Override
    protected boolean isValidTarget(final LevelReader bqd, final BlockPos fu) {
        final ChunkAccess cgy4 = bqd.getChunk(fu.getX() >> 4, fu.getZ() >> 4, ChunkStatus.FULL, false);
        return cgy4 != null && cgy4.getBlockState(fu).is(this.blockToRemove) && cgy4.getBlockState(fu.above()).isAir() && cgy4.getBlockState(fu.above(2)).isAir();
    }
}
