package vassistent.ui;

import vassistent.model.ProblemLevel;

import javax.swing.*;
import java.awt.*;

/**
 * Custom progress-style component that visualizes ratio and mapped problem level.
 */
public class ProblemLevelBar extends JPanel {

    private double ratio = 0.0;
    private ProblemLevel level = ProblemLevel.NONE;

    /**
     * Creates the level bar component with preferred sizing and transparent background.
     */
    public ProblemLevelBar() {
        setPreferredSize(new Dimension(420, 88));
        setMinimumSize(new Dimension(320, 72));
        setOpaque(false);
        setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
    }

    /**
     * Updates the displayed ratio and derived problem level.
     *
     * @param ratio ratio value, clamped to {@code [0, 1]}
     */
    public void setRatio(double ratio) {
        this.ratio = Math.max(0.0, Math.min(1.0, ratio));
        this.level = calculateLevel(this.ratio);
        repaint();
    }

    /**
     * Maps a ratio to a problem level threshold.
     *
     * @param ratio ratio value in {@code [0, 1]}
     * @return mapped problem level
     */
    private ProblemLevel calculateLevel(Double ratio) {
        if (ratio >= 0.9) {
            return ProblemLevel.DISASTER;
        } else if (ratio >= 0.8) {
            return ProblemLevel.HIGH;
        } else if (ratio >= 0.5) {
            return ProblemLevel.WARNING;
        } else {
            return ProblemLevel.NONE;
        }
    }

    /**
     * Paints the bar background, filled level area, and textual status.
     *
     * @param g graphics context provided by Swing
     */
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        int width = getWidth();
        int height = getHeight();

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

        int arc = Math.max(22, height / 2);

        GradientPaint trackGradient = new GradientPaint(
                0, 0, new Color(51, 60, 76),
                0, height, new Color(29, 36, 48)
        );
        g2.setPaint(trackGradient);
        g2.fillRoundRect(0, 0, width, height, arc, arc);

        int filledWidth = (int) (width * ratio);
        if (filledWidth > 0) {
            filledWidth = Math.max(filledWidth, arc / 2);
        }

        Color baseColor = getColorForLevel(level);
        GradientPaint fillGradient = new GradientPaint(
                0, 0, baseColor.darker(),
                Math.max(1, filledWidth), 0, baseColor
        );
        g2.setPaint(fillGradient);
        g2.fillRoundRect(0, 0, filledWidth, height, arc, arc);

        g2.setStroke(new BasicStroke(2f));
        g2.setColor(new Color(175, 190, 212));
        g2.drawRoundRect(1, 1, width - 2, height - 2, arc, arc);

        String text = "Problem " + level.name() + "  " + (int) (ratio * 100) + "%";
        g2.setFont(new Font("Segoe UI Semibold",
                Font.PLAIN,
                Math.max(19, (int) (height * 0.33))));
        g2.setColor(new Color(244, 248, 255));

        FontMetrics fm = g2.getFontMetrics();
        int textX = (width - fm.stringWidth(text)) / 2;
        int textY = (height - fm.getHeight()) / 2 + fm.getAscent();
        g2.drawString(text, textX, textY);
    }

    /**
     * Returns a base color for the given problem level.
     *
     * @param level problem level
     * @return display color for the level
     */
    private Color getColorForLevel(ProblemLevel level) {
        switch (level) {
            case DISASTER:
                return new Color(214, 70, 70);
            case HIGH:
                return new Color(234, 134, 45);
            case WARNING:
                return new Color(219, 180, 52);
            default:
                return new Color(53, 178, 107);
        }
    }
}
