package zenith.zov.client.hud.elements.component;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.util.Identifier;
import zenith.zov.Zenith;
import zenith.zov.base.animations.base.Animation;
import zenith.zov.base.animations.base.Easing;
import zenith.zov.base.font.Font;
import zenith.zov.base.font.Fonts;
import zenith.zov.base.theme.Theme;
import zenith.zov.client.hud.elements.draggable.DraggableHudElement;
import zenith.zov.utility.interfaces.IMinecraft;
import zenith.zov.utility.render.display.base.BorderRadius;
import zenith.zov.utility.render.display.base.CustomDrawContext;
import zenith.zov.utility.render.display.base.color.ColorRGBA;
import zenith.zov.utility.render.display.shader.DrawUtil;

public class PotionsComponent extends DraggableHudElement {
    private final Animation animationWidth = new Animation(200L, 100.0F, Easing.QUAD_IN_OUT);
    private final Animation animationScale = new Animation(200L, 0.0F, Easing.QUAD_IN_OUT);
    private final Map<String, PotionsComponent.PotionModule> modules = new LinkedHashMap<>();
    private final Animation animationVisible = new Animation(200L, 0.0F, Easing.QUAD_IN_OUT);
    Set<String> currentKeys = new HashSet<>();

    public PotionsComponent(
        String name, float initialX, float initialY, float windowWidth, float windowHeight, float offsetX, float offsetY, DraggableHudElement.Align align
    ) {
        super(name, initialX, initialY, windowWidth, windowHeight, offsetX, offsetY, align);
    }

    @Override
    public void render(CustomDrawContext ctx) {
        if (mc.player != null) {
            this.currentKeys.clear();

            for (StatusEffectInstance eff : new ArrayList<>(mc.player.getActiveStatusEffects().values())) {
                String key = ((StatusEffect)eff.getEffectType().value()).getTranslationKey() + eff.getAmplifier();
                this.currentKeys.add(key);
                if (!this.modules.containsKey(key)) {
                    this.modules.put(key, new PotionsComponent.PotionModule(eff));
                }
            }

            this.modules.values().removeIf(PotionsComponent.PotionModule::isDelete);
            boolean hidden = this.modules.isEmpty();
            this.animationScale.update(hidden ? 1.0F : 0.0F);
            Theme theme = Zenith.getInstance().getThemeManager().getCurrentTheme();
            Font iconFont = Fonts.ICONS.getFont(6.0F);
            Font font = Fonts.MEDIUM.getFont(6.0F);
            float x = this.x;
            float y = this.y;
            float height = 18.0F + (float)this.modules.values().stream().mapToDouble(PotionsComponent.PotionModule::getHeight).sum();
            float width = (float)this.modules.values().stream().mapToDouble(PotionsComponent.PotionModule::updateWidth).max().orElse(100.0);
            width = this.animationWidth.update(width);
            this.width = width;
            this.height = height;
            ctx.pushMatrix();
            BorderRadius radius = new BorderRadius(4.0F, 4.0F, 4.0F, 4.0F);
            this.animationVisible.update(mc.currentScreen instanceof ChatScreen || !this.modules.isEmpty());
            ctx.getMatrices().translate(x + width / 2.0F, y + height / 2.0F, 0.0F);
            ctx.getMatrices().scale(this.animationVisible.getValue(), this.animationVisible.getValue(), 1.0F);
            ctx.getMatrices().translate(-(x + width / 2.0F), -(y + height / 2.0F), 0.0F);
            DrawUtil.drawBlurHud(ctx.getMatrices(), x, y, width, height, 21.0F, BorderRadius.all(4.0F), ColorRGBA.WHITE);
            ctx.drawRoundedRect(x, y, width, height, radius, theme.getForegroundLight());
            ctx.drawText(iconFont, "O", x + 8.0F, y + (18.0F - iconFont.height()) / 2.0F, theme.getColor());
            ctx.drawText(iconFont, "M", x + width - 8.0F - iconFont.width("M"), y + (18.0F - iconFont.height()) / 2.0F, theme.getWhiteGray());
            ctx.drawText(font, "Potions", x + 8.0F + 8.0F + 2.0F, y + (18.0F - font.height()) / 2.0F, theme.getWhite());
            if (this.animationVisible.getValue() == 1.0F) {
                float offsetY = y + 18.0F;
                int index = 0;

                for (PotionsComponent.PotionModule module : this.modules.values()) {
                    module.render(ctx, x, offsetY, width, index);
                    offsetY += module.getHeight();
                    index++;
                }
            }

            ctx.drawRoundedBorder(x, y, width, height, 0.1F, BorderRadius.all(4.0F), theme.getForegroundStroke());
            DrawUtil.drawRoundedCorner(
                ctx.getMatrices(), x, y, width, height, 0.1F, Math.min(20.0F, Math.max(12.0F, height / 2.5F)), theme.getColor(), BorderRadius.all(4.0F)
            );
            ctx.popMatrix();
        }
    }

