namespace CMSMicroservice.Application.UserCQ.Queries.GetAllUserByFilter;
public class GetAllUserByFilterQueryHandler : IRequestHandler<GetAllUserByFilterQuery, GetAllUserByFilterResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetAllUserByFilterResponseDto> Handle(GetAllUserByFilterQuery request, CancellationToken cancellationToken)
    {
        var query = _context.Users
            .ApplyOrder(sortBy: request.SortBy)
            .AsNoTracking()
            .AsQueryable();
        if (request.Filter is not null)
        {
            query = query
                .Where(x => request.Filter.SearchText == null ||
                            x.FirstName.Contains(request.Filter.SearchText) ||
                            x.LastName.Contains(request.Filter.SearchText) ||
                            x.Mobile.Contains(request.Filter.SearchText) ||
                            x.NationalCode.Contains(request.Filter.SearchText))
                .Where(x => request.Filter.Id == null || x.Id == request.Filter.Id)
                .Where(x => request.Filter.FirstName == null || x.FirstName.Contains(request.Filter.FirstName))
                .Where(x => request.Filter.LastName == null || x.LastName.Contains(request.Filter.LastName))
                .Where(x => request.Filter.Mobile == null || x.Mobile.Contains(request.Filter.Mobile))
                .Where(x => request.Filter.NationalCode == null || x.NationalCode.Contains(request.Filter.NationalCode))
                .Where(x => request.Filter.AvatarPath == null || x.AvatarPath.Contains(request.Filter.AvatarPath))
                .Where(x => request.Filter.ReferralCode == null || x.ReferralCode == request.Filter.ReferralCode)
                .Where(x => request.Filter.IsMobileVerified == null || x.IsMobileVerified == request.Filter.IsMobileVerified)
                .Where(x => request.Filter.NetworkParentId == null || x.NetworkParentId == request.Filter.NetworkParentId)
                .Where(x => request.Filter.SmsNotifications == null || x.SmsNotifications == request.Filter.SmsNotifications)
                .Where(x => request.Filter.EmailNotifications == null || x.EmailNotifications == request.Filter.EmailNotifications)
                .Where(x => request.Filter.PushNotifications == null || x.PushNotifications == request.Filter.PushNotifications)
                .Where(x => request.Filter.BirthDate == null || x.BirthDate == request.Filter.BirthDate);
        }

        return new GetAllUserByFilterResponseDto
        {
            MetaData = await query.GetMetaData(request.PaginationState, cancellationToken),
            Models = await query.PaginatedListAsync(paginationState: request.PaginationState)
                .Select(x => new GetAllUserByFilterResponseModel
                {
                    Id = x.Id,
                    FirstName = x.FirstName,
                    LastName = x.LastName,
                    Mobile = x.Mobile,
                    NationalCode = x.NationalCode,
                    AvatarPath = x.AvatarPath,
                    NetworkParentId = x.NetworkParentId,
                    ReferralCode = x.ReferralCode,
                    IsMobileVerified = x.IsMobileVerified,
                    MobileVerifiedAt = x.MobileVerifiedAt,
                    EmailNotifications = x.EmailNotifications,
                    SmsNotifications = x.SmsNotifications,
                    PushNotifications = x.PushNotifications,
                    BirthDate = x.BirthDate,
                    DefaultAddress = x.UserAddresses
                        .Where(a => a.IsDefault && !a.IsDeleted)
                        .Select(a => a.Address)
                        .FirstOrDefault() ?? string.Empty,
                    DefaultPostalCode = x.UserAddresses
                        .Where(a => a.IsDefault && !a.IsDeleted)
                        .Select(a => a.PostalCode)
                        .FirstOrDefault() ?? string.Empty
                })
                .ToListAsync(cancellationToken)
        };
    }
}
