using Jiaowu.Api.Domain.Common;

namespace Jiaowu.Api.Domain.Academic;

public sealed class ExamPlan : EntityBase
{
    public Guid AcademicTermId { get; set; }
    public AcademicTerm? AcademicTerm { get; set; }
    public required string Name { get; set; }
    public ExamPlanStatus Status { get; set; } = ExamPlanStatus.Draft;
    public string? Notes { get; set; }
    public DateTime? PublishedAt { get; set; }
    public ICollection<ExamSession> Sessions { get; set; } = [];
    public ICollection<ExamRoomAssignment> Rooms { get; set; } = [];
}

public sealed class ExamArrangementJob : EntityBase
{
    public ExamArrangementKind Kind { get; set; }
    public Guid PlanId { get; set; }
    public Guid? ActivePlanId { get; set; }
    public Guid? RequestedByUserId { get; set; }
    public string? ProjectIdsJson { get; set; }
    public string? SessionIdsJson { get; set; }
    public bool AssignClassrooms { get; set; }
    public bool AssignInvigilators { get; set; }
    public ExamArrangementJobStatus Status { get; set; } =
        ExamArrangementJobStatus.Queued;
    public int TotalSessions { get; set; }
    public int ProcessedSessions { get; set; }
    public string? CurrentStep { get; set; }
    public string? ResultMessage { get; set; }
    public string? ErrorMessage { get; set; }
    public DateTime? StartedAt { get; set; }
    public DateTime? CompletedAt { get; set; }
}

public enum ExamArrangementKind
{
    FormalExam = 1,
    MakeupExam = 2
}

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

public sealed class ExamSession : EntityBase
{
    public Guid ExamPlanId { get; set; }
    public ExamPlan? ExamPlan { 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<ExamSessionInvigilator> Invigilators { get; set; } = [];
    public ICollection<ExamRoomSession> RoomLinks { get; set; } = [];
    public ICollection<ExamSeatAssignment> SeatAssignments { get; set; } = [];
}

public sealed class ExamSessionInvigilator
{
    public Guid ExamSessionId { get; set; }
    public ExamSession? ExamSession { get; set; }
    public Guid TeacherId { get; set; }
    public Teacher? Teacher { get; set; }
}

public sealed class ExamRoomAssignment : EntityBase
{
    public Guid ExamPlanId { get; set; }
    public ExamPlan? ExamPlan { get; set; }
    public Guid CourseId { get; set; }
    public Course? Course { 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; }
    public DateTime StartsAt { get; set; }
    public DateTime EndsAt { get; set; }
    public int RequiredInvigilatorCount { get; set; } = 2;
    public ICollection<ExamRoomSession> SessionLinks { get; set; } = [];
    public ICollection<ExamSeatAssignment> Seats { get; set; } = [];
    public ICollection<ExamRoomInvigilator> Invigilators { get; set; } = [];
}

public sealed class ExamRoomSession
{
    public Guid ExamRoomId { get; set; }
    public ExamRoomAssignment? ExamRoom { get; set; }
    public Guid ExamSessionId { get; set; }
    public ExamSession? ExamSession { get; set; }
}

public sealed class ExamSeatAssignment
{
    public Guid ExamRoomId { get; set; }
    public ExamRoomAssignment? ExamRoom { get; set; }
    public Guid ExamSessionId { get; set; }
    public ExamSession? ExamSession { get; set; }
    public Guid StudentId { get; set; }
    public Student? Student { get; set; }
    public int SeatNumber { get; set; }
}

public sealed class ExamRoomInvigilator
{
    public Guid ExamRoomId { get; set; }
    public ExamRoomAssignment? ExamRoom { get; set; }
    public Guid TeacherId { get; set; }
    public Teacher? Teacher { get; set; }
}

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

public sealed class ExamPublishJob : EntityBase
{
    public ExamPublishJobKind Kind { get; set; }
    public Guid PlanId { get; set; }
    public Guid? ActivePlanId { get; set; }
    public Guid? RequestedByUserId { get; set; }
    public string? ProjectIdsJson { get; set; }
    public ExamPublishJobStatus Status { get; set; } = ExamPublishJobStatus.Queued;
    public string? CurrentStep { get; set; }
    public string? ErrorMessage { get; set; }
    public DateTime? StartedAt { get; set; }
    public DateTime? CompletedAt { get; set; }
}

public enum ExamPublishJobKind
{
    FormalExam = 1,
    MakeupExam = 2,
    ExperimentProjects = 3
}

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