/*
 * Decompiled with CFR 0.152.
 * 
 * Could not load the following classes:
 *  it.unimi.dsi.fastutil.objects.Object2IntMap
 *  it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap
 *  meteordevelopment.orbit.EventHandler
 *  net.minecraft.class_10192
 *  net.minecraft.class_1304
 *  net.minecraft.class_1322$class_1323
 *  net.minecraft.class_1799
 *  net.minecraft.class_1802
 *  net.minecraft.class_1887
 *  net.minecraft.class_1893
 *  net.minecraft.class_3489
 *  net.minecraft.class_5134
 *  net.minecraft.class_5321
 *  net.minecraft.class_6880
 *  net.minecraft.class_9285
 *  net.minecraft.class_9285$class_9287
 *  net.minecraft.class_9334
 */
package meteordevelopment.meteorclient.systems.modules.combat;

import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Set;
import meteordevelopment.meteorclient.events.world.TickEvent;
import meteordevelopment.meteorclient.settings.BoolSetting;
import meteordevelopment.meteorclient.settings.EnchantmentListSetting;
import meteordevelopment.meteorclient.settings.EnumSetting;
import meteordevelopment.meteorclient.settings.IntSetting;
import meteordevelopment.meteorclient.settings.Setting;
import meteordevelopment.meteorclient.settings.SettingGroup;
import meteordevelopment.meteorclient.systems.modules.Categories;
import meteordevelopment.meteorclient.systems.modules.Module;
import meteordevelopment.meteorclient.systems.modules.Modules;
import meteordevelopment.meteorclient.systems.modules.player.ChestSwap;
import meteordevelopment.meteorclient.utils.Utils;
import meteordevelopment.meteorclient.utils.player.InvUtils;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.class_10192;
import net.minecraft.class_1304;
import net.minecraft.class_1322;
import net.minecraft.class_1799;
import net.minecraft.class_1802;
import net.minecraft.class_1887;
import net.minecraft.class_1893;
import net.minecraft.class_3489;
import net.minecraft.class_5134;
import net.minecraft.class_5321;
import net.minecraft.class_6880;
import net.minecraft.class_9285;
import net.minecraft.class_9334;

