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

namespace TeleWave.Application.Maintenance.ClearAllMedia;

public sealed class ClearAllMediaCommandHandler(IAppDbContext dbContext, IMediaStorage storage)
    : ICommandHandler<ClearAllMediaCommand, Result<int>>
{
    public async Task<Result<int>> Handle(
        ClearAllMediaCommand command,
        CancellationToken cancellationToken
    )
    {
        var assets = await dbContext
            .MediaAssets.Select(a => new { a.Id, a.OriginalExtension })
            .ToListAsync(cancellationToken);

        // Оба ExecuteDelete должны быть атомарны; файлы удаляем только после успешного коммита БД
        // (best-effort) — иначе при падении между ними расписание/ассеты рассинхронизируются с ФС.
        await using var transaction = await dbContext.BeginTransactionAsync(cancellationToken);
        // Расписание ссылается на удаляемые ассеты — чистим его тоже.
        await dbContext.ScheduleEntries.ExecuteDeleteAsync(cancellationToken);
        var deleted = await dbContext.MediaAssets.ExecuteDeleteAsync(cancellationToken);
        await transaction.CommitAsync(cancellationToken);

        foreach (var asset in assets)
            await storage.DeleteAssetArtifactsAsync(
                asset.Id,
                asset.OriginalExtension,
                cancellationToken
            );

        return Result.Success(deleted);
    }
}
