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(100, 50));
        setOpaque(false);
        setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    }

    /**
     * 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);

        // --- Hintergrund ---
        GradientPaint bg = new GradientPaint(
                0, 0, new Color(235,235,235),
                0, height, new Color(210,210,210)
        );

        g2.setPaint(bg);
        g2.fillRoundRect(0, 0, width, height, 20, 20);

        // --- Gefüllter Bereich ---
        int filledWidth = (int) (width * ratio);

        Color baseColor = getColorForLevel(level);
        Color darkerColor = baseColor.darker();

        GradientPaint gradient = new GradientPaint(
                0, 0, darkerColor,
                filledWidth, 0, baseColor
        );

        g2.setPaint(gradient);
        g2.fillRoundRect(0, 0, filledWidth, height, 20, 20);

        g2.setStroke(new BasicStroke(2f));
        g2.setColor(baseColor.brighter());
        g2.drawRoundRect(1,1,width-2,height-2,20,20);

        // --- Text ---
        String text = level.name() + "  (" + (int)(ratio * 100) + "%)";

        g2.setColor(Color.BLACK);

        FontMetrics fm = g2.getFontMetrics();
        int textWidth = fm.stringWidth(text);

        g2.drawString(
                text,
                (width - textWidth) / 2,
                (height + fm.getAscent()) / 2 - 3
        );
    }

    /**
     * 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(200, 0, 0);
            case HIGH:
                return new Color(255, 140, 0);
            case WARNING:
                return new Color(255, 215, 0);
            default:
                return new Color(0, 170, 0);
        }
    }
}
