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

namespace TeleWave.Application.Library.Genres.ListGenres;

public sealed class ListGenresQueryHandler(IAppDbContext dbContext)
    : IQueryHandler<ListGenresQuery, IReadOnlyList<GenreDto>>
{
    public async Task<IReadOnlyList<GenreDto>> Handle(
        ListGenresQuery query,
        CancellationToken cancellationToken
    )
    {
        var genres = await dbContext
            .Genres.AsNoTracking()
            .Include(g => g.Aliases)
            .OrderBy(g => g.SortOrder)
            .ThenBy(g => g.Name)
            .ToListAsync(cancellationToken);

        var usage = await dbContext
            .ShowGenres.AsNoTracking()
            .GroupBy(sg => sg.GenreId)
            .Select(g => new { GenreId = g.Key, Count = g.Count() })
            .ToDictionaryAsync(x => x.GenreId, x => x.Count, cancellationToken);

        return genres
            .Select(g => new GenreDto(
                g.Id,
                g.Name,
                g.Slug,
                g.SortOrder,
                g.IsSystem,
                g.Aliases.Select(a => a.Value).OrderBy(v => v, StringComparer.Ordinal).ToList(),
                usage.TryGetValue(g.Id, out var count) ? count : 0
            ))
            .ToList();
    }
}
