using Jiaowu.Api.Domain.Common;
using Jiaowu.Api.Domain.Identity;

namespace Jiaowu.Api.Domain.Academic;

public sealed class Campus : CatalogEntity
{
    public string? Address { get; set; }
}

public sealed class College : CatalogEntity
{
    public Guid? CampusId { get; set; }
    public Campus? Campus { get; set; }
    public string? ShortName { get; set; }
}

public sealed class Major : CatalogEntity
{
    public Guid CollegeId { get; set; }
    public College? College { get; set; }
    public required string DegreeType { get; set; }
    public int SchoolingYears { get; set; } = 4;
}

public sealed class AdministrativeClass : CatalogEntity
{
    public Guid MajorId { get; set; }
    public Major? Major { get; set; }
    public int Grade { get; set; }
    public string? CounselorName { get; set; }
    public Guid? CounselorUserId { get; set; }
    public ApplicationUser? CounselorUser { get; set; }
    public ICollection<Student> Students { get; set; } = [];
}

public sealed class Building : CatalogEntity
{
    public Guid CampusId { get; set; }
    public Campus? Campus { get; set; }
}

public sealed class Classroom : CatalogEntity
{
    public Guid BuildingId { get; set; }
    public Building? Building { get; set; }
    public int Capacity { get; set; }
    public string RoomType { get; set; } = "普通教室";
    public TeachingVenueNature TeachingVenueNature { get; set; } =
        TeachingVenueNature.GeneralClassroom;
    public string? Equipment { get; set; }
}

[Flags]
public enum TeachingVenueNature
{
    GeneralClassroom = 1,
    Laboratory = 2,
    TrainingRoom = 4,
    ComputerLab = 8,
    LanguageLab = 16,
    SportsVenue = 32,
    ArtsVenue = 64
}

public static class TeachingVenueNatureRules
{
    public const TeachingVenueNature ExperimentTeaching =
        TeachingVenueNature.Laboratory |
        TeachingVenueNature.TrainingRoom |
        TeachingVenueNature.ComputerLab |
        TeachingVenueNature.LanguageLab;

    public static bool SupportsExperiment(TeachingVenueNature value) =>
        (value & ExperimentTeaching) != 0;
}

public sealed class AcademicTerm : CatalogEntity
{
    public required string AcademicYear { get; set; }
    public TermSeason Season { get; set; }
    public DateOnly StartDate { get; set; }
    public DateOnly EndDate { get; set; }
    public bool IsCurrent { get; set; }
    public bool IsArchived { get; set; }
    public DateTime? ArchivedAt { get; set; }
}

public enum TermSeason
{
    Autumn = 1,
    Spring = 2,
    Summer = 3
}
