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

namespace TeleWave.Application.Library.Collections.ListCollections;

public sealed class ListCollectionsQueryHandler(IAppDbContext dbContext)
    : IQueryHandler<ListCollectionsQuery, IReadOnlyList<CollectionSummaryDto>>
{
    public async Task<IReadOnlyList<CollectionSummaryDto>> Handle(
        ListCollectionsQuery query,
        CancellationToken cancellationToken
    )
    {
        var collections = await dbContext
            .Collections.AsNoTracking()
            .Include(c => c.Items)
            .OrderBy(c => c.Name)
            .ToListAsync(cancellationToken);

        // Единиц воспроизведения может быть больше, чем частей: сериал внутри коллекции
        // разворачивается в свои серии.
        var showIds = collections
            .SelectMany(c => c.Items.Select(i => i.ShowId))
            .Distinct()
            .ToList();
        var episodeCounts = await dbContext
            .Shows.AsNoTracking()
            .Where(s => showIds.Contains(s.Id))
            .Select(s => new { s.Id, s.Episodes.Count })
            .ToDictionaryAsync(x => x.Id, x => x.Count, cancellationToken);

        return collections
            .Select(c => new CollectionSummaryDto(
                c.Id,
                c.Name,
                c.Description,
                c.PosterImageId,
                c.Items.Count,
                c.Items.Sum(i => episodeCounts.TryGetValue(i.ShowId, out var n) ? n : 0),
                c.CreatedAt
            ))
            .ToList();
    }
}
