namespace CMSMicroservice.Application.UserWalletCQ.Queries.GetAllUserWalletByFilter;

public class
    GetAllUserWalletByFilterQueryHandler : IRequestHandler<GetAllUserWalletByFilterQuery,
    GetAllUserWalletByFilterResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetAllUserWalletByFilterResponseDto> Handle(GetAllUserWalletByFilterQuery request,
        CancellationToken cancellationToken)
    {
        // #region Remove This Region After Implementing Migration
        //
        // // This Region Is For Adding UserWallet For Existing Users In Database
        // var usersWithNoWallet = _context.Users
        //     .Where(u => !_context.UserWallets.Any(uw => uw.UserId == u.Id))
        //     .Select(u => u.Id)
        //     .ToList();
        // foreach (var userId in usersWithNoWallet)
        // {
        //     await _context.UserWallets.AddAsync(new UserWallet()
        //     {
        //         UserId = userId,
        //         Balance = 0,
        //         NetworkBalance = 0
        //     }, cancellationToken);
        // }
        //
        // if (usersWithNoWallet.Any())
        // {
        //     await _context.SaveChangesAsync(cancellationToken);
        // }
        //
        // #endregion


        var query = _context.UserWallets
            .ApplyOrder(sortBy: request.SortBy)
            .AsNoTracking()
            .AsQueryable();
        if (request.Filter is not null)
        {
            query = query
                    .Where(x => request.Filter.Id == null || x.Id == request.Filter.Id)
                    .Where(x => request.Filter.UserId == null || x.UserId == request.Filter.UserId)
                    .Where(x => request.Filter.Balance == null || x.Balance == request.Filter.Balance)
                ;
        }

        return new GetAllUserWalletByFilterResponseDto
        {
            MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
            Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
                .ProjectToType<GetAllUserWalletByFilterResponseModel>().ToListAsync(cancellationToken)
        };
    }
}