package net.minecraft.world.entity.monster;

import java.util.EnumSet;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.ai.goal.RandomStrollGoal;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.MobType;
import java.util.Random;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.InfestedBlock;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.entity.EntityDimensions;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.ai.goal.target.NearestAttackableTargetGoal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.ai.goal.target.HurtByTargetGoal;
import net.minecraft.world.entity.PathfinderMob;
import net.minecraft.world.entity.ai.goal.MeleeAttackGoal;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.ai.goal.FloatGoal;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;

public class Silverfish extends Monster {
    private SilverfishWakeUpFriendsGoal friendsGoal;
    
    public Silverfish(final EntityType<? extends Silverfish> aku, final Level bjw) {
        super(aku, bjw);
    }
    
    @Override
    protected void registerGoals() {
        this.friendsGoal = new SilverfishWakeUpFriendsGoal(this);
        this.goalSelector.addGoal(1, new FloatGoal(this));
        this.goalSelector.addGoal(3, this.friendsGoal);
        this.goalSelector.addGoal(4, new MeleeAttackGoal(this, 1.0, false));
        this.goalSelector.addGoal(5, new SilverfishMergeWithStoneGoal(this));
        this.targetSelector.addGoal(1, new HurtByTargetGoal(this, new Class[0]).setAlertOthers(new Class[0]));
        this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true));
    }
    
    @Override
    public double getRidingHeight() {
        return 0.1;
    }
    
    @Override
    protected float getStandingEyeHeight(final Pose alj, final EntityDimensions akr) {
        return 0.1f;
    }
    
    @Override
    protected void registerAttributes() {
        super.registerAttributes();
        this.getAttribute(SharedMonsterAttributes.MAX_HEALTH).setBaseValue(8.0);
        this.getAttribute(SharedMonsterAttributes.MOVEMENT_SPEED).setBaseValue(0.25);
        this.getAttribute(SharedMonsterAttributes.ATTACK_DAMAGE).setBaseValue(1.0);
    }
    
    @Override
    protected boolean isMovementNoisy() {
        return false;
    }
    
    @Override
    protected SoundEvent getAmbientSound() {
        return SoundEvents.SILVERFISH_AMBIENT;
    }
    
    @Override
    protected SoundEvent getHurtSound(final DamageSource ajz) {
        return SoundEvents.SILVERFISH_HURT;
    }
    
    @Override
    protected SoundEvent getDeathSound() {
        return SoundEvents.SILVERFISH_DEATH;
    }
    
    @Override
    protected void playStepSound(final BlockPos fk, final BlockState byj) {
        this.playSound(SoundEvents.SILVERFISH_STEP, 0.15f, 1.0f);
    }
    
    @Override
    public boolean hurt(final DamageSource ajz, final float float2) {
        if (this.isInvulnerableTo(ajz)) {
            return false;
        }
        if ((ajz instanceof EntityDamageSource || ajz == DamageSource.MAGIC) && this.friendsGoal != null) {
            this.friendsGoal.notifyHurt();
        }
        return super.hurt(ajz, float2);
    }
    
    @Override
    public void tick() {
        this.yBodyRot = this.yRot;
        super.tick();
    }
    
    @Override
    public void setYBodyRot(final float float1) {
        super.setYBodyRot(this.yRot = float1);
    }
    
    @Override
    public float getWalkTargetValue(final BlockPos fk, final LevelReader bjz) {
        if (InfestedBlock.isCompatibleHostBlock(bjz.getBlockState(fk.below()))) {
            return 10.0f;
        }
        return super.getWalkTargetValue(fk, bjz);
    }
    
    public static boolean checkSliverfishSpawnRules(final EntityType<Silverfish> aku, final LevelAccessor bjx, final MobSpawnType alc, final BlockPos fk, final Random random) {
        if (Monster.checkAnyLightMonsterSpawnRules(aku, bjx, alc, fk, random)) {
            final Player ayj6 = bjx.getNearestPlayer(fk.getX() + 0.5, fk.getY() + 0.5, fk.getZ() + 0.5, 5.0, true);
            return ayj6 == null;
        }
        return false;
    }
    
    @Override
    public MobType getMobType() {
        return MobType.ARTHROPOD;
    }
    
    static class SilverfishWakeUpFriendsGoal extends Goal {
        private final Silverfish silverfish;
        private int lookForFriends;
        
        public SilverfishWakeUpFriendsGoal(final Silverfish axf) {
            this.silverfish = axf;
        }
        
        public void notifyHurt() {
            if (this.lookForFriends == 0) {
                this.lookForFriends = 20;
            }
        }
        
        @Override
        public boolean canUse() {
            return this.lookForFriends > 0;
        }
        
        @Override
        public void tick() {
            --this.lookForFriends;
            Label_0241: {
                if (this.lookForFriends <= 0) {
                    final Level bjw2 = this.silverfish.level;
                    final Random random3 = this.silverfish.getRandom();
                    final BlockPos fk4 = new BlockPos(this.silverfish);
                    for (int integer5 = 0; integer5 <= 5 && integer5 >= -5; integer5 = ((integer5 <= 0) ? 1 : 0) - integer5) {
                        for (int integer6 = 0; integer6 <= 10 && integer6 >= -10; integer6 = ((integer6 <= 0) ? 1 : 0) - integer6) {
                            for (int integer7 = 0; integer7 <= 10 && integer7 >= -10; integer7 = ((integer7 <= 0) ? 1 : 0) - integer7) {
                                final BlockPos fk5 = fk4.offset(integer6, integer5, integer7);
                                final BlockState byj9 = bjw2.getBlockState(fk5);
                                final Block bph10 = byj9.getBlock();
                                if (bph10 instanceof InfestedBlock) {
                                    if (bjw2.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
                                        bjw2.destroyBlock(fk5, true, this.silverfish);
                                    }
                                    else {
                                        bjw2.setBlock(fk5, ((InfestedBlock)bph10).getHostBlock().defaultBlockState(), 3);
                                    }
                                    if (random3.nextBoolean()) {
                                        break Label_0241;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    static class SilverfishMergeWithStoneGoal extends RandomStrollGoal {
        private Direction selectedDirection;
        private boolean doMerge;
        
        public SilverfishMergeWithStoneGoal(final Silverfish axf) {
            super(axf, 1.0, 10);
            this.setFlags(EnumSet.<Flag>of(Flag.MOVE));
        }
        
        @Override
        public boolean canUse() {
            if (this.mob.getTarget() != null) {
                return false;
            }
            if (!this.mob.getNavigation().isDone()) {
                return false;
            }
            final Random random2 = this.mob.getRandom();
            if (this.mob.level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && random2.nextInt(10) == 0) {
                this.selectedDirection = Direction.getRandomFace(random2);
                final BlockPos fk3 = new BlockPos(this.mob.getX(), this.mob.getY() + 0.5, this.mob.getZ()).relative(this.selectedDirection);
                final BlockState byj4 = this.mob.level.getBlockState(fk3);
                if (InfestedBlock.isCompatibleHostBlock(byj4)) {
                    return this.doMerge = true;
                }
            }
            this.doMerge = false;
            return super.canUse();
        }
        
        @Override
        public boolean canContinueToUse() {
            return !this.doMerge && super.canContinueToUse();
        }
        
        @Override
        public void start() {
            if (!this.doMerge) {
                super.start();
                return;
            }
            final LevelAccessor bjx2 = this.mob.level;
            final BlockPos fk3 = new BlockPos(this.mob.getX(), this.mob.getY() + 0.5, this.mob.getZ()).relative(this.selectedDirection);
            final BlockState byj4 = bjx2.getBlockState(fk3);
            if (InfestedBlock.isCompatibleHostBlock(byj4)) {
                bjx2.setBlock(fk3, InfestedBlock.stateByHostBlock(byj4.getBlock()), 3);
                this.mob.spawnAnim();
                this.mob.remove();
            }
        }
    }
}
