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

import dev.redstones.mediaplayerinfo.IMediaSession;
import dev.redstones.mediaplayerinfo.MediaInfo;
import dev.redstones.mediaplayerinfo.MediaPlayerInfo;
import java.util.Arrays;
import java.util.Comparator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import net.minecraft.client.gui.screen.ChatScreen;
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.math.Timer;
import zenith.zov.utility.render.display.Render2DUtil;
import zenith.zov.utility.render.display.Texture;
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 MusicInfoComponent extends DraggableHudElement {
    private final ExecutorService executorService = Executors.newSingleThreadExecutor();
    private MediaInfo mediaInfo;
    private final Identifier artwork = Zenith.id("icons/avatarmusic.png");
    private final Timer lastMedia = new Timer();
    public IMediaSession session;
    private boolean mediaInfoAvailable = false;
    private final Animation exit = new Animation(200L, 0.0F, Easing.QUAD_IN_OUT);
    private final Animation fadeAnimation = new Animation(300L, Easing.CUBIC_OUT);
    private final Animation progressAnimation = new Animation(200L, Easing.CUBIC_OUT);

    public MusicInfoComponent(
        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);

        try {
            this.mediaInfo = new MediaInfo("Track Name", "Artist", new byte[0], 43L, 150L, false);
            this.mediaInfoAvailable = true;
        } catch (NoClassDefFoundError var10) {
            System.err.println("MediaInfo dependency not available. Music info component will be disabled.");
            this.mediaInfoAvailable = false;
        } catch (Exception var11) {
            System.err.println("Failed to initialize MediaInfo: " + var11.getMessage());
            this.mediaInfoAvailable = false;
        }
    }

    @Override
    public void tick() {
        if (this.mediaInfoAvailable) {
            if (mc.player.age % 5 == 0) {
                this.executorService
                    .execute(
                        () -> {
                            try {
                                IMediaSession currentSession = this.session = MediaPlayerInfo.Instance
                                    .getMediaSessions()
                                    .stream()
                                    .max(Comparator.comparing(s -> s.getMedia().getPlaying()))
                                    .orElse(null);
                                if (currentSession != null) {
                                    MediaInfo info = currentSession.getMedia();
                                    if (!info.getTitle().isEmpty() || !info.getArtist().isEmpty()) {
                                        if (this.mediaInfo.getTitle().equals("Track Name")
                                            || !Arrays.equals(this.mediaInfo.getArtworkPng(), info.getArtworkPng())) {
                                            Render2DUtil.registerTexture(new Texture(this.artwork), info.getArtworkPng());
                                        }

                                        this.mediaInfo = info;
                                        this.lastMedia.reset();
                                    }
                                }
                            } catch (Exception var3) {
                                System.err.println("Error updating music info: " + var3.getMessage());
                            }
                        }
                    );
            }
        }
    }

    @Override
    public void render(CustomDrawContext ctx) {
        if (this.mediaInfoAvailable) {
            try {
                this.exit.update(!this.lastMedia.finished(2000L) || mc.currentScreen instanceof ChatScreen);
                if (this.exit.getValue() == 0.0F) {
                    return;
                }

                Font titleFont = Fonts.MEDIUM.getFont(6.0F);
                Font artistFont = Fonts.MEDIUM.getFont(5.0F);
                Font timeFont = Fonts.MEDIUM.getFont(6.0F);
                float coverBoxSize = 32.0F;
                float infoBoxWidth = 75.0F;
                float padding = 6.0F;
                float borderRadius = 4.0F;
                Theme theme = Zenith.getInstance().getThemeManager().getCurrentTheme();
                ColorRGBA bgLeft = theme.getForegroundLight();
                ColorRGBA bgRight = theme.getForegroundColor();
                ColorRGBA titleColor = theme.getWhite();
                ColorRGBA artistColor = theme.getGrayLight();
                ColorRGBA timeColor = theme.getColor();
                ColorRGBA progressBg = theme.getForegroundStroke();
                ColorRGBA progressFill = theme.getColor();
                this.width = coverBoxSize + infoBoxWidth;
                this.height = coverBoxSize;
                ctx.pushMatrix();
                float scaleX = this.x + this.width / 2.0F;
                float scaleY = this.y + this.height / 2.0F;
                ctx.getMatrices().translate(scaleX, scaleY, 0.0F);
                ctx.getMatrices().scale(this.exit.getValue(), this.exit.getValue(), 1.0F);
                ctx.getMatrices().translate(-scaleX, -scaleY, 1.0F);
                DrawUtil.drawBlurHud(ctx.getMatrices(), this.x, this.y, this.width, this.height, 21.0F, BorderRadius.all(4.0F), ColorRGBA.WHITE);
                ctx.drawRoundedRect(this.x, this.y, coverBoxSize, this.height, BorderRadius.left(borderRadius, borderRadius), bgLeft);
                ctx.drawRoundedRect(this.x + coverBoxSize, this.y, infoBoxWidth, this.height, BorderRadius.right(borderRadius, borderRadius), bgRight);
                ctx.drawRoundedBorder(this.x, this.y, coverBoxSize + infoBoxWidth, this.height, 0.1F, BorderRadius.all(4.0F), theme.getForegroundStroke());
                DrawUtil.drawRoundedCorner(
                    ctx.getMatrices(), this.x, this.y, coverBoxSize + infoBoxWidth, this.height, 0.1F, 15.0F, theme.getColor(), BorderRadius.all(4.0F)
                );
                scaleX = 4.0F;
                scaleY = coverBoxSize - scaleX * 2.0F;
                ctx.getMatrices().push();
                ctx.getMatrices().translate(0.0F, 0.0F, 0.0F);
                if (this.artwork != null) {
                    DrawUtil.drawRoundedTexture(ctx.getMatrices(), this.artwork, this.x + scaleX, this.y + scaleX, scaleY, scaleY, BorderRadius.all(2.0F));
                }

                ctx.getMatrices().pop();
                float rightX = this.x + coverBoxSize;
                float rightContentX = rightX + padding;
                float rightContentWidth = infoBoxWidth - padding * 2.0F;
                float sliderY = this.y + this.height - 7.0F;
                float progress = this.mediaInfo.getDuration() > 0L ? (float)this.mediaInfo.getPosition() / (float)this.mediaInfo.getDuration() : 0.0F;
                this.progressAnimation.update(progress);
                float animatedProgress = this.progressAnimation.getValue();
                float alpha = this.fadeAnimation.getValue();
                ColorRGBA bgLeftAlpha = bgLeft.mulAlpha(alpha);
                ColorRGBA bgRightAlpha = bgRight.mulAlpha(alpha);
                ctx.drawRoundedRect(this.x, this.y, coverBoxSize, this.height, BorderRadius.left(borderRadius, borderRadius), bgLeftAlpha);
                ctx.drawRoundedRect(this.x + coverBoxSize, this.y, infoBoxWidth, this.height, BorderRadius.right(borderRadius, borderRadius), bgRightAlpha);
                ctx.drawRoundedRect(rightContentX, sliderY, rightContentWidth, 2.0F, BorderRadius.all(0.2F), progressBg);
                ctx.drawRoundedRect(rightContentX, sliderY, rightContentWidth * Math.min(1.0F, animatedProgress), 2.0F, BorderRadius.all(0.2F), progressFill);
                float titleY = this.y + 8.0F;
                float artistY = titleY + titleFont.height() + 2.0F;
                String timeString = this.formatTime(this.mediaInfo.getPosition());
                float timeWidth = timeFont.width(timeString);
                float maxTextWidth = rightContentWidth - timeWidth - 2.0F;
                String title = this.mediaInfo.getTitle();
                String artist = this.mediaInfo.getArtist();
                this.renderScrollingText(ctx, titleFont, title, rightContentX, titleY, titleColor, maxTextWidth);
                if (artist != null && !artist.isEmpty()) {
                    this.renderScrollingText(ctx, artistFont, artist, rightContentX, artistY + 1.5F, artistColor, maxTextWidth);
                }

                ctx.drawText(timeFont, timeString, rightContentX + 3.0F + rightContentWidth - timeWidth, titleY, timeColor);
                ctx.popMatrix();
            } catch (Exception var35) {
                var35.printStackTrace();
            }
        }
    }

    private void renderScrollingText(CustomDrawContext ctx, Font font, String text, float x, float y, ColorRGBA color, float maxWidth) {
        float textW = font.width(text);
        float scroll = 0.0F;
        if (textW > maxWidth) {
            float scrollMax = textW - maxWidth;
            if (scrollMax < 0.0F) {
                scrollMax = 0.0F;
            }

            float pauseDuration = 1000.0F;
            float scrollDuration = 4000.0F;
            float totalCycle = pauseDuration + scrollDuration + pauseDuration + scrollDuration;
            long now = System.currentTimeMillis();
            float timeInCycle = (float)(now % (long)totalCycle);
            if (timeInCycle < pauseDuration) {
                scroll = 0.0F;
            } else if (timeInCycle < pauseDuration + scrollDuration) {
                float t = (timeInCycle - pauseDuration) / scrollDuration;
                scroll = t * scrollMax;
            } else if (timeInCycle < pauseDuration + scrollDuration + pauseDuration) {
                scroll = scrollMax;
            } else {
                float t = (timeInCycle - pauseDuration - scrollDuration - pauseDuration) / scrollDuration;
                scroll = scrollMax * (1.0F - t);
            }
        }

        ctx.enableScissor(
            (int)Math.ceil((double)(x - 1.0F)),
            (int)Math.ceil((double)(y - 1.0F)),
            (int)Math.ceil((double)(x - 1.0F + maxWidth + 2.0F)),
            (int)Math.ceil((double)(y - 1.0F + font.height() + 5.0F))
        );
        ctx.drawText(font, text.toLowerCase(), x - scroll, y, color);
        ctx.disableScissor();
    }

    private String formatTime(long ms) {
        long minutes = ms / 60L;
        long seconds = ms % 60L;
        return String.format("%d:%02d", minutes, seconds);
    }
}
