using Jiaowu.Api.Domain.Academic;
using Jiaowu.Api.Infrastructure.Graduation;

namespace Jiaowu.Api.Tests;

public sealed class StudentCourseProgressRulesTests
{
    [Fact]
    public void Passed_attempt_takes_precedence_over_other_states()
    {
        var result = StudentCourseProgressRules.Evaluate(
            [
                new StudentCourseAttemptSnapshot(52, GradeExamStatus.Normal),
                new StudentCourseAttemptSnapshot(76, GradeExamStatus.Normal)
            ],
            true);

        Assert.Equal(StudentCourseProgressStatus.Completed, result.Status);
        Assert.True(result.HasPassedAttempt);
        Assert.True(result.HasFailedAttempt);
    }

    [Fact]
    public void Failed_course_becomes_retaking_when_currently_in_progress()
    {
        var result = StudentCourseProgressRules.Evaluate(
            [new StudentCourseAttemptSnapshot(48, GradeExamStatus.Normal)],
            true);

        Assert.Equal(StudentCourseProgressStatus.Retaking, result.Status);
        Assert.False(result.HasPassedAttempt);
        Assert.True(result.HasFailedAttempt);
    }

    [Theory]
    [InlineData(GradeExamStatus.Absent, StudentCourseProgressStatus.Failed)]
    [InlineData(GradeExamStatus.Deferred, StudentCourseProgressStatus.Pending)]
    public void Special_exam_states_are_presented_accurately(
        GradeExamStatus examStatus,
        StudentCourseProgressStatus expected)
    {
        var result = StudentCourseProgressRules.Evaluate(
            [new StudentCourseAttemptSnapshot(null, examStatus)],
            false);

        Assert.Equal(expected, result.Status);
    }

    [Fact]
    public void Current_course_without_result_is_in_progress()
    {
        var result = StudentCourseProgressRules.Evaluate([], true);

        Assert.Equal(StudentCourseProgressStatus.InProgress, result.Status);
        Assert.False(result.HasPassedAttempt);
        Assert.False(result.HasFailedAttempt);
    }
}
