namespace CMSMicroservice.Application.ClubMembershipCQ.Queries.GetClubMembershipHistory;

public class GetClubMembershipHistoryQueryHandler : IRequestHandler<GetClubMembershipHistoryQuery, GetClubMembershipHistoryResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetClubMembershipHistoryResponseDto> Handle(GetClubMembershipHistoryQuery request, CancellationToken cancellationToken)
    {
        var query = _context.ClubMembershipHistories
            .Include(x => x.ClubMembership)
                .ThenInclude(m => m!.User)
            .AsNoTracking()
            .AsQueryable();

        if (request.Filter != null)
        {
            if (request.Filter.ClubMembershipId.HasValue)
                query = query.Where(x => x.ClubMembershipId == request.Filter.ClubMembershipId.Value);

            if (request.Filter.UserId.HasValue)
                query = query.Where(x => x.UserId == request.Filter.UserId.Value);

            if (request.Filter.Action.HasValue)
                query = query.Where(x => x.Action == request.Filter.Action.Value);

            if (request.Filter.CreatedFrom.HasValue)
                query = query.Where(x => x.Created >= request.Filter.CreatedFrom.Value);

            if (request.Filter.CreatedTo.HasValue)
                query = query.Where(x => x.Created <= request.Filter.CreatedTo.Value);
        }

        query = query.ApplyOrder(sortBy: request.SortBy ?? "-Created");

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

        var models = await query
            .PaginatedListAsync(paginationState: request.PaginationState)
            .Select(x => new GetClubMembershipHistoryResponseModel
            {
                Id = x.Id,
                ClubMembershipId = x.ClubMembershipId,
                UserId = x.UserId,
                UserName = x.ClubMembership != null && x.ClubMembership.User != null
                    ? $"{x.ClubMembership.User.FirstName} {x.ClubMembership.User.LastName}"
                    : string.Empty,
                OldIsActive = x.OldIsActive,
                NewIsActive = x.NewIsActive,
                OldInitialContribution = x.OldInitialContribution,
                NewInitialContribution = x.NewInitialContribution,
                Action = x.Action,
                Reason = x.Reason,
                PerformedBy = x.PerformedBy,
                Created = x.Created
            })
            .ToListAsync(cancellationToken);

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