using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage;
using TeleWave.Domain.Auth;
using TeleWave.Domain.Broadcast;
using TeleWave.Domain.Images;
using TeleWave.Domain.Library;
using TeleWave.Domain.Media;
using TeleWave.Domain.Programming;
using TeleWave.Domain.Settings;

namespace TeleWave.Application.Common.Interfaces;

public interface IAppDbContext
{
    DbSet<RefreshToken> RefreshTokens { get; }
    DbSet<MediaAsset> MediaAssets { get; }
    DbSet<Show> Shows { get; }
    DbSet<Genre> Genres { get; }
    DbSet<GenreAlias> GenreAliases { get; }
    DbSet<ShowGenre> ShowGenres { get; }
    DbSet<Collection> Collections { get; }
    DbSet<CollectionItem> CollectionItems { get; }
    DbSet<Group> Groups { get; }
    DbSet<GroupItem> GroupItems { get; }
    DbSet<ScheduleTemplate> ScheduleTemplates { get; }
    DbSet<GridLayer> GridLayers { get; }
    DbSet<Slot> Slots { get; }
    DbSet<SlotState> SlotStates { get; }
    DbSet<JunctionTemplate> JunctionTemplates { get; }
    DbSet<JunctionElement> JunctionElements { get; }
    DbSet<Channel> Channels { get; }
    DbSet<ScheduleEntry> ScheduleEntries { get; }
    DbSet<BumperTemplate> BumperTemplates { get; }
    DbSet<BumperTextVariant> BumperTextVariants { get; }
    DbSet<BumperAsset> BumperAssets { get; }
    DbSet<AppSetting> AppSettings { get; }
    DbSet<Image> Images { get; }

    Task<int> SaveChangesAsync(CancellationToken cancellationToken);

    /// <summary>Открывает явную транзакцию БД — для команд с несколькими операциями (в т.ч.
    /// <c>ExecuteDelete</c> в обход change-tracker), которые должны быть атомарны.</summary>
    Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken);

    /// <summary>Берёт транзакционную advisory-блокировку по каналу (снимается при коммите/откате).
    /// Сериализует генерацию расписания одного канала между фоновым тиком и ручной перегенерацией.
    /// Вызывать внутри открытой транзакции.</summary>
    Task AcquireChannelLockAsync(Guid channelId, CancellationToken cancellationToken);
}