    private String getAmplifierText(int amplifier) {
        return String.valueOf(amplifier + 1);
    }

    private String formatDuration(int durationTicks) {
        int totalSeconds = durationTicks / 20;
        int minutes = totalSeconds / 60;
        int seconds = totalSeconds % 60;
        return String.format("%02d:%02d", minutes, seconds);
    }

    private Identifier getEffectIcon(StatusEffect effect) {
        String id = effect.getTranslationKey().replace("effect.minecraft.", "").replace("effect.", "");
        return Identifier.of("minecraft", "textures/mob_effect/" + id + ".png");
    }

    private class PotionModule {
        private final Animation animation = new Animation(150L, 0.01F, Easing.QUAD_IN_OUT);
        private final Animation animationColor = new Animation(200L, Easing.QUAD_IN_OUT);
        private StatusEffectInstance effect;

        public PotionModule(StatusEffectInstance effect) {
            this.effect = effect;
        }

        public float updateWidth() {
            Font font = Fonts.MEDIUM.getFont(6.0F);
            String name = I18n.translate(((StatusEffect)this.effect.getEffectType().value()).getTranslationKey(), new Object[0]);
            String amp = PotionsComponent.this.getAmplifierText(this.effect.getAmplifier());
            String duration = PotionsComponent.this.formatDuration(this.effect.getDuration());
            float width = 100.0F;
            float moduleTextWidth = 24.0F + font.width(name + " " + amp);
            float keyTextWidth = font.width(duration);
            float widthText = width - (keyTextWidth + 8.0F);
            if (widthText < 8.0F + moduleTextWidth + 8.0F) {
                float deltaWidth = moduleTextWidth + 8.0F + 8.0F - widthText;
                width += deltaWidth;
            }

            return width;
        }

        public float getHeight() {
            return 18.0F * this.animation.getValue();
        }

        public void render(CustomDrawContext ctx, float x, float y, float width, int i) {
            String key = this.effect.getTranslationKey() + this.effect.getAmplifier();
            this.effect = new ArrayList<StatusEffectInstance>(IMinecraft.mc.player.getActiveStatusEffects().values())
                .stream()
                .filter(e -> (e.getTranslationKey() + e.getAmplifier()).equals(key))
                .findAny()
                .orElse(this.effect);
            this.animation.update(PotionsComponent.this.currentKeys.contains(key) ? 1.0F : 0.0F);
            this.animationColor.update(i % 2 == 0 ? 1.0F : 0.0F);
            Theme theme = Zenith.getInstance().getThemeManager().getCurrentTheme();
            Font font = Fonts.MEDIUM.getFont(6.0F);
            ColorRGBA background = theme.getForegroundLight().mix(theme.getForegroundColor(), this.animationColor.getValue());
            ctx.pushMatrix();
            ctx.getMatrices().translate(x + width / 2.0F, y + 9.0F, 0.0F);
            ctx.getMatrices().scale(this.animation.getValue(), this.animation.getValue(), 1.0F);
            ctx.getMatrices().translate(-(x + width / 2.0F), -(y + 9.0F), 0.0F);
            ctx.drawRoundedRect(
                x, y, width, 18.0F, i == PotionsComponent.this.modules.size() - 1 ? BorderRadius.bottom(4.0F, 4.0F) : BorderRadius.ZERO, background
            );
            Identifier icon = PotionsComponent.this.getEffectIcon((StatusEffect)this.effect.getEffectType().value());
            ctx.pushMatrix();
            ctx.getMatrices().translate(x + 8.0F, y + 6.0F, 0.0F);
            ctx.drawSpriteStretched(RenderLayer::getGuiTextured, IMinecraft.mc.getStatusEffectSpriteManager().getSprite(this.effect.getEffectType()), 0, 0, 6, 6);
            ctx.popMatrix();
            String name = I18n.translate(((StatusEffect)this.effect.getEffectType().value()).getTranslationKey(), new Object[0]);
            String amp = PotionsComponent.this.getAmplifierText(this.effect.getAmplifier());
            ctx.drawText(Fonts.BOLD.getFont(8.0F), ".", x + 8.0F + 8.0F + 2.0F, y + 4.0F, theme.getWhiteGray());
            ctx.drawText(font, name, x + 8.0F + 8.0F + 8.0F, y + (18.0F - font.height()) / 2.0F, theme.getWhite());
            ctx.drawText(font, amp, x + 8.0F + 8.0F + 8.0F + font.width(name + " "), y + (18.0F - font.height()) / 2.0F, theme.getGrayLight());
            String duration = PotionsComponent.this.formatDuration(this.effect.getDuration());
            ctx.drawText(font, duration, x + width - 8.0F - font.width(duration), y + (18.0F - font.height()) / 2.0F, theme.getColor());
            ctx.popMatrix();
        }

        public boolean isDelete() {
            return this.animation.getValue() == 0.0F;
        }
    }
}
