namespace TeleWave.Domain.Broadcast;

/// <summary>
/// Материализованная запись расписания канала: конкретный ассет в конкретное время. Программы и
/// реклама идут встык (<see cref="EndsAtUtc"/> одной равен <see cref="StartsAtUtc"/> следующей).
/// </summary>
public class ScheduleEntry
{
    public Guid Id { get; private set; }
    public Guid ChannelId { get; private set; }
    public Guid MediaAssetId { get; private set; }
    public ScheduleEntryKind Kind { get; private set; }
    public DateTimeOffset StartsAtUtc { get; private set; }
    public DateTimeOffset EndsAtUtc { get; private set; }

    /// <summary>Шоу (для <see cref="ScheduleEntryKind.Program"/>) — для EPG.</summary>
    public Guid? ShowId { get; private set; }

    /// <summary>Индекс серии в упорядоченном списке шоу (для EPG).</summary>
    public int? EpisodeIndex { get; private set; }

    /// <summary>Подблок заставки (<see cref="BumperTextVariant"/>), которым отрендерена запись — для метки в админ-расписании.</summary>
    public Guid? BumperVariantId { get; private set; }

    /// <summary>Слот сетки, породивший запись (null — служебная запись вне слотов).</summary>
    public Guid? SlotId { get; private set; }

    /// <summary>
    /// Коллекция (франшиза), частью которой шла запись, или null. Из шоу её не вывести: одно и то же
    /// шоу попадает в эфир и само по себе, и внутри коллекции, а группа хранит только ссылку.
    /// </summary>
    public Guid? CollectionId { get; private set; }

    /// <summary>
    /// Цепочка происхождения (JSON): слой, слот, группа, стратегия, дрейф. Пишется в момент
    /// генерации — восстановить её потом невозможно, а без неё отладка сетки превращается
    /// в угадывание.
    /// </summary>
    public string? TraceJson { get; private set; }

    private ScheduleEntry() { }

    /// <summary>Запись, порождённая слотом сетки: программа, заполнитель или конец вещания.</summary>
    public static ScheduleEntry FromSlot(
        Guid channelId,
        Guid mediaAssetId,
        ScheduleEntryKind kind,
        DateTimeOffset startsAtUtc,
        DateTimeOffset endsAtUtc,
        ScheduleEntryOrigin origin
    ) =>
        new()
        {
            Id = Guid.NewGuid(),
            ChannelId = channelId,
            MediaAssetId = mediaAssetId,
            Kind = kind,
            StartsAtUtc = startsAtUtc,
            EndsAtUtc = endsAtUtc,
            ShowId = origin.ShowId,
            EpisodeIndex = origin.EpisodeIndex,
            SlotId = origin.SlotId,
            TraceJson = origin.TraceJson,
            CollectionId = origin.CollectionId,
        };

    public static ScheduleEntry Program(
        Guid channelId,
        Guid mediaAssetId,
        DateTimeOffset startsAtUtc,
        DateTimeOffset endsAtUtc,
        Guid showId,
        int episodeIndex
    ) =>
        new()
        {
            Id = Guid.NewGuid(),
            ChannelId = channelId,
            MediaAssetId = mediaAssetId,
            Kind = ScheduleEntryKind.Program,
            StartsAtUtc = startsAtUtc,
            EndsAtUtc = endsAtUtc,
            ShowId = showId,
            EpisodeIndex = episodeIndex,
        };

    public static ScheduleEntry Ad(
        Guid channelId,
        Guid mediaAssetId,
        DateTimeOffset startsAtUtc,
        DateTimeOffset endsAtUtc
    ) =>
        new()
        {
            Id = Guid.NewGuid(),
            ChannelId = channelId,
            MediaAssetId = mediaAssetId,
            Kind = ScheduleEntryKind.Ad,
            StartsAtUtc = startsAtUtc,
            EndsAtUtc = endsAtUtc,
        };

    /// <summary>Заставка-переход. <paramref name="showId"/> — следующее шоу (для EPG/справки).</summary>
    public static ScheduleEntry Bumper(
        Guid channelId,
        Guid mediaAssetId,
        DateTimeOffset startsAtUtc,
        DateTimeOffset endsAtUtc,
        Guid? showId,
        Guid? bumperVariantId
    ) =>
        new()
        {
            Id = Guid.NewGuid(),
            ChannelId = channelId,
            MediaAssetId = mediaAssetId,
            Kind = ScheduleEntryKind.Bumper,
            StartsAtUtc = startsAtUtc,
            EndsAtUtc = endsAtUtc,
            ShowId = showId,
            BumperVariantId = bumperVariantId,
        };
}
