namespace Common.Builders;

using Domain.Entities;

/// <summary>
/// Builder pattern for creating Enrollment test objects.
/// </summary>
public class EnrollmentBuilder
{
    private int _id = 1;
    private int _studentId = 1;
    private int _subjectId = 1;
    private Student? _student;
    private Subject? _subject;
    private DateTime? _enrolledAt;

    public EnrollmentBuilder WithId(int id)
    {
        _id = id;
        return this;
    }

    public EnrollmentBuilder WithStudentId(int studentId)
    {
        _studentId = studentId;
        return this;
    }

    public EnrollmentBuilder WithSubjectId(int subjectId)
    {
        _subjectId = subjectId;
        return this;
    }

    public EnrollmentBuilder WithStudent(Student student)
    {
        _student = student;
        _studentId = student.Id;
        return this;
    }

    public EnrollmentBuilder WithSubject(Subject subject)
    {
        _subject = subject;
        _subjectId = subject.Id;
        return this;
    }

    public EnrollmentBuilder WithEnrolledAt(DateTime enrolledAt)
    {
        _enrolledAt = enrolledAt;
        return this;
    }

    public Enrollment Build()
    {
        var enrollment = new Enrollment(_studentId, _subjectId);
        SetProperty(enrollment, "Id", _id);

        if (_student is not null)
            SetProperty(enrollment, "Student", _student);

        if (_subject is not null)
            SetProperty(enrollment, "Subject", _subject);

        if (_enrolledAt.HasValue)
            SetProperty(enrollment, "EnrolledAt", _enrolledAt.Value);

        return enrollment;
    }

    private static void SetProperty<T>(T obj, string propertyName, object value) where T : class =>
        typeof(T).GetProperty(propertyName)!.SetValue(obj, value);
}
