using Core.Entities;

namespace Tests.Builders;

/// <summary>
/// Fluent builder for creating AssignmentRequirement test entities.
/// </summary>
public class AssignmentRequirementBuilder
{
    private EventDefinition? _eventDefinition = null;
    private Student? _student = null;
    private Requirement _requirement = Requirement.Include;

    public AssignmentRequirementBuilder ForEvent(EventDefinition eventDef)
    {
        _eventDefinition = eventDef;
        return this;
    }

    public AssignmentRequirementBuilder ForStudent(Student student)
    {
        _student = student;
        return this;
    }

    public AssignmentRequirementBuilder AsInclude()
    {
        _requirement = Requirement.Include;
        return this;
    }

    public AssignmentRequirementBuilder AsExclude()
    {
        _requirement = Requirement.Exclude;
        return this;
    }

    public AssignmentRequirementBuilder WithRequirement(Requirement requirement)
    {
        _requirement = requirement;
        return this;
    }

    public AssignmentRequirement Build()
    {
        if (_eventDefinition == null)
            throw new InvalidOperationException("AssignmentRequirement must have an event. Call ForEvent() before Build().");

        if (_student == null)
            throw new InvalidOperationException("AssignmentRequirement must have a student. Call ForStudent() before Build().");

        return new AssignmentRequirement(_eventDefinition, _student, _requirement);
    }

    // Static factory methods
    public static AssignmentRequirementBuilder Default() => new AssignmentRequirementBuilder();

    public static AssignmentRequirementBuilder Include(EventDefinition eventDef, Student student) =>
        new AssignmentRequirementBuilder()
            .ForEvent(eventDef)
            .ForStudent(student)
            .AsInclude();

    public static AssignmentRequirementBuilder Exclude(EventDefinition eventDef, Student student) =>
        new AssignmentRequirementBuilder()
            .ForEvent(eventDef)
            .ForStudent(student)
            .AsExclude();
}
