package cn.yunzhixue.ability.center.examsprint.infrastructure.report.rendering.achievement;

import org.junit.jupiter.api.Test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.assertj.core.api.Assertions.assertThat;

class AchievementExamSprintReportSvgChartBuilderTest {

    private static final Pattern SELF_CLOSING_RECT_PATTERN = Pattern.compile("<rect\\b[^>]*/>");

    /**
     * 覆盖成果报告柱状图正值极小但非零时，应按坐标轴比例绘制且不使用兜底最小柱高。
     */
    @Test
    void comparisonBarChartKeepsTinyPositiveBarsProportionalToAxisScale() {
        AchievementExamSprintReportSvgChartBuilder builder = new AchievementExamSprintReportSvgChartBuilder();

        String svg = builder.comparisonBarChart(
                "vocabulary-growth-chart",
                "词汇量对比",
                "训练前",
                1,
                "1 词",
                "训练后",
                1000,
                "1000 词",
                "#448aff");

        String beforeBar = extractRect(svg, "chart-bar chart-bar-before");
        String afterBar = extractRect(svg, "chart-bar chart-bar-after");

        assertThat(beforeBar)
                .contains("height='0'")
                .contains("fill='#448aff'")
                .doesNotContain("fill='#9fb3c8'")
                .doesNotContain("height='18'");
        assertThat(afterBar)
                .contains("height='144'")
                .contains("fill='#448aff'");
    }

    /**
     * 覆盖成果报告柱状图渲染内联 SVG 时，应声明 Batik 可识别的 CJK 字体族。
     */
    @Test
    void comparisonBarChartDeclaresBatikCjkFontFamilyOnInlineSvg() {
        AchievementExamSprintReportSvgChartBuilder builder = new AchievementExamSprintReportSvgChartBuilder();

        String svg = builder.comparisonBarChart(
                "vocabulary-growth-chart",
                "词汇量对比",
                "训练前",
                2328,
                "2328 词",
                "训练后",
                2347,
                "2347 词",
                "#448aff");

        assertThat(svg).contains("<svg class='achievement-bar-chart vocabulary-growth-chart' font-family=\"'MiSans VF', MiSans, ReportFont, sans-serif\"");
    }

    /**
     * 覆盖成果报告柱状图渲染 y 轴刻度时，应输出横向辅助网格线便于对比训练前后数据。
     */
    @Test
    void comparisonBarChartRendersYAxisHorizontalGridLines() {
        AchievementExamSprintReportSvgChartBuilder builder = new AchievementExamSprintReportSvgChartBuilder();

        String svg = builder.comparisonBarChart(
                "vocabulary-growth-chart",
                "词汇量对比",
                "训练前",
                50,
                "50 词",
                "训练后",
                100,
                "100 词",
                "#448aff");

        assertThat(svg)
                .contains("<line class='chart-grid-line' x1='58' y1='36' x2='324' y2='36' stroke='#edf2f7' stroke-width='1'/>")
                .contains("<line class='chart-grid-line' x1='58' y1='108' x2='324' y2='108' stroke='#edf2f7' stroke-width='1'/>")
                .contains("<line class='chart-grid-line' x1='58' y1='180' x2='324' y2='180' stroke='#edf2f7' stroke-width='1'/>");
    }

    private String extractRect(String svgOrHtml, String rectClass) {
        Matcher rectMatcher = SELF_CLOSING_RECT_PATTERN.matcher(svgOrHtml);
        String singleQuotedClass = "class='" + rectClass + "'";
        String doubleQuotedClass = "class=\"" + rectClass + "\"";
        while (rectMatcher.find()) {
            String rect = rectMatcher.group();
            if (rect.contains(singleQuotedClass) || rect.contains(doubleQuotedClass)) {
                return rect;
            }
        }
        throw new AssertionError("rect should exist for class '" + rectClass + "' in SVG/HTML fragment:\n" + svgOrHtml);
    }
}
