package net.minecraft.world.level.block.entity;

import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.core.Vec3i;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.util.FastColor;
import net.minecraft.util.Mth;
import org.apache.commons.lang3.mutable.MutableInt;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.tags.Tag;
import net.minecraft.tags.EntityTypeTags;
import java.util.Iterator;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.core.Position;
import net.minecraft.world.phys.AABB;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.player.Player;
import net.minecraft.sounds.SoundSource;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.entity.LivingEntity;
import java.util.List;
import net.minecraft.core.Direction;

public class BellBlockEntity extends BlockEntity implements TickableBlockEntity {
    private long lastRingTimestamp;
    public int ticks;
    public boolean shaking;
    public Direction clickDirection;
    private List<LivingEntity> nearbyEntities;
    private boolean resonating;
    private int resonationTicks;
    
    public BellBlockEntity() {
        super(BlockEntityType.BELL);
    }
    
    @Override
    public boolean triggerEvent(final int integer1, final int integer2) {
        if (integer1 == 1) {
            this.updateEntities();
            this.resonationTicks = 0;
            this.clickDirection = Direction.from3DDataValue(integer2);
            this.ticks = 0;
            return this.shaking = true;
        }
        return super.triggerEvent(integer1, integer2);
    }
    
    @Override
    public void tick() {
        if (this.shaking) {
            ++this.ticks;
        }
        if (this.ticks >= 50) {
            this.shaking = false;
            this.ticks = 0;
        }
        if (this.ticks >= 5 && this.resonationTicks == 0 && this.areRaidersNearby()) {
            this.resonating = true;
            this.playResonateSound();
        }
        if (this.resonating) {
            if (this.resonationTicks < 40) {
                ++this.resonationTicks;
            }
            else {
                this.makeRaidersGlow(this.level);
                this.showBellParticles(this.level);
                this.resonating = false;
            }
        }
    }
    
    private void playResonateSound() {
        this.level.playSound(null, this.getBlockPos(), SoundEvents.BELL_RESONATE, SoundSource.BLOCKS, 1.0f, 1.0f);
    }
    
    public void onHit(final Direction fz) {
        final BlockPos fu3 = this.getBlockPos();
        this.clickDirection = fz;
        if (this.shaking) {
            this.ticks = 0;
        }
        else {
            this.shaking = true;
        }
        this.level.blockEvent(fu3, this.getBlockState().getBlock(), 1, fz.get3DDataValue());
    }
    
    private void updateEntities() {
        final BlockPos fu2 = this.getBlockPos();
        if (this.level.getGameTime() > this.lastRingTimestamp + 60L || this.nearbyEntities == null) {
            this.lastRingTimestamp = this.level.getGameTime();
            final AABB deg3 = new AABB(fu2).inflate(48.0);
            this.nearbyEntities = this.level.<LivingEntity>getEntitiesOfClass(LivingEntity.class, deg3);
        }
        if (!this.level.isClientSide) {
            for (final LivingEntity aoy4 : this.nearbyEntities) {
                if (aoy4.isAlive()) {
                    if (aoy4.removed) {
                        continue;
                    }
                    if (!fu2.closerThan(aoy4.position(), 32.0)) {
                        continue;
                    }
                    aoy4.getBrain().<Long>setMemory(MemoryModuleType.HEARD_BELL_TIME, this.level.getGameTime());
                }
            }
        }
    }
    
    private boolean areRaidersNearby() {
        final BlockPos fu2 = this.getBlockPos();
        for (final LivingEntity aoy4 : this.nearbyEntities) {
            if (aoy4.isAlive()) {
                if (aoy4.removed) {
                    continue;
                }
                if (fu2.closerThan(aoy4.position(), 32.0) && aoy4.getType().is(EntityTypeTags.RAIDERS)) {
                    return true;
                }
                continue;
            }
        }
        return false;
    }
    
    private void makeRaidersGlow(final Level bqb) {
        if (bqb.isClientSide) {
            return;
        }
        this.nearbyEntities.stream().filter(this::isRaiderWithinRange).forEach(this::glow);
    }
    
    private void showBellParticles(final Level bqb) {
        if (!bqb.isClientSide) {
            return;
        }
        final BlockPos fu3 = this.getBlockPos();
        final MutableInt mutableInt4 = new MutableInt(16700985);
        final int integer5 = (int)this.nearbyEntities.stream().filter(aoy -> fu3.closerThan(aoy.position(), 48.0)).count();
        final float float6;
        final Vec3i vec3i;
        final float float7;
        final double double8;
        final double double9;
        final int n;
        int integer6;
        int integer7;
        final MutableInt mutableInt5;
        int integer8;
        double double10;
        double double11;
        double double12;
        this.nearbyEntities.stream().filter(this::isRaiderWithinRange).forEach(aoy -> {
            float6 = 1.0f;
            float7 = Mth.sqrt((aoy.getX() - vec3i.getX()) * (aoy.getX() - vec3i.getX()) + (aoy.getZ() - vec3i.getZ()) * (aoy.getZ() - vec3i.getZ()));
            double8 = vec3i.getX() + 0.5f + 1.0f / float7 * (aoy.getX() - vec3i.getX());
            double9 = vec3i.getZ() + 0.5f + 1.0f / float7 * (aoy.getZ() - vec3i.getZ());
            for (integer6 = Mth.clamp((n - 21) / -2, 3, 15), integer7 = 0; integer7 < integer6; ++integer7) {
                integer8 = mutableInt5.addAndGet(5);
                double10 = FastColor.ARGB32.red(integer8) / 255.0;
                double11 = FastColor.ARGB32.green(integer8) / 255.0;
                double12 = FastColor.ARGB32.blue(integer8) / 255.0;
                bqb.addParticle(ParticleTypes.ENTITY_EFFECT, double8, vec3i.getY() + 0.5f, double9, double10, double11, double12);
            }
        });
    }
    
    private boolean isRaiderWithinRange(final LivingEntity aoy) {
        return aoy.isAlive() && !aoy.removed && this.getBlockPos().closerThan(aoy.position(), 48.0) && aoy.getType().is(EntityTypeTags.RAIDERS);
    }
    
    private void glow(final LivingEntity aoy) {
        aoy.addEffect(new MobEffectInstance(MobEffects.GLOWING, 60));
    }
}
