using Jiaowu.Api.Domain.Common;

namespace Jiaowu.Api.Domain.Academic;

public sealed class MakeupExamPlan : EntityBase
{
    public Guid AcademicTermId { get; set; }
    public AcademicTerm? AcademicTerm { get; set; }
    public required string Name { get; set; }
    public MakeupExamPlanStatus Status { get; set; } = MakeupExamPlanStatus.Draft;
    public string? Notes { get; set; }
    public DateTime? PublishedAt { get; set; }
    public ICollection<MakeupExamSession> Sessions { get; set; } = [];
}

public sealed class MakeupExamSession : EntityBase
{
    public Guid MakeupExamPlanId { get; set; }
    public MakeupExamPlan? MakeupExamPlan { get; set; }
    public Guid TeachingTaskId { get; set; }
    public TeachingTask? TeachingTask { get; set; }
    public Guid? ClassroomId { get; set; }
    public Classroom? Classroom { get; set; }
    public DateOnly ExamDate { get; set; }
    public int StartPeriod { get; set; }
    public int PeriodCount { get; set; } = 2;
    public DateTime StartsAt { get; set; }
    public DateTime EndsAt { get; set; }
    public Guid? RequiredBuildingId { get; set; }
    public Building? RequiredBuilding { get; set; }
    public string? RequiredBuildingIds { get; set; }
    public int RequiredInvigilatorCount { get; set; } = 2;
    public string? Notes { get; set; }
    public ICollection<MakeupExamSessionInvigilator> Invigilators { get; set; } = [];
    public ICollection<MakeupExamEnrollment> Enrollments { get; set; } = [];
}

public sealed class MakeupExamSessionInvigilator
{
    public Guid MakeupExamSessionId { get; set; }
    public MakeupExamSession? MakeupExamSession { get; set; }
    public Guid TeacherId { get; set; }
    public Teacher? Teacher { get; set; }
}

public sealed class MakeupExamEnrollment
{
    public Guid MakeupExamSessionId { get; set; }
    public MakeupExamSession? MakeupExamSession { get; set; }
    public Guid StudentId { get; set; }
    public Student? Student { get; set; }
    public MakeupReason Reason { get; set; }
    public Guid? SourceGradeRecordId { get; set; }
    public GradeRecord? SourceGradeRecord { get; set; }
    public Guid? SourceDeferredExamId { get; set; }
    public DeferredExam? SourceDeferredExam { get; set; }
    public decimal? MakeupScore { get; set; }
}

public enum MakeupExamPlanStatus
{
    Draft = 1,
    Published = 2,
    Archived = 3
}

public enum MakeupReason
{
    Failed = 1,
    Absent = 2,
    DeferredApproved = 3
}

public sealed class MakeupExamAutoJob : EntityBase
{
    public Guid MakeupExamPlanId { get; set; }
    public MakeupExamPlan? MakeupExamPlan { get; set; }
    public MakeupExamAutoJobStatus Status { get; set; } = MakeupExamAutoJobStatus.Queued;
    public int TotalCourses { get; set; }
    public int ProcessedCourses { get; set; }
    public int CreatedSessions { get; set; }
    public int EnrolledStudents { get; set; }
    public string? MessagesJson { get; set; }
    public string? ErrorMessage { get; set; }
    public DateTime? StartedAt { get; set; }
    public DateTime? CompletedAt { get; set; }
}

public enum MakeupExamAutoJobStatus
{
    Queued = 1,
    Running = 2,
    Succeeded = 3,
    Failed = 4
}
