package net.minecraft.world.item;

import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.LevelReader;
import net.minecraft.tags.Tag;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.BaseCoralWallFanBlock;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.biome.Biomes;
import net.minecraft.world.level.block.Blocks;
import javax.annotation.Nullable;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.BonemealableBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.InteractionResult;

public class BoneMealItem extends Item {
    public BoneMealItem(final Properties a) {
        super(a);
    }
    
    @Override
    public InteractionResult useOn(final UseOnContext blv) {
        final Level bqb3 = blv.getLevel();
        final BlockPos fu4 = blv.getClickedPos();
        final BlockPos fu5 = fu4.relative(blv.getClickedFace());
        if (growCrop(blv.getItemInHand(), bqb3, fu4)) {
            if (!bqb3.isClientSide) {
                bqb3.levelEvent(2005, fu4, 0);
            }
            return InteractionResult.sidedSuccess(bqb3.isClientSide);
        }
        final BlockState cfj6 = bqb3.getBlockState(fu4);
        final boolean boolean7 = cfj6.isFaceSturdy(bqb3, fu4, blv.getClickedFace());
        if (boolean7 && growWaterPlant(blv.getItemInHand(), bqb3, fu5, blv.getClickedFace())) {
            if (!bqb3.isClientSide) {
                bqb3.levelEvent(2005, fu5, 0);
            }
            return InteractionResult.sidedSuccess(bqb3.isClientSide);
        }
        return InteractionResult.PASS;
    }
    
    public static boolean growCrop(final ItemStack bki, final Level bqb, final BlockPos fu) {
        final BlockState cfj4 = bqb.getBlockState(fu);
        if (cfj4.getBlock() instanceof BonemealableBlock) {
            final BonemealableBlock bvt5 = (BonemealableBlock)cfj4.getBlock();
            if (bvt5.isValidBonemealTarget(bqb, fu, cfj4, bqb.isClientSide)) {
                if (bqb instanceof ServerLevel) {
                    if (bvt5.isBonemealSuccess(bqb, bqb.random, fu, cfj4)) {
                        bvt5.performBonemeal((ServerLevel)bqb, bqb.random, fu, cfj4);
                    }
                    bki.shrink(1);
                }
                return true;
            }
        }
        return false;
    }
    
    public static boolean growWaterPlant(final ItemStack bki, final Level bqb, final BlockPos fu, @Nullable final Direction fz) {
        if (!bqb.getBlockState(fu).is(Blocks.WATER) || bqb.getFluidState(fu).getAmount() != 8) {
            return false;
        }
        if (!(bqb instanceof ServerLevel)) {
            return true;
        }
        int integer5 = 0;
    Label_0041:
        while (integer5 < 128) {
            BlockPos fu2 = fu;
            Biome bre7 = bqb.getBiome(fu2);
            BlockState cfj8 = Blocks.SEAGRASS.defaultBlockState();
            while (true) {
                for (int integer6 = 0; integer6 < integer5 / 16; ++integer6) {
                    fu2 = fu2.offset(BoneMealItem.random.nextInt(3) - 1, (BoneMealItem.random.nextInt(3) - 1) * BoneMealItem.random.nextInt(3) / 2, BoneMealItem.random.nextInt(3) - 1);
                    bre7 = bqb.getBiome(fu2);
                    if (bqb.getBlockState(fu2).isCollisionShapeFullBlock(bqb, fu2)) {
                        ++integer5;
                        continue Label_0041;
                    }
                }
                if (bre7 == Biomes.WARM_OCEAN || bre7 == Biomes.DEEP_WARM_OCEAN) {
                    if (integer5 == 0 && fz != null && fz.getAxis().isHorizontal()) {
                        cfj8 = ((StateHolder<O, BlockState>)BlockTags.WALL_CORALS.getRandomElement(bqb.random).defaultBlockState()).<Comparable, Direction>setValue((Property<Comparable>)BaseCoralWallFanBlock.FACING, fz);
                    }
                    else if (BoneMealItem.random.nextInt(4) == 0) {
                        cfj8 = BlockTags.UNDERWATER_BONEMEALS.getRandomElement(BoneMealItem.random).defaultBlockState();
                    }
                }
                if (cfj8.getBlock().is(BlockTags.WALL_CORALS)) {
                    for (int integer6 = 0; !cfj8.canSurvive(bqb, fu2) && integer6 < 4; cfj8 = ((StateHolder<O, BlockState>)cfj8).<Comparable, Direction>setValue((Property<Comparable>)BaseCoralWallFanBlock.FACING, Direction.Plane.HORIZONTAL.getRandomDirection(BoneMealItem.random)), ++integer6) {}
                }
                if (!cfj8.canSurvive(bqb, fu2)) {
                    continue;
                }
                final BlockState cfj9 = bqb.getBlockState(fu2);
                if (cfj9.is(Blocks.WATER) && bqb.getFluidState(fu2).getAmount() == 8) {
                    bqb.setBlock(fu2, cfj8, 3);
                    continue;
                }
                if (cfj9.is(Blocks.SEAGRASS) && BoneMealItem.random.nextInt(10) == 0) {
                    ((BonemealableBlock)Blocks.SEAGRASS).performBonemeal((ServerLevel)bqb, BoneMealItem.random, fu2, cfj9);
                }
                continue;
            }
        }
        bki.shrink(1);
        return true;
    }
    
    public static void addGrowthParticles(final LevelAccessor bqc, BlockPos fu, int integer) {
        if (integer == 0) {
            integer = 15;
        }
        final BlockState cfj4 = bqc.getBlockState(fu);
        if (cfj4.isAir()) {
            return;
        }
        double double5 = 0.5;
        double double6;
        if (cfj4.is(Blocks.WATER)) {
            integer *= 3;
            double6 = 1.0;
            double5 = 3.0;
        }
        else if (cfj4.isSolidRender(bqc, fu)) {
            fu = fu.above();
            integer *= 3;
            double5 = 3.0;
            double6 = 1.0;
        }
        else {
            double6 = cfj4.getShape(bqc, fu).max(Direction.Axis.Y);
        }
        bqc.addParticle(ParticleTypes.HAPPY_VILLAGER, fu.getX() + 0.5, fu.getY() + 0.5, fu.getZ() + 0.5, 0.0, 0.0, 0.0);
        for (int integer2 = 0; integer2 < integer; ++integer2) {
            final double double7 = BoneMealItem.random.nextGaussian() * 0.02;
            final double double8 = BoneMealItem.random.nextGaussian() * 0.02;
            final double double9 = BoneMealItem.random.nextGaussian() * 0.02;
            final double double10 = 0.5 - double5;
            final double double11 = fu.getX() + double10 + BoneMealItem.random.nextDouble() * double5 * 2.0;
            final double double12 = fu.getY() + BoneMealItem.random.nextDouble() * double6;
            final double double13 = fu.getZ() + double10 + BoneMealItem.random.nextDouble() * double5 * 2.0;
            if (!bqc.getBlockState(new BlockPos(double11, double12, double13).below()).isAir()) {
                bqc.addParticle(ParticleTypes.HAPPY_VILLAGER, double11, double12, double13, double7, double8, double9);
            }
        }
    }
}
