package zenith.zov.client.screens.autobuy.items;

import com.google.gson.JsonObject;
import java.util.List;
import lombok.Generated;
import net.minecraft.item.ItemStack;
import zenith.zov.base.autobuy.enchantes.minecraft.EnchantVanilla;
import zenith.zov.base.autobuy.item.ItemBuy;
import zenith.zov.client.modules.api.setting.impl.BooleanSetting;
import zenith.zov.client.modules.api.setting.impl.NumberSetting;
import zenith.zov.client.screens.menu.settings.api.MenuSetting;
import zenith.zov.client.screens.menu.settings.impl.MenuBooleanSetting;
import zenith.zov.client.screens.menu.settings.impl.MenuSliderSetting;

public class AutoInventoryElytra extends ExtendAutoInventoryItem {
    private EnchantVanilla enchantVanilla = new EnchantVanilla("Unbreaking", "minecraft:unbreaking", 0);
    private EnchantVanilla meding = new EnchantVanilla("Mending", "minecraft:mending", 1);
    private MenuSliderSetting maxDamage = new MenuSliderSetting(new NumberSetting("Max Damage Percent", 0.8F, 0.0F, 1.0F, 0.1F));
    private MenuSliderSetting unBrekingSetting = new MenuSliderSetting(
        new NumberSetting("Unbreaking Level", 0.0F, 0.0F, 8.0F, 1.0F, (oldValue, newValue) -> this.enchantVanilla.setMinLevel((int)newValue))
    );
    private MenuBooleanSetting meddingState = new MenuBooleanSetting(new BooleanSetting("Mending", false));

    public AutoInventoryElytra(ItemBuy itemBuy) {
        super(itemBuy);
    }

    public AutoInventoryElytra copy() {
        AutoInventoryElytra autoInventoryElytra = new AutoInventoryElytra(this.getItemBuy());
        autoInventoryElytra.enchantVanilla = new EnchantVanilla(
            this.enchantVanilla.getName(), this.enchantVanilla.getChecked(), this.enchantVanilla.getMinLevel()
        );
        autoInventoryElytra.meding = new EnchantVanilla(this.meding.getName(), this.meding.getChecked(), this.meding.getMinLevel());
        autoInventoryElytra.maxDamage.getSetting().setCurrent(this.maxDamage.getSetting().getCurrent());
        autoInventoryElytra.unBrekingSetting.getSetting().setCurrent(this.unBrekingSetting.getSetting().getCurrent());
        return autoInventoryElytra;
    }

    @Override
    public List<MenuSetting> getEnchants() {
        return List.of(this.maxDamage, this.unBrekingSetting, this.meddingState);
    }

    @Override
    public boolean isBuy(ItemStack stack) {
        return super.isBuy(stack) && !(this.getDurabilityPercent(stack) < this.maxDamage.getSetting().getCurrent())
            ? this.enchantVanilla.isEnchanted(stack) && (this.meddingState.getSetting().isEnabled() || this.meding.isEnchanted(stack))
            : false;
    }

    private float getDurabilityPercent(ItemStack stack) {
        int damage = stack.getDamage();
        int maxDamage = stack.getMaxDamage();
        return (float)(maxDamage - damage) / (float)maxDamage;
    }

    @Override
    public void load(JsonObject obj) {
        super.load(obj);
        if (obj.has("maxDamage")) {
            float v = obj.get("maxDamage").getAsFloat();
            this.maxDamage.getSetting().setCurrent(v);
        }

        if (obj.has("unbreakingLevel")) {
            float lvl = obj.get("unbreakingLevel").getAsFloat();
            this.unBrekingSetting.getSetting().setCurrent(lvl);
            this.enchantVanilla.setMinLevel((int)lvl);
        }

        if (obj.has("mendingEnabled")) {
            boolean enabled = obj.get("mendingEnabled").getAsBoolean();
            this.meddingState.getSetting().setEnabled(enabled);
        }

        if (obj.has("unbreaking")) {
            JsonObject unb = obj.getAsJsonObject("unbreaking");
            if (unb.has("minLevel")) {
                int min = unb.get("minLevel").getAsInt();
                this.enchantVanilla.setMinLevel(min);
                this.unBrekingSetting.getSetting().setCurrent((float)min);
            }
        }

        if (obj.has("mending")) {
            JsonObject mend = obj.getAsJsonObject("mending");
            if (mend.has("minLevel")) {
                this.meding.setMinLevel(mend.get("minLevel").getAsInt());
            }
        }
    }

    @Override
    public JsonObject save() {
        JsonObject obj = super.save();
        obj.addProperty("maxDamage", this.maxDamage.getSetting().getCurrent());
        obj.addProperty("unbreakingLevel", this.unBrekingSetting.getSetting().getCurrent());
        obj.addProperty("mendingEnabled", this.meddingState.getSetting().isEnabled());
        JsonObject unb = new JsonObject();
        unb.addProperty("name", this.enchantVanilla.getName());
        unb.addProperty("minLevel", this.enchantVanilla.getMinLevel());
        obj.add("unbreaking", unb);
        JsonObject mend = new JsonObject();
        mend.addProperty("name", this.meding.getName());
        mend.addProperty("minLevel", this.meding.getMinLevel());
        obj.add("mending", mend);
        return obj;
    }

    @Generated
    public EnchantVanilla getEnchantVanilla() {
        return this.enchantVanilla;
    }

    @Generated
    public EnchantVanilla getMeding() {
        return this.meding;
    }

    @Generated
    public MenuSliderSetting getMaxDamage() {
        return this.maxDamage;
    }

    @Generated
    public MenuSliderSetting getUnBrekingSetting() {
        return this.unBrekingSetting;
    }

    @Generated
    public MenuBooleanSetting getMeddingState() {
        return this.meddingState;
    }

    @Generated
    public void setEnchantVanilla(EnchantVanilla enchantVanilla) {
        this.enchantVanilla = enchantVanilla;
    }

    @Generated
    public void setMeding(EnchantVanilla meding) {
        this.meding = meding;
    }

    @Generated
    public void setMaxDamage(MenuSliderSetting maxDamage) {
        this.maxDamage = maxDamage;
    }

    @Generated
    public void setUnBrekingSetting(MenuSliderSetting unBrekingSetting) {
        this.unBrekingSetting = unBrekingSetting;
    }

    @Generated
    public void setMeddingState(MenuBooleanSetting meddingState) {
        this.meddingState = meddingState;
    }
}
