using Core.Entities;

namespace Tests.Builders;

/// <summary>
/// Fluent builder for creating StudentEventRanking test entities.
/// </summary>
public class StudentEventRankingBuilder
{
    private Student? _student = null;
    private EventDefinition? _eventDefinition = null;
    private int _rank = 1;

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

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

    public StudentEventRankingBuilder WithRank(int rank)
    {
        if (rank < 1 || rank > StudentEventRanking.MaxRank)
            throw new ArgumentOutOfRangeException(nameof(rank),
                $"Rank must be between 1 and {StudentEventRanking.MaxRank}");

        _rank = rank;
        return this;
    }

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

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

        var ranking = new StudentEventRanking
        {
            Student = _student,
            EventDefinition = _eventDefinition,
            Rank = _rank
        };

        // Set up bidirectional relationship: add to student's EventRankings if not already there
        if (!_student.EventRankings.Any(er => er.EventDefinition == _eventDefinition))
        {
            _student.EventRankings.Add(ranking);
        }

        return ranking;
    }

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

    public static StudentEventRankingBuilder Create(Student student, EventDefinition eventDef) =>
        new StudentEventRankingBuilder().ForStudent(student).ForEvent(eventDef);
}
