package net.minecraft.world.entity.projectile;

import java.util.AbstractList;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.world.level.ItemLike;
import net.minecraft.nbt.Tag;
import net.minecraft.nbt.ListTag;
import net.minecraft.core.Registry;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.world.entity.Entity;
import net.minecraft.nbt.CompoundTag;
import java.util.Iterator;
import java.util.Collection;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.entity.LivingEntity;
import com.google.common.collect.Sets;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.Level;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.effect.MobEffectInstance;
import java.util.Set;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.network.syncher.EntityDataAccessor;

public class Arrow extends AbstractArrow {
    private static final EntityDataAccessor<Integer> ID_EFFECT_COLOR;
    private Potion potion;
    private final Set<MobEffectInstance> effects;
    private boolean fixedColor;
    
    public Arrow(final EntityType<? extends Arrow> aoq, final Level bqb) {
        super(aoq, bqb);
        this.potion = Potions.EMPTY;
        this.effects = Sets.newHashSet();
    }
    
    public Arrow(final Level bqb, final double double2, final double double3, final double double4) {
        super(EntityType.ARROW, double2, double3, double4, bqb);
        this.potion = Potions.EMPTY;
        this.effects = Sets.newHashSet();
    }
    
    public Arrow(final Level bqb, final LivingEntity aoy) {
        super(EntityType.ARROW, aoy, bqb);
        this.potion = Potions.EMPTY;
        this.effects = Sets.newHashSet();
    }
    
    public void setEffectsFromItem(final ItemStack bki) {
        if (bki.getItem() == Items.TIPPED_ARROW) {
            this.potion = PotionUtils.getPotion(bki);
            final Collection<MobEffectInstance> collection3 = PotionUtils.getCustomEffects(bki);
            if (!collection3.isEmpty()) {
                for (final MobEffectInstance aog5 : collection3) {
                    this.effects.add(new MobEffectInstance(aog5));
                }
            }
            final int integer4 = getCustomColor(bki);
            if (integer4 == -1) {
                this.updateColor();
            }
            else {
                this.setFixedColor(integer4);
            }
        }
        else if (bki.getItem() == Items.ARROW) {
            this.potion = Potions.EMPTY;
            this.effects.clear();
            this.entityData.<Integer>set(Arrow.ID_EFFECT_COLOR, -1);
        }
    }
    
    public static int getCustomColor(final ItemStack bki) {
        final CompoundTag le2 = bki.getTag();
        if (le2 != null && le2.contains("CustomPotionColor", 99)) {
            return le2.getInt("CustomPotionColor");
        }
        return -1;
    }
    
    private void updateColor() {
        this.fixedColor = false;
        if (this.potion == Potions.EMPTY && this.effects.isEmpty()) {
            this.entityData.<Integer>set(Arrow.ID_EFFECT_COLOR, -1);
        }
        else {
            this.entityData.<Integer>set(Arrow.ID_EFFECT_COLOR, PotionUtils.getColor(PotionUtils.getAllEffects(this.potion, this.effects)));
        }
    }
    
    public void addEffect(final MobEffectInstance aog) {
        this.effects.add(aog);
        this.getEntityData().<Integer>set(Arrow.ID_EFFECT_COLOR, PotionUtils.getColor(PotionUtils.getAllEffects(this.potion, this.effects)));
    }
    
    @Override
    protected void defineSynchedData() {
        super.defineSynchedData();
        this.entityData.<Integer>define(Arrow.ID_EFFECT_COLOR, -1);
    }
    
    @Override
    public void tick() {
        super.tick();
        if (this.level.isClientSide) {
            if (this.inGround) {
                if (this.inGroundTime % 5 == 0) {
                    this.makeParticle(1);
                }
            }
            else {
                this.makeParticle(2);
            }
        }
        else if (this.inGround && this.inGroundTime != 0 && !this.effects.isEmpty() && this.inGroundTime >= 600) {
            this.level.broadcastEntityEvent(this, (byte)0);
            this.potion = Potions.EMPTY;
            this.effects.clear();
            this.entityData.<Integer>set(Arrow.ID_EFFECT_COLOR, -1);
        }
    }
    
