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

import cn.yunzhixue.ability.center.examsprint.contracts.report.ExamSprintReportType;
import cn.yunzhixue.ability.center.examsprint.domain.report.ReportGenerationStatus;
import cn.yunzhixue.ability.center.examsprint.domain.report.ReportType;
import org.junit.jupiter.api.Test;

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

class ExamSprintReportContractMapperTest {

    @Test
    void mapsEveryDomainGenerationStatusToContractStatusWithTheSamePublicName() {
        for (ReportGenerationStatus domainStatus : ReportGenerationStatus.values()) {
            assertThat(ExamSprintReportContractMapper.toContractStatus(domainStatus).name())
                    .isEqualTo(domainStatus.name());
        }
    }

    @Test
    void rejectsNullGenerationStatus() {
        assertThatThrownBy(() -> ExamSprintReportContractMapper.toContractStatus(null))
                .isInstanceOf(NullPointerException.class)
                .hasMessageContaining("status");
    }

    @Test
    void mapsKnownDomainReportTypesToExplicitContractReportTypes() {
        assertThat(ExamSprintReportContractMapper.toContractReportType(ReportType.OUTLOOK))
                .isEqualTo(ExamSprintReportType.OUTLOOK);
        assertThat(ExamSprintReportContractMapper.toContractReportType(ReportType.ACHIEVEMENT))
                .isEqualTo(ExamSprintReportType.ACHIEVEMENT);
    }

    @Test
    void mapsKnownContractReportTypesToExplicitDomainReportTypes() {
        assertThat(ExamSprintReportContractMapper.toDomainReportType(ExamSprintReportType.OUTLOOK))
                .isEqualTo(ReportType.OUTLOOK);
        assertThat(ExamSprintReportContractMapper.toDomainReportType(ExamSprintReportType.ACHIEVEMENT))
                .isEqualTo(ReportType.ACHIEVEMENT);
    }

    @Test
    void mapsEveryDomainReportTypeToContractReportTypeWithTheSamePublicName() {
        for (ReportType domainReportType : ReportType.values()) {
            assertThat(ExamSprintReportContractMapper.toContractReportType(domainReportType).name())
                    .isEqualTo(domainReportType.name());
        }
    }

    @Test
    void mapsEveryContractReportTypeToDomainReportTypeWithTheSamePublicName() {
        for (ExamSprintReportType contractReportType : ExamSprintReportType.values()) {
            assertThat(ExamSprintReportContractMapper.toDomainReportType(contractReportType).name())
                    .isEqualTo(contractReportType.name());
        }
    }

    @Test
    void rejectsNullReportTypeInBothDirections() {
        assertThatThrownBy(() -> ExamSprintReportContractMapper.toContractReportType(null))
                .isInstanceOf(NullPointerException.class)
                .hasMessageContaining("reportType");
        assertThatThrownBy(() -> ExamSprintReportContractMapper.toDomainReportType(null))
                .isInstanceOf(NullPointerException.class)
                .hasMessageContaining("reportType");
    }
}
