using Core.Entities;

namespace Tests.Builders;

/// <summary>
/// Fluent builder for creating Team test entities.
/// </summary>
public class TeamBuilder
{
    private static int _idCounter = 1;

    private int _id = _idCounter++;
    private EventDefinition? _event = null;
    private List<Student> _students = new();
    private Student? _captain = null;
    private string? _identifier = null;

    public TeamBuilder ForEvent(EventDefinition eventDef)
    {
        _event = eventDef;
        return this;
    }

    public TeamBuilder WithStudent(Student student)
    {
        if (!_students.Contains(student))
            _students.Add(student);
        return this;
    }

    public TeamBuilder WithStudents(params Student[] students)
    {
        foreach (var student in students)
        {
            if (!_students.Contains(student))
                _students.Add(student);
        }
        return this;
    }

    public TeamBuilder WithStudents(IEnumerable<Student> students)
    {
        foreach (var student in students)
        {
            if (!_students.Contains(student))
                _students.Add(student);
        }
        return this;
    }

    public TeamBuilder WithCaptain(Student captain)
    {
        _captain = captain;
        // Ensure captain is in the students list
        if (!_students.Contains(captain))
            _students.Add(captain);
        return this;
    }

    public TeamBuilder WithIdentifier(string identifier)
    {
        _identifier = identifier;
        return this;
    }

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

        var team = new Team
        {
            Id = _id,
            Event = _event,
            Students = _students.ToList(),
            Captain = _captain,
            Identifier = _identifier
        };

        // Set up bidirectional relationship: add team to each student's Teams collection
        foreach (var student in _students)
        {
            if (!student.Teams.Contains(team))
                student.Teams.Add(team);
        }

        return team;
    }

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

    public static TeamBuilder Create(EventDefinition eventDef) =>
        new TeamBuilder().ForEvent(eventDef);

    /// <summary>
    /// Reset the ID counter for test isolation. Call this in test SetUp.
    /// </summary>
    public static void ResetIdCounter() => _idCounter = 1;
}
