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.item.BlockItem;
import net.minecraft.world.level.block.FlowerBlock;
import net.minecraft.nbt.CompoundTag;
import org.apache.commons.lang3.tuple.Pair;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.Entity;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
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.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.global.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;

public class MushroomCow extends Cow {
    private static final EntityDataAccessor<String> DATA_TYPE;
    private MobEffect effect;
    private int effectDuration;
    private UUID lastLightningBoltUUID;
    
    public MushroomCow(final EntityType<? extends MushroomCow> aku, final Level bjw) {
        super(aku, bjw);
    }
    
    @Override
    public float getWalkTargetValue(final BlockPos fk, final LevelReader bjz) {
        if (bjz.getBlockState(fk.below()).getBlock() == Blocks.MYCELIUM) {
            return 10.0f;
        }
        return bjz.getBrightness(fk) - 0.5f;
    }
    
    public static boolean checkMushroomSpawnRules(final EntityType<MushroomCow> aku, final LevelAccessor bjx, final MobSpawnType alc, final BlockPos fk, final Random random) {
        return bjx.getBlockState(fk.below()).getBlock() == Blocks.MYCELIUM && bjx.getRawBrightness(fk, 0) > 8;
    }
    
    @Override
    public void thunderHit(final LightningBolt avy) {
        final UUID uUID3 = avy.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 boolean mobInteract(final Player ayj, final InteractionHand ajk) {
        final ItemStack ben4 = ayj.getItemInHand(ajk);
        if (ben4.getItem() == Items.BOWL && !this.isBaby() && !ayj.abilities.instabuild) {
            ben4.shrink(1);
            boolean boolean6 = false;
            ItemStack ben5;
            if (this.effect != null) {
                boolean6 = true;
                ben5 = new ItemStack(Items.SUSPICIOUS_STEW);
                SuspiciousStewItem.saveMobEffect(ben5, this.effect, this.effectDuration);
                this.effect = null;
                this.effectDuration = 0;
            }
            else {
                ben5 = new ItemStack(Items.MUSHROOM_STEW);
            }
            if (ben4.isEmpty()) {
                ayj.setItemInHand(ajk, ben5);
            }
            else if (!ayj.inventory.add(ben5)) {
                ayj.drop(ben5, false);
            }
            SoundEvent aah7;
            if (boolean6) {
                aah7 = SoundEvents.MOOSHROOM_MILK_SUSPICIOUSLY;
            }
            else {
                aah7 = SoundEvents.MOOSHROOM_MILK;
            }
            this.playSound(aah7, 1.0f, 1.0f);
            return true;
        }
        if (ben4.getItem() == Items.SHEARS && !this.isBaby()) {
            this.level.addParticle(ParticleTypes.EXPLOSION, this.getX(), this.getY(0.5), this.getZ(), 0.0, 0.0, 0.0);
            if (!this.level.isClientSide) {
                this.remove();
                final Cow ath5 = EntityType.COW.create(this.level);
                ath5.moveTo(this.getX(), this.getY(), this.getZ(), this.yRot, this.xRot);
                ath5.setHealth(this.getHealth());
                ath5.yBodyRot = this.yBodyRot;
                if (this.hasCustomName()) {
                    ath5.setCustomName(this.getCustomName());
                    ath5.setCustomNameVisible(this.isCustomNameVisible());
                }
                if (this.isPersistenceRequired()) {
                    ath5.setPersistenceRequired();
                }
                ath5.setInvulnerable(this.isInvulnerable());
                this.level.addFreshEntity(ath5);
                for (int integer6 = 0; integer6 < 5; ++integer6) {
                    this.level.addFreshEntity(new ItemEntity(this.level, this.getX(), this.getY(1.0), this.getZ(), new ItemStack(this.getMushroomType().blockState.getBlock())));
                }
                ben4.<Player>hurtAndBreak(1, ayj, ayj -> ayj.broadcastBreakEvent(ajk));
                this.playSound(SoundEvents.MOOSHROOM_SHEAR, 1.0f, 1.0f);
            }
            return true;
        }
        if (this.getMushroomType() == MushroomType.BROWN && ben4.getItem().is(ItemTags.SMALL_FLOWERS)) {
            if (this.effect != null) {
                for (int integer7 = 0; integer7 < 2; ++integer7) {
                    this.level.addParticle(ParticleTypes.SMOKE, this.getX() + this.random.nextFloat() / 2.0f, this.getY(0.5), this.getZ() + this.random.nextFloat() / 2.0f, 0.0, this.random.nextFloat() / 5.0f, 0.0);
                }
            }
            else {
                final Pair<MobEffect, Integer> pair5 = this.getEffectFromItemStack(ben4);
                if (!ayj.abilities.instabuild) {
                    ben4.shrink(1);
                }
                for (int integer6 = 0; integer6 < 4; ++integer6) {
                    this.level.addParticle(ParticleTypes.EFFECT, this.getX() + this.random.nextFloat() / 2.0f, this.getY(0.5), this.getZ() + this.random.nextFloat() / 2.0f, 0.0, this.random.nextFloat() / 5.0f, 0.0);
                }
                this.effect = (MobEffect)pair5.getLeft();
                this.effectDuration = (int)pair5.getRight();
                this.playSound(SoundEvents.MOOSHROOM_EAT, 2.0f, 1.0f);
            }
        }
        return super.mobInteract(ayj, ajk);
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag jt) {
        super.addAdditionalSaveData(jt);
        jt.putString("Type", this.getMushroomType().type);
        if (this.effect != null) {
            jt.putByte("EffectId", (byte)MobEffect.getId(this.effect));
            jt.putInt("EffectDuration", this.effectDuration);
        }
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag jt) {
        super.readAdditionalSaveData(jt);
        this.setMushroomType(byType(jt.getString("Type")));
        if (jt.contains("EffectId", 1)) {
            this.effect = MobEffect.byId(jt.getByte("EffectId"));
        }
        if (jt.contains("EffectDuration", 3)) {
            this.effectDuration = jt.getInt("EffectDuration");
        }
    }
    
    private Pair<MobEffect, Integer> getEffectFromItemStack(final ItemStack ben) {
        final FlowerBlock brl3 = (FlowerBlock)((BlockItem)ben.getItem()).getBlock();
        return (Pair<MobEffect, Integer>)Pair.of(brl3.getSuspiciousStewEffect(), brl3.getEffectDuration());
    }
    
    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 ako) {
        final MushroomCow atm3 = EntityType.MOOSHROOM.create(this.level);
        atm3.setMushroomType(this.getOffspringType((MushroomCow)ako));
        return atm3;
    }
    
    private MushroomType getOffspringType(final MushroomCow atm) {
        final MushroomType a3 = this.getMushroomType();
        final MushroomType a4 = atm.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 byj) {
            this.type = string3;
            this.blockState = byj;
        }
        
        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;
        }
    }
}
