using LiteCqrs;
using Microsoft.EntityFrameworkCore;
using TeleWave.Application.Common.Interfaces;
using TeleWave.Domain.Library;

namespace TeleWave.Application.Library.Interstitials.ListInterstitials;

public sealed class ListInterstitialsQueryHandler(IAppDbContext dbContext)
    : IQueryHandler<ListInterstitialsQuery, IReadOnlyList<InterstitialDto>>
{
    public async Task<IReadOnlyList<InterstitialDto>> Handle(
        ListInterstitialsQuery query,
        CancellationToken cancellationToken
    )
    {
        var shows = await dbContext
            .Shows.AsNoTracking()
            .Include(s => s.Episodes)
            .Where(s => s.Kind == ShowKind.Interstitial)
            .OrderBy(s => s.Name)
            .ToListAsync(cancellationToken);

        // У ролика ровно одна «серия» — берём её ассет, чтобы показать длительность и статус обработки.
        var assetIds = shows
            .Select(s =>
                s.Episodes.OrderBy(e => e.Position).Select(e => e.MediaAssetId).FirstOrDefault()
            )
            .Where(id => id != Guid.Empty)
            .Distinct()
            .ToList();
        var assets = await dbContext
            .MediaAssets.AsNoTracking()
            .Where(a => assetIds.Contains(a.Id))
            .Select(a => new
            {
                a.Id,
                a.Status,
                a.Duration,
            })
            .ToDictionaryAsync(a => a.Id, cancellationToken);

        return shows
            .Select(s =>
            {
                var assetId = s
                    .Episodes.OrderBy(e => e.Position)
                    .Select(e => (Guid?)e.MediaAssetId)
                    .FirstOrDefault();
                var asset = assetId is { } id && assets.TryGetValue(id, out var a) ? a : null;
                return new InterstitialDto(
                    s.Id,
                    s.Name,
                    assetId,
                    asset?.Status,
                    asset?.Duration?.TotalSeconds,
                    s.CreatedAt
                );
            })
            .ToList();
    }
}
