namespace TeleWave.Domain.Programming.Planning;

/// <summary>
/// Кольцевой перебор единиц с проверкой «влезает ли в остаток». Общий и для добора шва рекламой,
/// и для аварийного запаса: в обоих случаях нужно продолжать с места прошлого раза — иначе каждая
/// пауза начиналась бы с одного и того же ролика, — и уметь взять другую единицу, когда очередная
/// не влезла. «Не влезла эта» не значит «не влезет ничего»: в списке есть и короткие.
/// </summary>
public sealed class UnitRotation<T>(IReadOnlyList<T> items, Func<T, TimeSpan> duration)
    where T : class
{
    private int _cursor;

    public T? Next(TimeSpan available)
    {
        for (var offset = 0; offset < items.Count; offset++)
        {
            var index = (_cursor + offset) % items.Count;
            var item = items[index];
            var length = duration(item);
            if (length <= TimeSpan.Zero || length > available)
                continue;

            _cursor = (index + 1) % items.Count;
            return item;
        }

        return null;
    }
}
