package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.Util;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.entity.vehicle.MinecartTNT;
import net.minecraft.world.entity.boss.wither.WitherBoss;
import net.minecraft.world.entity.projectile.WitherSkull;
import net.minecraft.world.entity.monster.Creeper;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.item.BlockPlaceContext;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.util.Mth;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.tags.Tag;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.level.BlockGetter;
import java.util.Random;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.item.Items;
import java.util.Iterator;
import java.util.List;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.entity.animal.Bee;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.world.item.enchantment.EnchantmentHelper;
import net.minecraft.world.item.enchantment.Enchantments;
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.core.Direction;

public class BeehiveBlock extends BaseEntityBlock {
    private static final Direction[] SPAWN_DIRECTIONS;
    public static final DirectionProperty FACING;
    public static final IntegerProperty HONEY_LEVEL;
    
    public BeehiveBlock(final Properties c) {
        super(c);
        this.registerDefaultState((((StateHolder<O, BlockState>)this.stateDefinition.any()).setValue((Property<Comparable>)BeehiveBlock.HONEY_LEVEL, 0)).<Comparable, Direction>setValue((Property<Comparable>)BeehiveBlock.FACING, Direction.NORTH));
    }
    
    @Override
    public boolean hasAnalogOutputSignal(final BlockState cfj) {
        return true;
    }
    
    @Override
    public int getAnalogOutputSignal(final BlockState cfj, final Level bqb, final BlockPos fu) {
        return cfj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
    }
    
