namespace TeleWave.Domain.Programming;
///
/// Позиция группы: ссылка на шоу или коллекцию плюс вес и порядок.
///
/// — полиморфная ссылка, поэтому внешнего ключа на неё нет: удаление шоу
/// или коллекции из библиотеки чистит позиции команд удаления, а не каскадом БД.
///
public class GroupItem
{
public Guid Id { get; private set; }
public Guid GroupId { get; private set; }
public GroupElementKind ElementKind { get; private set; }
public Guid ElementId { get; private set; }
/// Чем эта позиция является для группы — см. .
public GroupItemRole Role { get; private set; }
///
/// Вес при случайном выборе внутри группы (по умолчанию 1). Не конфликтует с остыванием, если
/// применять их в правильном порядке: сначала остывание отсекает недавно показанное, затем
/// взвешенный выбор работает среди оставшихся.
///
public int Weight { get; private set; }
/// Порядок для последовательных стратегий (может иметь разрывы после удалений).
public int Position { get; private set; }
public const int DefaultWeight = 1;
private GroupItem() { }
internal static GroupItem Create(
Guid groupId,
GroupElementKind elementKind,
Guid elementId,
int position,
GroupItemRole role = GroupItemRole.Member
) =>
new()
{
Id = Guid.NewGuid(),
GroupId = groupId,
ElementKind = elementKind,
ElementId = elementId,
Role = role,
Weight = DefaultWeight,
Position = position,
};
internal void SetRole(GroupItemRole role) => Role = role;
internal void SetPosition(int position) => Position = position;
internal void SetWeight(int weight) => Weight = Math.Max(0, weight);
}