package cn.yunzhixue.ability.center.examsprint.application.report;

import cn.yunzhixue.ability.center.examsprint.contracts.report.AchievementExamSprintReportPayload;
import cn.yunzhixue.ability.center.examsprint.domain.report.AchievementReportContent;
import com.fasterxml.jackson.databind.JsonNode;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Objects;

final class AchievementReportContentMapper {

    private AchievementReportContentMapper() {
    }

    static AchievementReportContent toDomainContent(AchievementExamSprintReportPayload payload) {
        Objects.requireNonNull(payload, "payload");
        String masteryHitRateText = masteryHitRateText(payload.paperMasteryHitRate());
        String learningEfficiencyText = learningEfficiencyText(payload.paperMasteryHitRate());
        return new AchievementReportContent(
                payload.studentName(),
                reportTitle(payload.stageName()),
                payload.testPaperTitle() + " · 临考突击 · 真实提分效果",
                "恭喜完成临考突击专项训练",
                "基于" + payload.testPaperTitle() + " · 真实学习效果分析",
                new AchievementReportContent.SummaryMetrics(
                        signed(payload.studentImproveWordCount()),
                        signed(payload.testPaperImprovedWordCount()),
                        masteryHitRateText,
                        learningEfficiencyText),
                new AchievementReportContent.Comparison(
                        payload.studentVocabularyBefore().doubleValue(),
                        payload.studentVocabulary().doubleValue(),
                        format(payload.studentVocabularyBefore()),
                        format(payload.studentVocabulary()),
                        signed(payload.studentImproveWordCount())),
                new AchievementReportContent.Comparison(
                        payload.testPaperBeforMastery().doubleValue(),
                        payload.testPaperLatestMastery().doubleValue(),
                        format(payload.testPaperBeforMastery()),
                        format(payload.testPaperLatestMastery()),
                        signed(payload.testPaperImprovedWordCount())),
                new AchievementReportContent.StageVocabularySummary(
                        payload.stageName(),
                        format(payload.stageVocabulary()),
                        format(payload.studentInitialVocabMastery()),
                        format(payload.studentCurrentVocabMastery()),
                        signed(payload.studentVocabMasteryImprovement())),
                new AchievementReportContent.TestPaperVocabularySummary(
                        payload.testPaperTitle(),
                        format(payload.testPaperWordCount()),
                        format(payload.testPaperBeforUnMastery()),
                        format(payload.testPaperAfterUnMastery()),
                        format(payload.testPaperBeforMasteryRate()),
                        format(payload.testPaperLatestMasteryRate()),
                        signed(payload.testPaperImproveRate())),
                new AchievementReportContent.ExamUnknownWordsHitStatus(
                        masteryHitRateText,
                        learningEfficiencyText,
                        format(payload.testPaperBeforUnMastery()),
                        format(payload.testPaperAfterUnMastery()),
                        format(payload.testPaperImprovedWordCount()),
                        hitWords(payload.testPaperImprovedWords())));
    }

    private static String reportTitle(String stageName) {
        String normalizedStageName = Objects.requireNonNull(stageName, "stageName").trim();
        if (normalizedStageName.contains("英语")) {
            return normalizedStageName + "临考突击学习成果报告";
        }
        return normalizedStageName + "英语临考突击学习成果报告";
    }

    private static String signed(BigDecimal value) {
        String formatted = format(value);
        return value.signum() > 0 ? "+" + formatted : formatted;
    }

    private static String format(BigDecimal value) {
        return value.stripTrailingZeros().toPlainString();
    }

    private static String masteryHitRateText(BigDecimal paperMasteryHitRate) {
        return formatTwoDecimals(paperMasteryHitRate) + "%";
    }

    private static String learningEfficiencyText(BigDecimal paperMasteryHitRate) {
        BigDecimal derivedEfficiency = paperMasteryHitRate
                .divide(BigDecimal.valueOf(100), 8, RoundingMode.HALF_UP)
                .divide(new BigDecimal("0.04"), 6, RoundingMode.HALF_UP);
        return formatTwoDecimals(derivedEfficiency);
    }

    private static String formatTwoDecimals(BigDecimal value) {
        return value.setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString();
    }

    private static List<String> hitWords(List<JsonNode> improvedWords) {
        return improvedWords.stream()
                .map(AchievementReportContentMapper::hitWord)
                .filter(word -> !word.isBlank())
                .toList();
    }

    private static String hitWord(JsonNode improvedWord) {
        if (improvedWord.isTextual()) {
            return improvedWord.asText().trim();
        }
        return improvedWord.path("WordSpell").asText("").trim();
    }
}
