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> aku, final Level bjw) {
        super(aku, bjw);
        this.potion = Potions.EMPTY;
        this.effects = Sets.newHashSet();
    }
    
    public Arrow(final Level bjw, final double double2, final double double3, final double double4) {
        super(EntityType.ARROW, double2, double3, double4, bjw);
        this.potion = Potions.EMPTY;
        this.effects = Sets.newHashSet();
    }
    
    public Arrow(final Level bjw, final LivingEntity akz) {
        super(EntityType.ARROW, akz, bjw);
        this.potion = Potions.EMPTY;
        this.effects = Sets.newHashSet();
    }
    
    public void setEffectsFromItem(final ItemStack ben) {
        if (ben.getItem() == Items.TIPPED_ARROW) {
            this.potion = PotionUtils.getPotion(ben);
            final Collection<MobEffectInstance> collection3 = PotionUtils.getCustomEffects(ben);
            if (!collection3.isEmpty()) {
                for (final MobEffectInstance akk5 : collection3) {
                    this.effects.add(new MobEffectInstance(akk5));
                }
            }
            final int integer4 = getCustomColor(ben);
            if (integer4 == -1) {
                this.updateColor();
            }
            else {
                this.setFixedColor(integer4);
            }
        }
        else if (ben.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 ben) {
        final CompoundTag jt2 = ben.getTag();
        if (jt2 != null && jt2.contains("CustomPotionColor", 99)) {
            return jt2.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 akk) {
        this.effects.add(akk);
        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 jt) {
        super.addAdditionalSaveData(jt);
        if (this.potion != Potions.EMPTY && this.potion != null) {
            jt.putString("Potion", Registry.POTION.getKey(this.potion).toString());
        }
        if (this.fixedColor) {
            jt.putInt("Color", this.getColor());
        }
        if (!this.effects.isEmpty()) {
            final ListTag jz3 = new ListTag();
            for (final MobEffectInstance akk5 : this.effects) {
                ((AbstractList<CompoundTag>)jz3).add(akk5.save(new CompoundTag()));
            }
            jt.put("CustomPotionEffects", jz3);
        }
    }
    
    @Override
    public void readAdditionalSaveData(final CompoundTag jt) {
        super.readAdditionalSaveData(jt);
        if (jt.contains("Potion", 8)) {
            this.potion = PotionUtils.getPotion(jt);
        }
        for (final MobEffectInstance akk4 : PotionUtils.getCustomEffects(jt)) {
            this.addEffect(akk4);
        }
        if (jt.contains("Color", 99)) {
            this.setFixedColor(jt.getInt("Color"));
        }
        else {
            this.updateColor();
        }
    }
    
    @Override
    protected void doPostHurtEffects(final LivingEntity akz) {
        super.doPostHurtEffects(akz);
        for (final MobEffectInstance akk4 : this.potion.getEffects()) {
            akz.addEffect(new MobEffectInstance(akk4.getEffect(), Math.max(akk4.getDuration() / 8, 1), akk4.getAmplifier(), akk4.isAmbient(), akk4.isVisible()));
        }
        if (!this.effects.isEmpty()) {
            for (final MobEffectInstance akk4 : this.effects) {
                akz.addEffect(akk4);
            }
        }
    }
    
    @Override
    protected ItemStack getPickupItem() {
        if (this.effects.isEmpty() && this.potion == Potions.EMPTY) {
            return new ItemStack(Items.ARROW);
        }
        final ItemStack ben2 = new ItemStack(Items.TIPPED_ARROW);
        PotionUtils.setPotion(ben2, this.potion);
        PotionUtils.setCustomEffects(ben2, this.effects);
        if (this.fixedColor) {
            ben2.getOrCreateTag().putInt("CustomPotionColor", this.getColor());
        }
        return ben2;
    }
    
    @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);
    }
}
