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

import java.util.List;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
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.client.modules.impl.combat.Aura;
import zenith.zov.utility.game.player.PlayerIntersectionUtil;
import zenith.zov.utility.mixin.accessors.DrawContextAccessor;
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 TargetHudComponent extends DraggableHudElement {
    private final Animation healthAnimation = new Animation(200L, Easing.LINEAR);
    private final Animation gappleAnimation = new Animation(200L, Easing.LINEAR);
    private final Animation toggleAnimation = new Animation(200L, Easing.QUAD_IN_OUT);
    private final Animation targetSwitchAnimation = new Animation(150L, Easing.SINE_IN_OUT);
    private LivingEntity target;
    private String lastTargetName = "";

    public TargetHudComponent(
        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) {
        this.width = 145.0F;
        this.height = 40.0F;
        Aura aura = Aura.INSTANCE;
        LivingEntity target = (LivingEntity)(mc.currentScreen instanceof ChatScreen ? mc.player : aura.getTarget());
        this.setTarget(target);
        if (this.toggleAnimation.getValue() != 0.0F && this.target != null) {
            String currentTargetName = this.target.getName().getString();
            this.renderTargetHud(ctx, this.target, this.toggleAnimation.getValue());
        }
    }

    private void renderTargetHud(CustomDrawContext ctx, LivingEntity target, float animation) {
        float posX = this.x;
        float posY = this.y;
        float width = 145.0F;
        float height = 40.0F;
        float headSize = 24.0F;
        float padding = 5.0F;
        float fontSize = 7.5F;
        Theme theme = Zenith.getInstance().getThemeManager().getCurrentTheme();
        ColorRGBA bgLeft = theme.getForegroundLight();
        ColorRGBA bgRight = theme.getForegroundColor();
        ctx.getMatrices().push();
        ctx.getMatrices().translate(this.x, this.y, 0.0F);
        ctx.getMatrices().scale(0.8F, 0.8F, 1.0F);
        ctx.getMatrices().translate(-this.x, -this.y, 0.0F);
        ctx.getMatrices().translate(posX + width / 2.0F, posY + height / 2.0F, 0.0F);
        ctx.getMatrices().scale(animation, animation, 1.0F);
        ctx.getMatrices().translate(-(posX + width / 2.0F), -(posY + height / 2.0F), 0.0F);
        DrawUtil.drawBlurHud(ctx.getMatrices(), this.x, this.y, width, height, 21.0F, BorderRadius.all(4.0F), ColorRGBA.WHITE);
        ctx.drawRoundedRect(posX, posY, headSize + padding * 2.0F, height, BorderRadius.left(4.0F, 4.0F), bgLeft);
        ctx.drawRoundedRect(posX + headSize + padding * 2.0F, posY, width - (headSize + padding * 2.0F), height, BorderRadius.right(4.0F, 4.0F), bgRight);
        float hp = (float)Math.round(PlayerIntersectionUtil.getHealth(target));
        float maxHp = Math.max(20.0F, hp);
        float gapple = Math.max(0.0F, hp - 20.0F);
        float healthPercent = hp / maxHp;
        float gapplePercent = gapple / maxHp;
        float barFullWidth = width - padding * 2.0F - headSize - padding * 2.0F;
        float animatedHealth = this.healthAnimation.update(barFullWidth * healthPercent);
        float animatedGapple = this.gappleAnimation.update(barFullWidth * gapplePercent);
        float headX = posX + padding;
        float headY = posY + (height - headSize) / 2.0F;
        if (target instanceof PlayerEntity player) {
            DrawUtil.drawPlayerHeadWithRoundedShader(
                ctx.getMatrices(),
                ((AbstractClientPlayerEntity)player).getSkinTextures().texture(),
                headX,
                headY,
                headSize,
                BorderRadius.all(0.5F),
                ColorRGBA.WHITE
            );
        } else {
            Font qFont = Fonts.MEDIUM.getFont(12.0F);
            ctx.drawText(qFont, "?", headX + (headSize - qFont.width("?")) / 2.0F, headY + headSize / 2.0F - qFont.height() / 2.0F, ColorRGBA.WHITE);
        }

        Font nameFont = Fonts.MEDIUM.getFont(fontSize);
        String name = target.getName().getString();
        float maxNameWidth = width - (headSize + padding * 2.0F + 20.0F) - 30.0F;
        String displayName = name;
        if (nameFont.width(name) > maxNameWidth) {
            while (nameFont.width(displayName + "...") > maxNameWidth && displayName.length() > 0) {
                displayName = displayName.substring(0, displayName.length() - 1);
            }

            displayName = displayName + "...";
        }

        ctx.drawText(nameFont, displayName, headX + headSize + padding * 2.0F, headY, theme.getWhite());
        String hpText = Math.round(hp) + "hp";
        Font hpFont = Fonts.MEDIUM.getFont(fontSize);
        ctx.drawText(hpFont, hpText, posX + width - padding - hpFont.width(hpText), headY, new ColorRGBA(181, 162, 255));
        if (target instanceof PlayerEntity player) {
            this.drawArmor(
                ctx, player, headX + headSize + padding * 2.0F, headY + fontSize, posX + width - (headX + headSize + padding * 2.0F), padding, fontSize
            );
        }

        float barX = headX + headSize + padding * 2.0F;
        float barY = headY + headSize - 2.5F;
        ColorRGBA barBg = bgRight.darker(0.2F);
        ctx.drawRoundedRect(barX, barY, barFullWidth, 2.5F, BorderRadius.all(0.5F), barBg);
        ctx.drawRoundedRect(barX, barY, animatedHealth, 2.5F, BorderRadius.all(0.5F), new ColorRGBA(181, 162, 255));
        ctx.drawRoundedBorder(posX, posY, width, height, 0.01F, BorderRadius.all(4.0F), theme.getForegroundStroke());
        DrawUtil.drawRoundedCorner(ctx.getMatrices(), posX, posY, width, height, 0.01F, 20.0F, theme.getColor(), BorderRadius.all(4.0F));
        ctx.getMatrices().pop();
        this.width = width * 0.8F;
        this.height = height * 0.8F;
    }

    private void drawArmor(CustomDrawContext ctx, PlayerEntity player, float posX, float posY, float headSize, float padding, float fontSize) {
        float width = 145.0F;
        float boxSizeItem = 10.0F;
        float paddingItem = 4.0F;
        float iconX = posX;
        float iconY = posY + 1.0F;
        Font xFont = Fonts.ICONS.getFont(5.0F);
        List<ItemStack> armor = player.getInventory().armor;
        ItemStack[] items = new ItemStack[]{player.getMainHandStack(), player.getOffHandStack(), armor.get(3), armor.get(2), armor.get(1), armor.get(0)};
        Font font = Fonts.MEDIUM.getFont(5.0F);

        for (ItemStack stack : items) {
            if (!stack.isEmpty()) {
                ctx.getMatrices().push();
                ctx.getMatrices().translate((double)iconX + ((double)boxSizeItem - 9.6) / 2.0, (double)iconY + ((double)boxSizeItem - 9.6) / 2.0, 0.0);
                ctx.getMatrices().scale(0.6F, 0.6F, 0.6F);
                ctx.drawItem(stack, 0, 0);
                ((DrawContextAccessor)ctx).callDrawItemBar(stack, 0, 0);
                ((DrawContextAccessor)ctx).callDrawCooldownProgress(stack, 0, 0);
                ctx.getMatrices().pop();
            } else {
                ctx.drawText(
                    xFont,
                    "M",
                    iconX + (boxSizeItem - xFont.width("X")) / 2.0F,
                    iconY + (boxSizeItem - xFont.height()) / 2.0F,
                    Zenith.getInstance().getThemeManager().getCurrentTheme().getGrayLight()
                );
            }

            iconX += boxSizeItem + paddingItem;
        }
    }

    public void setTarget(LivingEntity target) {
        if (target == null) {
            this.toggleAnimation.update(0.0F);
            if (this.toggleAnimation.getValue() == 0.0F) {
                this.target = null;
            }
        } else if (target != this.target) {
            this.toggleAnimation.update(0.0F);
            if (this.toggleAnimation.getValue() == 0.0F) {
                this.target = target;
            }
        } else {
            this.toggleAnimation.update(1.0F);
        }
    }
}
