using Jiaowu.Api.Domain.Common;

namespace Jiaowu.Api.Domain.Academic;

public sealed class ExperimentProject : EntityBase
{
    public Guid TeachingTaskId { get; set; }
    public TeachingTask? TeachingTask { get; set; }
    // 集中安排的项目复用已发布课表中的实验课，不再维护一份重复的场次。
    public Guid? ScheduleEntryId { get; set; }
    public ScheduleEntry? ScheduleEntry { get; set; }
    // 集中安排按课表的具体周次拆分为实验项目；自行安排为空。
    public int? ScheduleWeek { get; set; }
    public required string Code { get; set; }
    public required string Name { get; set; }
    public ExperimentArrangementMode ArrangementMode { get; set; }
    public string? Description { get; set; }
    public string? Requirements { get; set; }
    public DateOnly StartDate { get; set; }
    public DateOnly EndDate { get; set; }
    // 自主预约项目可单独控制学生可选场次的时间窗口（UTC 时刻）。
    public DateTime? SelectionStartsAt { get; set; }
    public DateTime? SelectionEndsAt { get; set; }
    public ExperimentProjectStatus Status { get; set; } =
        ExperimentProjectStatus.Draft;
    public DateTime? PublishedAt { get; set; }
    public DateTime? ClosedAt { get; set; }
    public ICollection<ExperimentSession> Sessions { get; set; } = [];
    public ICollection<ExperimentBooking> Bookings { get; set; } = [];
    public ExperimentGradeSheet? GradeSheet { get; set; }
}

public sealed class ExperimentSession : EntityBase
{
    public Guid ExperimentProjectId { get; set; }
    public ExperimentProject? ExperimentProject { get; set; }
    public Guid ClassroomId { get; set; }
    public Classroom? Classroom { get; set; }
    public DateOnly SessionDate { get; set; }
    public int StartPeriod { get; set; }
    public int PeriodCount { get; set; }
    public int Capacity { get; set; }
    public int ReservedCount { get; set; }
    public string? Notes { get; set; }
    public ExperimentSessionStatus Status { get; set; } =
        ExperimentSessionStatus.Scheduled;
    public DateTime? CancelledAt { get; set; }
    public ICollection<ExperimentBooking> Bookings { get; set; } = [];
    public ICollection<ExperimentSessionInstructor> Instructors { get; set; } = [];
}

public sealed class ExperimentSessionInstructor : EntityBase
{
    public Guid ExperimentSessionId { get; set; }
    public ExperimentSession? ExperimentSession { get; set; }
    public Guid TeacherId { get; set; }
    public Teacher? Teacher { get; set; }
}

public sealed class ExperimentBooking : EntityBase
{
    public Guid ExperimentProjectId { get; set; }
    public ExperimentProject? ExperimentProject { get; set; }
    public Guid ExperimentSessionId { get; set; }
    public ExperimentSession? ExperimentSession { get; set; }
    public Guid StudentId { get; set; }
    public Student? Student { get; set; }
    public ExperimentBookingStatus Status { get; set; } =
        ExperimentBookingStatus.Booked;
    public DateTime BookedAt { get; set; } = DateTime.UtcNow;
    public DateTime? CancelledAt { get; set; }
}

public enum ExperimentArrangementMode
{
    Centralized = 1,
    SelfScheduled = 2
}

public enum ExperimentProjectStatus
{
    Draft = 1,
    Published = 2,
    Closed = 3
}

public enum ExperimentSessionStatus
{
    Scheduled = 1,
    Cancelled = 2
}

public enum ExperimentBookingStatus
{
    Booked = 1,
    Cancelled = 2
}
