package net.minecraft.world.damagesource;

import javax.annotation.Nullable;
import java.util.Iterator;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.entity.Entity;
import net.minecraft.core.BlockPos;
import com.google.common.collect.Lists;
import net.minecraft.world.entity.LivingEntity;
import java.util.List;

public class CombatTracker {
    private final List<CombatEntry> entries;
    private final LivingEntity mob;
    private int lastDamageTime;
    private int combatStartTime;
    private int combatEndTime;
    private boolean inCombat;
    private boolean takingDamage;
    private String nextLocation;
    
    public CombatTracker(final LivingEntity akz) {
        this.entries = Lists.newArrayList();
        this.mob = akz;
    }
    
    public void prepareForDamage() {
        this.resetPreparedStatus();
        if (this.mob.onLadder()) {
            final Block bph2 = this.mob.level.getBlockState(new BlockPos(this.mob)).getBlock();
            if (bph2 == Blocks.LADDER) {
                this.nextLocation = "ladder";
            }
            else if (bph2 == Blocks.VINE) {
                this.nextLocation = "vines";
            }
        }
        else if (this.mob.isInWater()) {
            this.nextLocation = "water";
        }
    }
    
    public void recordDamage(final DamageSource ajz, final float float2, final float float3) {
        this.recheckStatus();
        this.prepareForDamage();
        final CombatEntry ajw5 = new CombatEntry(ajz, this.mob.tickCount, float2, float3, this.nextLocation, this.mob.fallDistance);
        this.entries.add(ajw5);
        this.lastDamageTime = this.mob.tickCount;
        this.takingDamage = true;
        if (ajw5.isCombatRelated() && !this.inCombat && this.mob.isAlive()) {
            this.inCombat = true;
            this.combatStartTime = this.mob.tickCount;
            this.combatEndTime = this.combatStartTime;
            this.mob.onEnterCombat();
        }
    }
    
    public Component getDeathMessage() {
        if (this.entries.isEmpty()) {
            return new TranslatableComponent("death.attack.generic", new Object[] { this.mob.getDisplayName() });
        }
        final CombatEntry ajw2 = this.getMostSignificantFall();
        final CombatEntry ajw3 = this.entries.get(this.entries.size() - 1);
        final Component lf5 = ajw3.getAttackerName();
        final Entity akq6 = ajw3.getSource().getEntity();
        Component lf7;
        if (ajw2 != null && ajw3.getSource() == DamageSource.FALL) {
            final Component lf6 = ajw2.getAttackerName();
            if (ajw2.getSource() == DamageSource.FALL || ajw2.getSource() == DamageSource.OUT_OF_WORLD) {
                lf7 = new TranslatableComponent("death.fell.accident." + this.getFallLocation(ajw2), new Object[] { this.mob.getDisplayName() });
            }
            else if (lf6 != null && (lf5 == null || !lf6.equals(lf5))) {
                final Entity akq7 = ajw2.getSource().getEntity();
                final ItemStack ben9 = (akq7 instanceof LivingEntity) ? ((LivingEntity)akq7).getMainHandItem() : ItemStack.EMPTY;
                if (!ben9.isEmpty() && ben9.hasCustomHoverName()) {
                    lf7 = new TranslatableComponent("death.fell.assist.item", new Object[] { this.mob.getDisplayName(), lf6, ben9.getDisplayName() });
                }
                else {
                    lf7 = new TranslatableComponent("death.fell.assist", new Object[] { this.mob.getDisplayName(), lf6 });
                }
            }
            else if (lf5 != null) {
                final ItemStack ben10 = (akq6 instanceof LivingEntity) ? ((LivingEntity)akq6).getMainHandItem() : ItemStack.EMPTY;
                if (!ben10.isEmpty() && ben10.hasCustomHoverName()) {
                    lf7 = new TranslatableComponent("death.fell.finish.item", new Object[] { this.mob.getDisplayName(), lf5, ben10.getDisplayName() });
                }
                else {
                    lf7 = new TranslatableComponent("death.fell.finish", new Object[] { this.mob.getDisplayName(), lf5 });
                }
            }
            else {
                lf7 = new TranslatableComponent("death.fell.killer", new Object[] { this.mob.getDisplayName() });
            }
        }
        else {
            lf7 = ajw3.getSource().getLocalizedDeathMessage(this.mob);
        }
        return lf7;
    }
    
    @Nullable
    public LivingEntity getKiller() {
        LivingEntity akz2 = null;
        Player ayj3 = null;
        float float4 = 0.0f;
        float float5 = 0.0f;
        for (final CombatEntry ajw7 : this.entries) {
            if (ajw7.getSource().getEntity() instanceof Player && (ayj3 == null || ajw7.getDamage() > float5)) {
                float5 = ajw7.getDamage();
                ayj3 = (Player)ajw7.getSource().getEntity();
            }
            if (ajw7.getSource().getEntity() instanceof LivingEntity && (akz2 == null || ajw7.getDamage() > float4)) {
                float4 = ajw7.getDamage();
                akz2 = (LivingEntity)ajw7.getSource().getEntity();
            }
        }
        if (ayj3 != null && float5 >= float4 / 3.0f) {
            return ayj3;
        }
        return akz2;
    }
    
    @Nullable
    private CombatEntry getMostSignificantFall() {
        CombatEntry ajw2 = null;
        CombatEntry ajw3 = null;
        float float4 = 0.0f;
        float float5 = 0.0f;
        for (int integer6 = 0; integer6 < this.entries.size(); ++integer6) {
            final CombatEntry ajw4 = this.entries.get(integer6);
            final CombatEntry ajw5 = (integer6 > 0) ? this.entries.get(integer6 - 1) : null;
            if ((ajw4.getSource() == DamageSource.FALL || ajw4.getSource() == DamageSource.OUT_OF_WORLD) && ajw4.getFallDistance() > 0.0f && (ajw2 == null || ajw4.getFallDistance() > float5)) {
                if (integer6 > 0) {
                    ajw2 = ajw5;
                }
                else {
                    ajw2 = ajw4;
                }
                float5 = ajw4.getFallDistance();
            }
            if (ajw4.getLocation() != null && (ajw3 == null || ajw4.getDamage() > float4)) {
                ajw3 = ajw4;
                float4 = ajw4.getDamage();
            }
        }
        if (float5 > 5.0f && ajw2 != null) {
            return ajw2;
        }
        if (float4 > 5.0f && ajw3 != null) {
            return ajw3;
        }
        return null;
    }
    
    private String getFallLocation(final CombatEntry ajw) {
        return (ajw.getLocation() == null) ? "generic" : ajw.getLocation();
    }
    
    public int getCombatDuration() {
        if (this.inCombat) {
            return this.mob.tickCount - this.combatStartTime;
        }
        return this.combatEndTime - this.combatStartTime;
    }
    
    private void resetPreparedStatus() {
        this.nextLocation = null;
    }
    
    public void recheckStatus() {
        final int integer2 = this.inCombat ? 300 : 100;
        if (this.takingDamage && (!this.mob.isAlive() || this.mob.tickCount - this.lastDamageTime > integer2)) {
            final boolean boolean3 = this.inCombat;
            this.takingDamage = false;
            this.inCombat = false;
            this.combatEndTime = this.mob.tickCount;
            if (boolean3) {
                this.mob.onLeaveCombat();
            }
            this.entries.clear();
        }
    }
    
    public LivingEntity getMob() {
        return this.mob;
    }
}
