package net.minecraft.world.level.block;

import net.minecraft.world.level.block.state.AbstractStateHolder;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
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.item.ItemEntity;
import net.minecraft.nbt.Tag;
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.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.Entity;
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.properties.IntegerProperty;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import net.minecraft.core.Direction;

public class BeehiveBlock extends BaseEntityBlock {
    public 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((((AbstractStateHolder<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 byj) {
        return true;
    }
    
    @Override
    public int getAnalogOutputSignal(final BlockState byj, final Level bjw, final BlockPos fk) {
        return byj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
    }
    
    @Override
    public void playerDestroy(final Level bjw, final Player ayj, final BlockPos fk, final BlockState byj, @Nullable final BlockEntity bwl, final ItemStack ben) {
        super.playerDestroy(bjw, ayj, fk, byj, bwl, ben);
        if (!bjw.isClientSide && bwl instanceof BeehiveBlockEntity) {
            final BeehiveBlockEntity bwi8 = (BeehiveBlockEntity)bwl;
            if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, ben) == 0) {
                bwi8.emptyAllLivingFromHive(ayj, byj, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
                bjw.updateNeighbourForOutputSignal(fk, this);
                this.angerNearbyBees(bjw, fk);
            }
            CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)ayj, byj.getBlock(), ben, bwi8.getOccupantCount());
        }
    }
    
    private void angerNearbyBees(final Level bjw, final BlockPos fk) {
        final List<Bee> list4 = bjw.<Bee>getEntitiesOfClass(Bee.class, new AABB(fk).inflate(8.0, 6.0, 8.0));
        if (!list4.isEmpty()) {
            final List<Player> list5 = bjw.<Player>getEntitiesOfClass(Player.class, new AABB(fk).inflate(8.0, 6.0, 8.0));
            final int integer6 = list5.size();
            for (final Bee atd8 : list4) {
                if (atd8.getTarget() == null) {
                    atd8.makeAngry(list5.get(bjw.random.nextInt(integer6)));
                }
            }
        }
    }
    
    public static void dropHoneycomb(final Level bjw, final BlockPos fk) {
        Block.popResource(bjw, fk, new ItemStack(Items.HONEYCOMB, 3));
    }
    
