package net.minecraft.world.entity.animal;

import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.entity.AgableMob;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.FlowerBlock;
import net.minecraft.world.item.BlockItem;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import java.util.Optional;
import net.minecraft.sounds.SoundEvent;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.item.Item;
import net.minecraft.tags.Tag;
import net.minecraft.tags.ItemTags;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.item.ItemUtils;
import net.minecraft.world.item.SuspiciousStewItem;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.LightningBolt;
import java.util.Random;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.LevelReader;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import java.util.UUID;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.world.entity.Shearable;

public class MushroomCow extends Cow implements Shearable {
    private static final EntityDataAccessor<String> DATA_TYPE;
    private MobEffect effect;
    private int effectDuration;
    private UUID lastLightningBoltUUID;
    
    public MushroomCow(final EntityType<? extends MushroomCow> aoq, final Level bqb) {
        super(aoq, bqb);
    }
    
    @Override
    public float getWalkTargetValue(final BlockPos fu, final LevelReader bqd) {
        if (bqd.getBlockState(fu.below()).is(Blocks.MYCELIUM)) {
            return 10.0f;
        }
        return bqd.getBrightness(fu) - 0.5f;
    }
    
    public static boolean checkMushroomSpawnRules(final EntityType<MushroomCow> aoq, final LevelAccessor bqc, final MobSpawnType apb, final BlockPos fu, final Random random) {
        return bqc.getBlockState(fu.below()).is(Blocks.MYCELIUM) && bqc.getRawBrightness(fu, 0) > 8;
    }
    
