using JSMR.Application.Circles.Queries.GetCreators;
using Microsoft.EntityFrameworkCore;

namespace JSMR.Infrastructure.Data.Repositories.Circles;

public class CircleCreatorsProvider(AppDbContext context) : ICircleCreatorsProvider
{
    public async Task<GetCircleCreatorsResponse> HandleAsync(GetCircleCreatorsRequest request, CancellationToken cancellationToken = default)
    {
        int? circleId = await CircleLookup.ResolveCircleIdAsync(context, request.CircleId, request.NameOrMakerId, cancellationToken);

        if (circleId is null)
            return new GetCircleCreatorsResponse([]);

        IQueryable<CircleCreatorItem> query =
           from voiceWork in context.VoiceWorks.AsNoTracking()
           where voiceWork.CircleId == circleId.Value
           join voiceWorkCreator in context.VoiceWorkCreators.AsNoTracking() on voiceWork.VoiceWorkId equals voiceWorkCreator.VoiceWorkId
           join creator in context.Creators.AsNoTracking() on voiceWorkCreator.CreatorId equals creator.CreatorId
           group new { creator.Name, voiceWork.SalesDate, voiceWork.Downloads } by creator.Name into g
           select new CircleCreatorItem(
               g.Key,
               g.Min(x => x.SalesDate),
               g.Max(x => x.SalesDate),
               g.Sum(x => x.Downloads ?? 0),
               g.Count());

        CircleCreatorItem[] items = await query
            .OrderByDescending(x => x.Count)
            .ThenByDescending(x => x.Downloads)
            .ToArrayAsync(cancellationToken);

        return new GetCircleCreatorsResponse(items);
    }
}