namespace CMSMicroservice.Application.ClubMembershipCQ.Queries.GetAllClubMemberships;

public class GetAllClubMembershipsQueryHandler : IRequestHandler<GetAllClubMembershipsQuery, GetAllClubMembershipsResponseDto>
{
    private readonly IApplicationDbContext _context;

    public GetAllClubMembershipsQueryHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<GetAllClubMembershipsResponseDto> Handle(GetAllClubMembershipsQuery request, CancellationToken cancellationToken)
    {
        var query = _context.ClubMemberships
            .Include(x => x.User)
            .Include(x => x.LastPackage)
            .ApplyOrder(sortBy: request.SortBy)
            .AsNoTracking()
            .AsQueryable();

        if (request.Filter is not null)
        {
            query = query
                .Where(x => request.Filter.UserId == null || x.UserId == request.Filter.UserId)
                .Where(x => request.Filter.IsActive == null || x.IsActive == request.Filter.IsActive)
                .Where(x => request.Filter.ActivationDateFrom == null || x.ActivatedAt >= request.Filter.ActivationDateFrom)
                .Where(x => request.Filter.ActivationDateTo == null || x.ActivatedAt <= request.Filter.ActivationDateTo);
        }

        var meta = await query.GetMetaData(request.PaginationState, cancellationToken);

        var models = await query
            .PaginatedListAsync(paginationState: request.PaginationState)
            .Select(x => new GetAllClubMembershipsResponseModel
            {
                Id = x.Id,
                UserId = x.UserId,
                UserName = x.User != null ? $"{x.User.FirstName} {x.User.LastName}" : string.Empty,
                PackageId = x.LastPackageId ?? 0,
                PackageName = x.LastPackage != null ? x.LastPackage.Title : string.Empty,
                IsActive = x.IsActive,
                ActivatedAt = x.LastActivationDate ?? x.ActivatedAt,
                InitialContribution = x.InitialContribution,
                TotalEarned = x.TotalEarned,
                Created = x.Created,
                LastModified = x.LastModified
            })
            .ToListAsync(cancellationToken);

        return new GetAllClubMembershipsResponseDto
        {
            MetaData = meta,
            Models = models
        };
    }
}
