using TeleWave.Domain.Programming;

namespace TeleWave.Application.Programming.Templates.Generate;

/// <summary>Что делать с тем, что в сетке уже есть.</summary>
public enum GridGenerationMode
{
    /// <summary>Только незакрытые интервалы; ручные слоты не трогаются.</summary>
    FillGaps = 0,

    /// <summary>Снести все слоты шаблона и построить неделю заново.</summary>
    Rebuild = 1,
}

/// <summary>Куда ложится слот. Имена слоёв — в <see cref="GridPlanner"/>.</summary>
public enum GridPlanLayer
{
    Main = 0,
    Weekend = 1,

    /// <summary>Праздничная сетка: слой поверх основного, действующий только в свои даты.</summary>
    Season = 2,
}

/// <summary>
/// Будущий слот: то же, что <see cref="SlotInput"/>, но без слоя и идентификаторов. Сравнивается
/// по значению — на этом держится схлопывание одинаковых дней в один слот «каждый день».
/// </summary>
public sealed record PlannedSlot(
    GridPlanLayer Layer,
    int? Weekday,
    TimeOnly Start,
    int DurationMinutes,
    string Title,
    Daypart Daypart,
    SlotKind SlotKind,
    Guid? GroupId,
    string? GroupName,
    SlotBlockMode BlockMode,
    int BlockValue,
    SlotStrategy? Strategy,
    RepeatSource? RepeatSource,
    /// <summary>Жёсткий старт. Ставится в начале прайма: кино должно начинаться в объявленное время.</summary>
    bool IsAnchor
);

/// <summary>
/// Результат разбора: что будет создано, что снесено и о чём стоит знать заранее. Считается и для
/// предпросмотра, и для самой генерации — одним и тем же кодом, поэтому показанное совпадает
/// с созданным.
/// </summary>
/// <param name="FreeMinutes">Сколько минут недели генератор считал свободными.</param>
/// <param name="CoveredMinutes">Сколько из них закрыто слотами плана.</param>
public sealed record GridPlan(
    GridProfile Profile,
    GridGenerationMode Mode,
    IReadOnlyList<PlannedSlot> Slots,
    IReadOnlyList<PlanNote> Notes,
    int SlotsToRemove,
    Guid? FallbackGroupId,
    string? FallbackGroupName,
    int FreeMinutes,
    int CoveredMinutes
);