    @Override
    public InteractionResult use(final BlockState byj, final Level bjw, final BlockPos fk, final Player ayj, final InteractionHand ajk, final BlockHitResult cvg) {
        final ItemStack ben8 = ayj.getItemInHand(ajk);
        final ItemStack ben9 = ben8.copy();
        final int integer10 = byj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
        boolean boolean11 = false;
        if (integer10 >= 5) {
            if (ben8.getItem() == Items.SHEARS) {
                bjw.playSound(ayj, ayj.getX(), ayj.getY(), ayj.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.NEUTRAL, 1.0f, 1.0f);
                dropHoneycomb(bjw, fk);
                ben8.<Player>hurtAndBreak(1, ayj, ayj -> ayj.broadcastBreakEvent(ajk));
                boolean11 = true;
            }
            else if (ben8.getItem() == Items.GLASS_BOTTLE) {
                ben8.shrink(1);
                bjw.playSound(ayj, ayj.getX(), ayj.getY(), ayj.getZ(), SoundEvents.BOTTLE_FILL, SoundSource.NEUTRAL, 1.0f, 1.0f);
                if (ben8.isEmpty()) {
                    ayj.setItemInHand(ajk, new ItemStack(Items.HONEY_BOTTLE));
                }
                else if (!ayj.inventory.add(new ItemStack(Items.HONEY_BOTTLE))) {
                    ayj.drop(new ItemStack(Items.HONEY_BOTTLE), false);
                }
                boolean11 = true;
            }
        }
        if (boolean11) {
            if (!CampfireBlock.isSmokeyPos(bjw, fk, 5)) {
                if (this.hiveContainsBees(bjw, fk)) {
                    this.angerNearbyBees(bjw, fk);
                }
                this.releaseBeesAndResetHoneyLevel(bjw, byj, fk, ayj, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            }
            else {
                this.resetHoneyLevel(bjw, byj, fk);
                if (ayj instanceof ServerPlayer) {
                    CriteriaTriggers.SAFELY_HARVEST_HONEY.trigger((ServerPlayer)ayj, fk, ben9);
                }
            }
            return InteractionResult.SUCCESS;
        }
        return super.use(byj, bjw, fk, ayj, ajk, cvg);
    }
    
    private boolean hiveContainsBees(final Level bjw, final BlockPos fk) {
        final BlockEntity bwl4 = bjw.getBlockEntity(fk);
        if (bwl4 instanceof BeehiveBlockEntity) {
            final BeehiveBlockEntity bwi5 = (BeehiveBlockEntity)bwl4;
            return !bwi5.isEmpty();
        }
        return false;
    }
    
    public void releaseBeesAndResetHoneyLevel(final Level bjw, final BlockState byj, final BlockPos fk, @Nullable final Player ayj, final BeehiveBlockEntity.BeeReleaseStatus b) {
        this.resetHoneyLevel(bjw, byj, fk);
        final BlockEntity bwl7 = bjw.getBlockEntity(fk);
        if (bwl7 instanceof BeehiveBlockEntity) {
            final BeehiveBlockEntity bwi8 = (BeehiveBlockEntity)bwl7;
            bwi8.emptyAllLivingFromHive(ayj, byj, b);
        }
    }
    
    public void resetHoneyLevel(final Level bjw, final BlockState byj, final BlockPos fk) {
        bjw.setBlock(fk, ((AbstractStateHolder<O, BlockState>)byj).<Comparable, Integer>setValue((Property<Comparable>)BeehiveBlock.HONEY_LEVEL, 0), 3);
    }
    
    @Override
    public void animateTick(final BlockState byj, final Level bjw, final BlockPos fk, final Random random) {
        if (byj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL) >= 5) {
            for (int integer6 = 0; integer6 < random.nextInt(1) + 1; ++integer6) {
                this.trySpawnDripParticles(bjw, fk, byj);
            }
        }
    }
    
    private void trySpawnDripParticles(final Level bjw, final BlockPos fk, final BlockState byj) {
        if (!byj.getFluidState().isEmpty() || bjw.random.nextFloat() < 0.3f) {
            return;
        }
        final VoxelShape cwf5 = byj.getCollisionShape(bjw, fk);
        final double double6 = cwf5.max(Direction.Axis.Y);
        if (double6 >= 1.0 && !byj.is(BlockTags.IMPERMEABLE)) {
            final double double7 = cwf5.min(Direction.Axis.Y);
            if (double7 > 0.0) {
                this.spawnParticle(bjw, fk, cwf5, fk.getY() + double7 - 0.05);
            }
            else {
                final BlockPos fk2 = fk.below();
                final BlockState byj2 = bjw.getBlockState(fk2);
                final VoxelShape cwf6 = byj2.getCollisionShape(bjw, fk2);
                final double double8 = cwf6.max(Direction.Axis.Y);
                if ((double8 < 1.0 || !byj2.isCollisionShapeFullBlock(bjw, fk2)) && byj2.getFluidState().isEmpty()) {
                    this.spawnParticle(bjw, fk, cwf5, fk.getY() - 0.05);
                }
            }
        }
    }
    
    private void spawnParticle(final Level bjw, final BlockPos fk, final VoxelShape cwf, final double double4) {
        this.spawnFluidParticle(bjw, fk.getX() + cwf.min(Direction.Axis.X), fk.getX() + cwf.max(Direction.Axis.X), fk.getZ() + cwf.min(Direction.Axis.Z), fk.getZ() + cwf.max(Direction.Axis.Z), double4);
    }
    
    private void spawnFluidParticle(final Level bjw, final double double2, final double double3, final double double4, final double double5, final double double6) {
        bjw.addParticle(ParticleTypes.DRIPPING_HONEY, Mth.lerp(bjw.random.nextDouble(), double2, double3), double6, Mth.lerp(bjw.random.nextDouble(), double4, double5), 0.0, 0.0, 0.0);
    }
    
