using LiteCqrs;
using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Application.Common.Models;
using TeleWave.Application.Library;
using TeleWave.Application.Media;

namespace TeleWave.Application.Maintenance.DeleteShowMedia;

public sealed class DeleteShowMediaCommandHandler(IAppDbContext dbContext, ShowMediaEraser eraser)
    : ICommandHandler<DeleteShowMediaCommand, Result<int>>
{
    public async Task<Result<int>> Handle(
        DeleteShowMediaCommand command,
        CancellationToken cancellationToken
    )
    {
        var show = await dbContext
            .Shows.Include(s => s.Episodes)
            .FirstOrDefaultAsync(s => s.Id == command.ShowId, cancellationToken);
        if (show is null)
            return Result.Failure<int>(ShowErrors.NotFound);

        var episodes = show.Episodes.ToList();

        // Всё, что в БД, — одной транзакцией; файлы удаляются после коммита.
        await using var transaction = await dbContext.BeginTransactionAsync(cancellationToken);
        var erased = await eraser.EraseAsync(show, cancellationToken);

        // Шоу остаётся, а его серии теперь указывали бы на удалённые ассеты — убираем их.
        foreach (var episode in episodes)
            show.RemoveEpisode(episode.Id);
        await dbContext.SaveChangesAsync(cancellationToken);
        await transaction.CommitAsync(cancellationToken);

        await eraser.DeleteFilesAsync(erased, cancellationToken);
        return Result.Success(erased.Count);
    }
}
