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

import jakarta.validation.Valid;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;

import java.util.List;

public record OutlookExamSprintReportPayload(
        @NotNull @Valid ReportMetadata reportMetadata,
        @NotNull @Valid ReadinessOverview readinessOverview,
        @NotNull @Valid SyllabusMasteryChart syllabusMasteryChart,
        @NotNull @Valid PastPaperVocabularyChart pastPaperVocabularyChart,
        @NotNull @Valid HighFrequencyVocabularyChart highFrequencyVocabularyChart,
        @NotNull @Valid VocabularyFrequencyBandChart vocabularyFrequencyBandChart,
        @NotNull @Valid FrequencyPlan frequencyPlan,
        @NotNull @Valid ScoreImprovementCaseStudy scoreImprovementCaseStudy) {

    public record ReportMetadata(
            @NotBlank String reportVersionLabel,
            @NotBlank String learnerName,
            @NotBlank String targetExamName,
            @NotBlank String sprintPeriodLabel,
            @NotBlank String authorName) {
    }

    public record ReadinessOverview(
            @NotBlank String summary,
            @NotBlank String currentStage,
            @NotBlank String keyInsight,
            @Min(0) @Max(100) int readinessScore) {
    }

    public record SyllabusMasteryChart(
            @Min(0) int totalWordCount,
            @Min(0) int masteredWordCount,
            @Min(0) int unmasteredWordCount,
            @Min(0) @Max(100) int masteryPercent,
            @NotBlank String summaryLabel,
            @NotBlank String recommendation) {

        public boolean hasConsistentWordCounts() {
            return masteredWordCount + unmasteredWordCount == totalWordCount;
        }

        public boolean hasConsistentMasteryPercent() {
            return totalWordCount == 0 || masteryPercent == Math.round((masteredWordCount * 100.0f) / totalWordCount);
        }
    }

    public record PastPaperVocabularyChart(
            @Min(0) int totalWordCount,
            @Min(0) int unknownWordCountBeforeSprint,
            @Min(0) int unknownWordCountAfterSprint,
            @NotBlank String projectedScoreGainLabel,
            @NotBlank String recommendation) {

        public boolean hasValidUnknownWordCounts() {
            return unknownWordCountBeforeSprint >= unknownWordCountAfterSprint;
        }
    }

    public record HighFrequencyVocabularyChart(
            @Min(0) @Max(100) int basicCorePercent,
            @Min(0) @Max(100) int highScorePercent,
            @NotBlank String highlightLabel) {
    }

    public record VocabularyFrequencyBandChart(
            @NotEmpty List<@Valid VocabularyFrequencyBar> bars) {

        public boolean hasExpectedBarCount() {
            return bars != null && bars.size() == 3;
        }
    }

    public record VocabularyFrequencyBar(
            @NotBlank String bandLabel,
            double currentValue,
            @NotBlank String priorityLabel,
            @NotBlank String themeColor) {
    }

    public record FrequencyPlan(
            @NotEmpty List<@Valid FrequencyPlanCard> cards,
            @NotBlank String recommendationTitle,
            @NotBlank String recommendationSummary,
            @NotEmpty List<@Valid PhaseSuggestion> phaseSuggestions) {

        public boolean hasExpectedCadences() {
            return cards != null && !cards.isEmpty();
        }
    }

    public record FrequencyPlanCard(
            @Min(0) int cadencePerWeek,
            @NotBlank String scoreGainLabel,
            @Min(0) @Max(100) int winRatePercent,
            boolean recommended,
            String badgeLabel,
            String emphasisIcon) {
    }

    public record PhaseSuggestion(
            @NotBlank String title,
            @NotBlank String description) {
    }

    public record ScoreImprovementCaseStudy(
            @NotBlank String headline,
            @NotBlank String learnerName,
            @NotBlank String studyPeriodLabel,
            @Min(0) int memorizedWordCount,
            @Min(0) int examHitWordCount,
            double hitRatePercent,
            @NotBlank String baselineScoreLabel,
            @Min(0) int finalScore,
            @Min(0) int scoreGain) {
    }
}