    @Override
    public BlockState getStateForPlacement(final BlockPlaceContext bcq) {
        return ((AbstractStateHolder<O, BlockState>)this.defaultBlockState()).<Comparable, Direction>setValue((Property<Comparable>)BeehiveBlock.FACING, bcq.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 byj) {
        return RenderShape.MODEL;
    }
    
    @Nullable
    @Override
    public BlockEntity newBlockEntity(final BlockGetter bjg) {
        return new BeehiveBlockEntity();
    }
    
    @Override
    public void playerWillDestroy(final Level bjw, final BlockPos fk, final BlockState byj, final Player ayj) {
        if (!bjw.isClientSide && ayj.isCreative() && bjw.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) {
            final BlockEntity bwl6 = bjw.getBlockEntity(fk);
            if (bwl6 instanceof BeehiveBlockEntity) {
                final BeehiveBlockEntity bwi7 = (BeehiveBlockEntity)bwl6;
                final ItemStack ben8 = new ItemStack(this);
                final int integer9 = byj.<Integer>getValue((Property<Integer>)BeehiveBlock.HONEY_LEVEL);
                final boolean boolean10 = !bwi7.isEmpty();
                if (!boolean10 && integer9 == 0) {
                    return;
                }
                if (boolean10) {
                    final CompoundTag jt11 = new CompoundTag();
                    jt11.put("Bees", bwi7.writeBees());
                    ben8.addTagElement("BlockEntityTag", jt11);
                }
                final CompoundTag jt11 = new CompoundTag();
                jt11.putInt("honey_level", integer9);
                ben8.addTagElement("BlockStateTag", jt11);
                final ItemEntity awb12 = new ItemEntity(bjw, fk.getX(), fk.getY(), fk.getZ(), ben8);
                awb12.setDefaultPickUpDelay();
                bjw.addFreshEntity(awb12);
            }
        }
        super.playerWillDestroy(bjw, fk, byj, ayj);
    }
    
    @Override
    public List<ItemStack> getDrops(final BlockState byj, final LootContext.Builder a) {
        final Entity akq4 = a.<Entity>getOptionalParameter(LootContextParams.THIS_ENTITY);
        if (akq4 instanceof PrimedTnt || akq4 instanceof Creeper || akq4 instanceof WitherSkull || akq4 instanceof WitherBoss || akq4 instanceof MinecartTNT) {
            final BlockEntity bwl5 = a.<BlockEntity>getOptionalParameter(LootContextParams.BLOCK_ENTITY);
            if (bwl5 instanceof BeehiveBlockEntity) {
                final BeehiveBlockEntity bwi6 = (BeehiveBlockEntity)bwl5;
                bwi6.emptyAllLivingFromHive(null, byj, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            }
        }
        return super.getDrops(byj, a);
    }
    
    @Override
    public BlockState updateShape(final BlockState byj1, final Direction fp, final BlockState byj3, final LevelAccessor bjx, final BlockPos fk5, final BlockPos fk6) {
        if (bjx.getBlockState(fk6).getBlock() instanceof FireBlock) {
            final BlockEntity bwl8 = bjx.getBlockEntity(fk5);
            if (bwl8 instanceof BeehiveBlockEntity) {
                final BeehiveBlockEntity bwi9 = (BeehiveBlockEntity)bwl8;
                bwi9.emptyAllLivingFromHive(null, byj1, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY);
            }
        }
        return super.updateShape(byj1, fp, byj3, bjx, fk5, fk6);
    }
    
    static {
        SPAWN_DIRECTIONS = new Direction[] { Direction.WEST, Direction.EAST, Direction.SOUTH };
        FACING = HorizontalDirectionalBlock.FACING;
        HONEY_LEVEL = BlockStateProperties.LEVEL_HONEY;
    }
}