    private void makeParticle(final int integer) {
        final int integer2 = this.getColor();
        if (integer2 == -1 || integer <= 0) {
            return;
        }
        final double double4 = (integer2 >> 16 & 0xFF) / 255.0;
        final double double5 = (integer2 >> 8 & 0xFF) / 255.0;
        final double double6 = (integer2 >> 0 & 0xFF) / 255.0;
        for (int integer3 = 0; integer3 < integer; ++integer3) {
            this.level.addParticle(ParticleTypes.ENTITY_EFFECT, this.getRandomX(0.5), this.getRandomY(), this.getRandomZ(0.5), double4, double5, double6);
        }
    }
    
    public int getColor() {
        return this.entityData.<Integer>get(Arrow.ID_EFFECT_COLOR);
    }
    
    private void setFixedColor(final int integer) {
        this.fixedColor = true;
        this.entityData.<Integer>set(Arrow.ID_EFFECT_COLOR, integer);
    }
    
    @Override
    public void addAdditionalSaveData(final CompoundTag le) {
        super.addAdditionalSaveData(le);
        if (this.potion != Potions.EMPTY && this.potion != null) {
            le.putString("Potion", Registry.POTION.getKey(this.potion).toString());
        }
        if (this.fixedColor) {
            le.putInt("Color", this.getColor());
        }
        if (!this.effects.isEmpty()) {
            final ListTag lk3 = new ListTag();
            for (final MobEffectInstance aog5 : this.effects) {
                ((AbstractList<CompoundTag>)lk3).add(aog5.save(new CompoundTag()));
            }
            le.put("CustomPotionEffects", lk3);
        }
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag le) {
        super.readAdditionalSaveData(le);
        if (le.contains("Potion", 8)) {
            this.potion = PotionUtils.getPotion(le);
        }
        for (final MobEffectInstance aog4 : PotionUtils.getCustomEffects(le)) {
            this.addEffect(aog4);
        }
        if (le.contains("Color", 99)) {
            this.setFixedColor(le.getInt("Color"));
        }
        else {
            this.updateColor();
        }
    }
    
    @Override
    protected void doPostHurtEffects(final LivingEntity aoy) {
        super.doPostHurtEffects(aoy);
        for (final MobEffectInstance aog4 : this.potion.getEffects()) {
            aoy.addEffect(new MobEffectInstance(aog4.getEffect(), Math.max(aog4.getDuration() / 8, 1), aog4.getAmplifier(), aog4.isAmbient(), aog4.isVisible()));
        }
        if (!this.effects.isEmpty()) {
            for (final MobEffectInstance aog4 : this.effects) {
                aoy.addEffect(aog4);
            }
        }
    }
    
    @Override
    protected ItemStack getPickupItem() {
        if (this.effects.isEmpty() && this.potion == Potions.EMPTY) {
            return new ItemStack(Items.ARROW);
        }
        final ItemStack bki2 = new ItemStack(Items.TIPPED_ARROW);
        PotionUtils.setPotion(bki2, this.potion);
        PotionUtils.setCustomEffects(bki2, this.effects);
        if (this.fixedColor) {
            bki2.getOrCreateTag().putInt("CustomPotionColor", this.getColor());
        }
        return bki2;
    }
    
    @Override
    public void handleEntityEvent(final byte byte1) {
        if (byte1 == 0) {
            final int integer3 = this.getColor();
            if (integer3 != -1) {
                final double double4 = (integer3 >> 16 & 0xFF) / 255.0;
                final double double5 = (integer3 >> 8 & 0xFF) / 255.0;
                final double double6 = (integer3 >> 0 & 0xFF) / 255.0;
                for (int integer4 = 0; integer4 < 20; ++integer4) {
                    this.level.addParticle(ParticleTypes.ENTITY_EFFECT, this.getRandomX(0.5), this.getRandomY(), this.getRandomZ(0.5), double4, double5, double6);
                }
            }
        }
        else {
            super.handleEntityEvent(byte1);
        }
    }
    
    static {
        ID_EFFECT_COLOR = SynchedEntityData.<Integer>defineId(Arrow.class, EntityDataSerializers.INT);
    }
}