    @Override
    public void thunderHit(final LightningBolt aox) {
        final UUID uUID3 = aox.getUUID();
        if (!uUID3.equals(this.lastLightningBoltUUID)) {
            this.setMushroomType((this.getMushroomType() == MushroomType.RED) ? MushroomType.BROWN : MushroomType.RED);
            this.lastLightningBoltUUID = uUID3;
            this.playSound(SoundEvents.MOOSHROOM_CONVERT, 2.0f, 1.0f);
        }
    }
    
    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.<String>define(MushroomCow.DATA_TYPE, MushroomType.RED.type);
    }
    
    @Override
    public InteractionResult mobInteract(final Player bec, final InteractionHand anf) {
        final ItemStack bki4 = bec.getItemInHand(anf);
        if (bki4.getItem() == Items.BOWL && !this.isBaby()) {
            boolean boolean6 = false;
            ItemStack bki5;
            if (this.effect != null) {
                boolean6 = true;
                bki5 = new ItemStack(Items.SUSPICIOUS_STEW);
                SuspiciousStewItem.saveMobEffect(bki5, this.effect, this.effectDuration);
                this.effect = null;
                this.effectDuration = 0;
            }
            else {
                bki5 = new ItemStack(Items.MUSHROOM_STEW);
            }
            final ItemStack bki6 = ItemUtils.createBucketResult(bki4, bec, bki5);
            bec.setItemInHand(anf, bki6);
            SoundEvent ack8;
            if (boolean6) {
                ack8 = SoundEvents.MOOSHROOM_MILK_SUSPICIOUSLY;
            }
            else {
                ack8 = SoundEvents.MOOSHROOM_MILK;
            }
            this.playSound(ack8, 1.0f, 1.0f);
            return InteractionResult.sidedSuccess(this.level.isClientSide);
        }
        if (bki4.getItem() == Items.SHEARS && this.readyForShearing()) {
            this.shear(SoundSource.PLAYERS);
            if (!this.level.isClientSide) {
                bki4.<Player>hurtAndBreak(1, bec, bec -> bec.broadcastBreakEvent(anf));
            }
            return InteractionResult.sidedSuccess(this.level.isClientSide);
        }
        if (this.getMushroomType() == MushroomType.BROWN && bki4.getItem().is(ItemTags.SMALL_FLOWERS)) {
            if (this.effect != null) {
                for (int integer5 = 0; integer5 < 2; ++integer5) {
                    this.level.addParticle(ParticleTypes.SMOKE, this.getX() + this.random.nextDouble() / 2.0, this.getY(0.5), this.getZ() + this.random.nextDouble() / 2.0, 0.0, this.random.nextDouble() / 5.0, 0.0);
                }
            }
            else {
                final Optional<Pair<MobEffect, Integer>> optional5 = this.getEffectFromItemStack(bki4);
                if (!optional5.isPresent()) {
                    return InteractionResult.PASS;
                }
                final Pair<MobEffect, Integer> pair6 = optional5.get();
                if (!bec.abilities.instabuild) {
                    bki4.shrink(1);
                }
                for (int integer6 = 0; integer6 < 4; ++integer6) {
                    this.level.addParticle(ParticleTypes.EFFECT, this.getX() + this.random.nextDouble() / 2.0, this.getY(0.5), this.getZ() + this.random.nextDouble() / 2.0, 0.0, this.random.nextDouble() / 5.0, 0.0);
                }
                this.effect = (MobEffect)pair6.getLeft();
                this.effectDuration = (int)pair6.getRight();
                this.playSound(SoundEvents.MOOSHROOM_EAT, 2.0f, 1.0f);
            }
            return InteractionResult.sidedSuccess(this.level.isClientSide);
        }
        return super.mobInteract(bec, anf);
    }
    
    @Override
    public void shear(final SoundSource acm) {
        this.level.playSound(null, this, SoundEvents.MOOSHROOM_SHEAR, acm, 1.0f, 1.0f);
        if (!this.level.isClientSide()) {
            ((ServerLevel)this.level).<SimpleParticleType>sendParticles(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 1, 0.0, 0.0, 0.0, 0.0);
            this.remove();
            final Cow ayp3 = EntityType.COW.create(this.level);
            ayp3.moveTo(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot);
            ayp3.setHealth(this.getHealth());
            ayp3.yBodyRot = this.yBodyRot;
            if (this.hasCustomName()) {
                ayp3.setCustomName(this.getCustomName());
                ayp3.setCustomNameVisible(this.isCustomNameVisible());
            }
            if (this.isPersistenceRequired()) {
                ayp3.setPersistenceRequired();
            }
            ayp3.setInvulnerable(this.isInvulnerable());
            this.level.addFreshEntity(ayp3);
            for (int integer4 = 0; integer4 < 5; ++integer4) {
                this.level.addFreshEntity(new ItemEntity(this.level, this.getX(), this.getY(1.0), this.getZ(), new ItemStack(this.getMushroomType().blockState.getBlock())));
            }
        }
    }
    
    @Override
    public boolean readyForShearing() {
        return this.isAlive() && !this.isBaby();
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        le.putString("Type", this.getMushroomType().type);
        if (this.effect != null) {
            le.putByte("EffectId", (byte)MobEffect.getId(this.effect));
            le.putInt("EffectDuration", this.effectDuration);
        }
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        this.setMushroomType(byType(le.getString("Type")));
        if (le.contains("EffectId", 1)) {
            this.effect = MobEffect.byId(le.getByte("EffectId"));
        }
        if (le.contains("EffectDuration", 3)) {
            this.effectDuration = le.getInt("EffectDuration");
        }
    }
    
    private Optional<Pair<MobEffect, Integer>> getEffectFromItemStack(final ItemStack bki) {
        final Item bke3 = bki.getItem();
        if (bke3 instanceof BlockItem) {
            final Block bvr4 = ((BlockItem)bke3).getBlock();
            if (bvr4 instanceof FlowerBlock) {
                final FlowerBlock bxx5 = (FlowerBlock)bvr4;
                return Optional.<Pair<MobEffect, Integer>>of(Pair.of(bxx5.getSuspiciousStewEffect(), bxx5.getEffectDuration()));
            }
        }
        return Optional.<Pair<MobEffect, Integer>>empty();
    }
    
    private void setMushroomType(final MushroomType a) {
        this.entityData.<String>set(MushroomCow.DATA_TYPE, a.type);
    }
    
    public MushroomType getMushroomType() {
        return byType(this.entityData.<String>get(MushroomCow.DATA_TYPE));
    }
    
    @Override
    public MushroomCow getBreedOffspring(final AgableMob aok) {
        final MushroomCow ayu3 = EntityType.MOOSHROOM.create(this.level);
        ayu3.setMushroomType(this.getOffspringType((MushroomCow)aok));
        return ayu3;
    }
    
    private MushroomType getOffspringType(final MushroomCow ayu) {
        final MushroomType a3 = this.getMushroomType();
        final MushroomType a4 = ayu.getMushroomType();
        MushroomType a5;
        if (a3 == a4 && this.random.nextInt(1024) == 0) {
            a5 = ((a3 == MushroomType.BROWN) ? MushroomType.RED : MushroomType.BROWN);
        }
        else {
            a5 = (this.random.nextBoolean() ? a3 : a4);
        }
        return a5;
    }
    
    static {
        DATA_TYPE = SynchedEntityData.<String>defineId(MushroomCow.class, EntityDataSerializers.STRING);
    }
    
    public enum MushroomType {
        RED("red", Blocks.RED_MUSHROOM.defaultBlockState()), 
        BROWN("brown", Blocks.BROWN_MUSHROOM.defaultBlockState());
        
        private final String type;
        private final BlockState blockState;
        
        private MushroomType(final String string3, final BlockState cfj) {
            this.type = string3;
            this.blockState = cfj;
        }
        
        public BlockState getBlockState() {
            return this.blockState;
        }
        
        private static MushroomType byType(final String string) {
            for (final MushroomType a5 : values()) {
                if (a5.type.equals(string)) {
                    return a5;
                }
            }
            return MushroomType.RED;
        }
    }
}