public class AutoArmor
extends Module {
    private final SettingGroup sgGeneral;
    private final Setting<Protection> preferredProtection;
    private final Setting<Integer> delay;
    private final Setting<Set<class_5321<class_1887>>> avoidedEnchantments;
    private final Setting<Boolean> blastLeggings;
    private final Setting<Boolean> antiBreak;
    private final Setting<Boolean> ignoreElytra;
    private final Object2IntMap<class_6880<class_1887>> enchantments;
    private final ArmorPiece[] armorPieces;
    private final ArmorPiece helmet;
    private final ArmorPiece chestplate;
    private final ArmorPiece leggings;
    private final ArmorPiece boots;
    private int timer;

    public AutoArmor() {
        super(Categories.PvP, "auto-armor", "Automatically equips armor.");
        this.sgGeneral = this.settings.getDefaultGroup();
        this.preferredProtection = this.sgGeneral.add(((EnumSetting.Builder)((EnumSetting.Builder)((EnumSetting.Builder)new EnumSetting.Builder().name("preferred-protection")).description("Which type of protection to prefer.")).defaultValue(Protection.Protection)).build());
        this.delay = this.sgGeneral.add(((IntSetting.Builder)((IntSetting.Builder)((IntSetting.Builder)new IntSetting.Builder().name("swap-delay")).description("The delay between equipping armor pieces.")).defaultValue(1)).min(0).sliderMax(5).build());
        this.avoidedEnchantments = this.sgGeneral.add(((EnchantmentListSetting.Builder)((EnchantmentListSetting.Builder)new EnchantmentListSetting.Builder().name("avoided-enchantments")).description("Enchantments that should be avoided.")).defaultValue(class_1893.field_9113, class_1893.field_9122).build());
        this.blastLeggings = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("blast-prot-leggings")).description("Uses blast protection for leggings regardless of preferred protection.")).defaultValue(true)).build());
        this.antiBreak = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("anti-break")).description("Takes off armor if it is about to break.")).defaultValue(false)).build());
        this.ignoreElytra = this.sgGeneral.add(((BoolSetting.Builder)((BoolSetting.Builder)((BoolSetting.Builder)new BoolSetting.Builder().name("ignore-elytra")).description("Will not replace your elytra if you have it equipped.")).defaultValue(true)).build());
        this.enchantments = new Object2IntOpenHashMap();
        this.armorPieces = new ArmorPiece[4];
        this.helmet = new ArmorPiece(class_1304.field_6169);
        this.chestplate = new ArmorPiece(class_1304.field_6174);
        this.leggings = new ArmorPiece(class_1304.field_6172);
        this.boots = new ArmorPiece(class_1304.field_6166);
        this.armorPieces[0] = this.helmet;
        this.armorPieces[1] = this.chestplate;
        this.armorPieces[2] = this.leggings;
        this.armorPieces[3] = this.boots;
    }

    @Override
    public void onActivate() {
        this.timer = 0;
    }

    @EventHandler
    private void onPreTick(TickEvent.Pre event) {
        if (this.timer > 0) {
            --this.timer;
            return;
        }
        for (ArmorPiece armorPiece : this.armorPieces) {
            armorPiece.reset();
        }
        block7: for (int i = 0; i < this.mc.field_1724.method_31548().method_67533().size(); ++i) {
            class_1799 itemStack = this.mc.field_1724.method_31548().method_5438(i);
            if (itemStack.method_7960() || !this.isArmor(itemStack) || this.antiBreak.get().booleanValue() && itemStack.method_7963() && itemStack.method_7936() - itemStack.method_7919() <= 10) continue;
            Utils.getEnchantments(itemStack, this.enchantments);
            if (this.hasAvoidedEnchantment()) continue;
            switch (this.getItemSlotId(itemStack)) {
                case 0: {
                    this.boots.add(itemStack, i);
                    continue block7;
                }
                case 1: {
                    this.leggings.add(itemStack, i);
                    continue block7;
                }
                case 2: {
                    this.chestplate.add(itemStack, i);
                    continue block7;
                }
                case 3: {
                    this.helmet.add(itemStack, i);
                }
            }
        }
        for (ArmorPiece armorPiece : this.armorPieces) {
            armorPiece.calculate();
        }
        Arrays.sort(this.armorPieces, Comparator.comparingInt(ArmorPiece::getSortScore));
        for (ArmorPiece armorPiece : this.armorPieces) {
            armorPiece.apply();
        }
    }

    private boolean hasAvoidedEnchantment() {
        for (class_6880 enchantment : this.enchantments.keySet()) {
            if (!enchantment.method_40224(this.avoidedEnchantments.get()::contains)) continue;
            return true;
        }
        return false;
    }

    private int getItemSlotId(class_1799 itemStack) {
        if (itemStack.method_57826(class_9334.field_54197)) {
            return 2;
        }
        return ((class_10192)itemStack.method_58694(class_9334.field_54196)).comp_3174().method_5927();
    }

    private int getScore(class_1799 itemStack) {
        if (itemStack.method_7960()) {
            return 0;
        }
        int score = 0;
        class_5321 protection = this.preferredProtection.get().enchantment;
        if (this.isArmor(itemStack) && this.blastLeggings.get().booleanValue() && this.getItemSlotId(itemStack) == 1) {
            protection = class_1893.field_9107;
        }
        score += 3 * Utils.getEnchantmentLevel(this.enchantments, protection);
        score += Utils.getEnchantmentLevel(this.enchantments, (class_5321<class_1887>)class_1893.field_9111);
        score += Utils.getEnchantmentLevel(this.enchantments, (class_5321<class_1887>)class_1893.field_9107);
        score += Utils.getEnchantmentLevel(this.enchantments, (class_5321<class_1887>)class_1893.field_9095);
        score += Utils.getEnchantmentLevel(this.enchantments, (class_5321<class_1887>)class_1893.field_9096);
        score += Utils.getEnchantmentLevel(this.enchantments, (class_5321<class_1887>)class_1893.field_9119);
        score += 2 * Utils.getEnchantmentLevel(this.enchantments, (class_5321<class_1887>)class_1893.field_9101);
        if (itemStack.method_57826(class_9334.field_49636)) {
            class_9285 component = (class_9285)itemStack.method_58694(class_9334.field_49636);
            for (class_9285.class_9287 modifier : component.comp_2393()) {
                if (modifier.comp_2395() != class_5134.field_23724 && modifier.comp_2395() != class_5134.field_23725) continue;
                double e = modifier.comp_2396().comp_2449();
                score += (switch (modifier.comp_2396().comp_2450()) {
                    default -> throw new MatchException(null, null);
                    case class_1322.class_1323.field_6328 -> (int)e;
                    case class_1322.class_1323.field_6330 -> (int)(e * this.mc.field_1724.method_45326(modifier.comp_2395()));
                    case class_1322.class_1323.field_6331 -> (int)(e * (double)score);
                });
            }
        }
        return score;
    }

    private boolean cannotSwap() {
        return this.timer > 0;
    }

    private void swap(int from, int armorSlotId) {
        InvUtils.move().from(from).toArmor(armorSlotId);
        this.timer = this.delay.get();
    }

    private void moveToEmpty(int armorSlotId) {
        for (int i = 0; i < this.mc.field_1724.method_31548().method_67533().size(); ++i) {
            if (!this.mc.field_1724.method_31548().method_5438(i).method_7960()) continue;
            InvUtils.move().fromArmor(armorSlotId).to(i);
            this.timer = this.delay.get();
            break;
        }
    }

    private boolean isArmor(class_1799 itemStack) {
        return itemStack.method_31573(class_3489.field_48294) || itemStack.method_31573(class_3489.field_48295) || itemStack.method_31573(class_3489.field_48296) || itemStack.method_31573(class_3489.field_48297);
    }

    public static enum Protection {
        Protection((class_5321<class_1887>)class_1893.field_9111),
        BlastProtection((class_5321<class_1887>)class_1893.field_9107),
        FireProtection((class_5321<class_1887>)class_1893.field_9095),
        ProjectileProtection((class_5321<class_1887>)class_1893.field_9096);

        private final class_5321<class_1887> enchantment;

        private Protection(class_5321<class_1887> enchantment) {
            this.enchantment = enchantment;
        }
    }

    private class ArmorPiece {
        private final class_1304 slot;
        private int bestSlot;
        private int bestScore;
        private int score;
        private int durability;

        public ArmorPiece(class_1304 slot) {
            this.slot = slot;
        }

        public void reset() {
            this.bestSlot = -1;
            this.bestScore = -1;
            this.score = -1;
            this.durability = Integer.MAX_VALUE;
        }

        public void add(class_1799 itemStack, int slot) {
            int score = AutoArmor.this.getScore(itemStack);
            if (score > this.bestScore) {
                this.bestScore = score;
                this.bestSlot = slot;
            }
        }

        public void calculate() {
            if (AutoArmor.this.cannotSwap()) {
                return;
            }
            class_1799 itemStack = ((AutoArmor)AutoArmor.this).mc.field_1724.method_6118(this.slot);
            if ((AutoArmor.this.ignoreElytra.get().booleanValue() || Modules.get().isActive(ChestSwap.class)) && itemStack.method_7909() == class_1802.field_8833) {
                this.score = Integer.MAX_VALUE;
                return;
            }
            Utils.getEnchantments(itemStack, AutoArmor.this.enchantments);
            if (AutoArmor.this.enchantments.containsKey((Object)class_1893.field_9113)) {
                this.score = Integer.MAX_VALUE;
                return;
            }
            this.score = AutoArmor.this.getScore(itemStack);
            this.score = this.decreaseScoreByAvoidedEnchantments(this.score);
            this.score = this.applyAntiBreakScore(this.score, itemStack);
            if (!itemStack.method_7960()) {
                this.durability = itemStack.method_7936() - itemStack.method_7919();
            }
        }

        public int getSortScore() {
            if (AutoArmor.this.antiBreak.get().booleanValue() && this.durability <= 10) {
                return -1;
            }
            return this.bestScore;
        }

        public void apply() {
            if (AutoArmor.this.cannotSwap() || this.score == Integer.MAX_VALUE) {
                return;
            }
            if (this.bestScore > this.score) {
                AutoArmor.this.swap(this.bestSlot, this.slot.method_5927());
            } else if (AutoArmor.this.antiBreak.get().booleanValue() && this.durability <= 10) {
                AutoArmor.this.moveToEmpty(this.slot.method_5927());
            }
        }

        private int decreaseScoreByAvoidedEnchantments(int score) {
            for (class_5321<class_1887> enchantment : AutoArmor.this.avoidedEnchantments.get()) {
                score -= 2 * AutoArmor.this.enchantments.getInt(enchantment);
            }
            return score;
        }

        private int applyAntiBreakScore(int score, class_1799 itemStack) {
            if (AutoArmor.this.antiBreak.get().booleanValue() && itemStack.method_7963() && itemStack.method_7936() - itemStack.method_7919() <= 10) {
                return -1;
            }
            return score;
        }
    }
}