    @Override
    public void playerDestroy(final Level bqb, final Player bec, final BlockPos fu, final BlockState cfj, @Nullable final BlockEntity cdl, final ItemStack bki) {
        super.playerDestroy(bqb, bec, fu, cfj, cdl, bki);
        if (!bqb.isClientSide && cdl instanceof BeehiveBlockEntity) {
            final BeehiveBlockEntity cdi8 = (BeehiveBlockEntity)cdl;
            if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, bki) == 0) {
                cdi8.emptyAllLivingFromHive(bec, cfj, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
                bqb.updateNeighbourForOutputSignal(fu, this);
                this.angerNearbyBees(bqb, fu);
            }
            CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)bec, cfj.getBlock(), bki, cdi8.getOccupantCount());
        }
    }
    
    private void angerNearbyBees(final Level bqb, final BlockPos fu) {
        final List<Bee> list4 = bqb.<Bee>getEntitiesOfClass(Bee.class, new AABB(fu).inflate(8.0, 6.0, 8.0));
        if (!list4.isEmpty()) {
            final List<Player> list5 = bqb.<Player>getEntitiesOfClass(Player.class, new AABB(fu).inflate(8.0, 6.0, 8.0));
            final int integer6 = list5.size();
            for (final Bee ayl8 : list4) {
                if (ayl8.getTarget() == null) {
                    ayl8.setTarget(list5.get(bqb.random.nextInt(integer6)));
                }
            }
        }
    }
    
    public static void dropHoneycomb(final Level bqb, final BlockPos fu) {
        Block.popResource(bqb, fu, new ItemStack(Items.HONEYCOMB, 3));
    }
    
    @Override
    public InteractionResult use(final BlockState cfj, final Level bqb, final BlockPos fu, final Player bec, final InteractionHand anf, final BlockHitResult deh) {
        final ItemStack bki8 = bec.getItemInHand(anf);
        final int integer9 = cfj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
        boolean boolean10 = false;
        if (integer9 >= 5) {
            if (bki8.getItem() == Items.SHEARS) {
                bqb.playSound(bec, bec.getX(), bec.getY(), bec.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.NEUTRAL, 1.0f, 1.0f);
                dropHoneycomb(bqb, fu);
                bki8.<Player>hurtAndBreak(1, bec, bec -> bec.broadcastBreakEvent(anf));
                boolean10 = true;
            }
            else if (bki8.getItem() == Items.GLASS_BOTTLE) {
                bki8.shrink(1);
                bqb.playSound(bec, bec.getX(), bec.getY(), bec.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0f, 1.0f);
                if (bki8.isEmpty()) {
                    bec.setItemInHand(anf, new ItemStack(Items.HONEY_BOTTLE));
                }
                else if (!bec.inventory.add(new ItemStack(Items.HONEY_BOTTLE))) {
                    bec.drop(new ItemStack(Items.HONEY_BOTTLE), false);
                }
                boolean10 = true;
            }
        }
        if (boolean10) {
            if (!CampfireBlock.isSmokeyPos(bqb, fu)) {
                if (this.hiveContainsBees(bqb, fu)) {
                    this.angerNearbyBees(bqb, fu);
                }
                this.releaseBeesAndResetHoneyLevel(bqb, cfj, fu, bec, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            }
            else {
                this.resetHoneyLevel(bqb, cfj, fu);
            }
            return InteractionResult.sidedSuccess(bqb.isClientSide);
        }
        return super.use(cfj, bqb, fu, bec, anf, deh);
    }
    
    private boolean hiveContainsBees(final Level bqb, final BlockPos fu) {
        final BlockEntity cdl4 = bqb.getBlockEntity(fu);
        if (cdl4 instanceof BeehiveBlockEntity) {
            final BeehiveBlockEntity cdi5 = (BeehiveBlockEntity)cdl4;
            return !cdi5.isEmpty();
        }
        return false;
    }
    
    public void releaseBeesAndResetHoneyLevel(final Level bqb, final BlockState cfj, final BlockPos fu, @Nullable final Player bec, final BeehiveBlockEntity.BeeReleaseStatus b) {
        this.resetHoneyLevel(bqb, cfj, fu);
        final BlockEntity cdl7 = bqb.getBlockEntity(fu);
        if (cdl7 instanceof BeehiveBlockEntity) {
            final BeehiveBlockEntity cdi8 = (BeehiveBlockEntity)cdl7;
            cdi8.emptyAllLivingFromHive(bec, cfj, b);
        }
    }
    
    public void resetHoneyLevel(final Level bqb, final BlockState cfj, final BlockPos fu) {
        bqb.setBlock(fu, ((StateHolder<O, BlockState>)cfj).<Comparable, Integer>setValue((Property<Comparable>)BeehiveBlock.HONEY_LEVEL, 0), 3);
    }
    
    @Override
    public void animateTick(final BlockState cfj, final Level bqb, final BlockPos fu, final Random random) {
        if (cfj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL) >= 5) {
            for (int integer6 = 0; integer6 < random.nextInt(1) + 1; ++integer6) {
                this.trySpawnDripParticles(bqb, fu, cfj);
            }
        }
    }
    
    private void trySpawnDripParticles(final Level bqb, final BlockPos fu, final BlockState cfj) {
        if (!cfj.getFluidState().isEmpty() || bqb.random.nextFloat() < 0.3f) {
            return;
        }
        final VoxelShape dfg5 = cfj.getCollisionShape(bqb, fu);
        final double double6 = dfg5.max(Direction.Axis.Y);
        if (double6 >= 1.0 && !cfj.is(BlockTags.IMPERMEABLE)) {
            final double double7 = dfg5.min(Direction.Axis.Y);
            if (double7 > 0.0) {
                this.spawnParticle(bqb, fu, dfg5, fu.getY() + double7 - 0.05);
            }
            else {
                final BlockPos fu2 = fu.below();
                final BlockState cfj2 = bqb.getBlockState(fu2);
                final VoxelShape dfg6 = cfj2.getCollisionShape(bqb, fu2);
                final double double8 = dfg6.max(Direction.Axis.Y);
                if ((double8 < 1.0 || !cfj2.isCollisionShapeFullBlock(bqb, fu2)) && cfj2.getFluidState().isEmpty()) {
                    this.spawnParticle(bqb, fu, dfg5, fu.getY() - 0.05);
                }
            }
        }
    }
    
    private void spawnParticle(final Level bqb, final BlockPos fu, final VoxelShape dfg, final double double4) {
        this.spawnFluidParticle(bqb, fu.getX() + dfg.min(Direction.Axis.X), fu.getX() + dfg.max(Direction.Axis.X), fu.getZ() + dfg.min(Direction.Axis.Z), fu.getZ() + dfg.max(Direction.Axis.Z), double4);
    }
    
    private void spawnFluidParticle(final Level bqb, final double double2, final double double3, final double double4, final double double5, final double double6) {
        bqb.addParticle(ParticleTypes.DRIPPING_HONEY, Mth.lerp(bqb.random.nextDouble(), double2, double3), double6, Mth.lerp(bqb.random.nextDouble(), double4, double5), 0.0, 0.0, 0.0);
    }
    
    @Override
    public BlockState getStateForPlacement(final BlockPlaceContext bin) {
        return ((StateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Direction>setValue((Property<Comparable>)BeehiveBlock.FACING, bin.getHorizontalDirection().getOpposite());
    }
    
    @Override
    protected void createBlockStateDefinition(final StateDefinition.Builder<Block, BlockState> a) {
        a.add(BeehiveBlock.HONEY_LEVEL, BeehiveBlock.FACING);
    }
    
    @Override
    public RenderShape getRenderShape(final BlockState cfj) {
        return RenderShape.MODEL;
    }
    
    @Nullable
    @Override
    public BlockEntity newBlockEntity(final BlockGetter bpg) {
        return new BeehiveBlockEntity();
    }
    
    @Override
    public void playerWillDestroy(final Level bqb, final BlockPos fu, final BlockState cfj, final Player bec) {
        if (!bqb.isClientSide && bec.isCreative() && bqb.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
            final BlockEntity cdl6 = bqb.getBlockEntity(fu);
            if (cdl6 instanceof BeehiveBlockEntity) {
                final BeehiveBlockEntity cdi7 = (BeehiveBlockEntity)cdl6;
                final ItemStack bki8 = new ItemStack(this);
                final int integer9 = cfj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
                final boolean boolean10 = !cdi7.isEmpty();
                if (!boolean10 && integer9 == 0) {
                    return;
                }
                if (boolean10) {
                    final CompoundTag le11 = new CompoundTag();
                    le11.put("Bees", cdi7.writeBees());
                    bki8.addTagElement("BlockEntityTag", le11);
                }
                final CompoundTag le11 = new CompoundTag();
                le11.putInt("honey_level", integer9);
                bki8.addTagElement("BlockStateTag", le11);
                final ItemEntity bbg12 = new ItemEntity(bqb, fu.getX(), fu.getY(), fu.getZ(), bki8);
                bbg12.setDefaultPickUpDelay();
                bqb.addFreshEntity(bbg12);
            }
        }
        super.playerWillDestroy(bqb, fu, cfj, bec);
    }
    
    @Override
    public List<ItemStack> getDrops(final BlockState cfj, final LootContext.Builder a) {
        final Entity aom4 = a.<Entity>getOptionalParameter(LootContextParams.THIS_ENTITY);
        if (aom4 instanceof PrimedTnt || aom4 instanceof Creeper || aom4 instanceof WitherSkull || aom4 instanceof WitherBoss || aom4 instanceof MinecartTNT) {
            final BlockEntity cdl5 = a.<BlockEntity>getOptionalParameter(LootContextParams.BLOCK_ENTITY);
            if (cdl5 instanceof BeehiveBlockEntity) {
                final BeehiveBlockEntity cdi6 = (BeehiveBlockEntity)cdl5;
                cdi6.emptyAllLivingFromHive(null, cfj, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            }
        }
        return super.getDrops(cfj, a);
    }
    
    @Override
    public BlockState updateShape(final BlockState cfj1, final Direction fz, final BlockState cfj3, final LevelAccessor bqc, final BlockPos fu5, final BlockPos fu6) {
        if (bqc.getBlockState(fu6).getBlock() instanceof FireBlock) {
            final BlockEntity cdl8 = bqc.getBlockEntity(fu5);
            if (cdl8 instanceof BeehiveBlockEntity) {
                final BeehiveBlockEntity cdi9 = (BeehiveBlockEntity)cdl8;
                cdi9.emptyAllLivingFromHive(null, cfj1, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            }
        }
        return super.updateShape(cfj1, fz, cfj3, bqc, fu5, fu6);
    }
    
    public static Direction getRandomOffset(final Random random) {
        return Util.<Direction>getRandom(BeehiveBlock.SPAWN_DIRECTIONS, random);
    }
    
    static {
        SPAWN_DIRECTIONS = new Direction[] { Direction.WEST, Direction.EAST, Direction.SOUTH };
        FACING = HorizontalDirectionalBlock.FACING;
        HONEY_LEVEL = BlockStateProperties.LEVEL_HONEY;
    }
}
