namespace CMSMicroservice.Application.UserOrderCQ.Queries.GetAllUserOrderByFilter;
public class GetAllUserOrderByFilterQueryHandler : IRequestHandler<GetAllUserOrderByFilterQuery, GetAllUserOrderByFilterResponseDto>
{
    private readonly IApplicationDbContext _context;

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

    public async Task<GetAllUserOrderByFilterResponseDto> Handle(GetAllUserOrderByFilterQuery request, CancellationToken cancellationToken)
    {
        var query = _context.UserOrders
            .Include(i => i.UserAddress)
            .Include(i => i.User)
            .Include(i => i.FactorDetails)
                .ThenInclude(t => t.Product)
            .Include(i => i.OrderVAT)
            .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.Amount == null || x.Amount == request.Filter.Amount)
                .Where(x => request.Filter.PackageId == null || x.PackageId == request.Filter.PackageId)
                .Where(x => request.Filter.TransactionId == null || x.TransactionId == request.Filter.TransactionId)
                .Where(x => request.Filter.PaymentStatus == null || x.PaymentStatus == request.Filter.PaymentStatus.Value)
                .Where(x => request.Filter.PaymentDate == null || x.PaymentDate >= request.Filter.PaymentDate)
                .Where(x => request.Filter.UserId == null || x.UserId == request.Filter.UserId)
                .Where(x => request.Filter.UserAddressId == null || x.UserAddressId == request.Filter.UserAddressId)
                .Where(x => request.Filter.PaymentMethod == null || x.PaymentMethod == request.Filter.PaymentMethod)
                .Where(x => request.Filter.DeliveryStatus == null || x.DeliveryStatus== request.Filter.DeliveryStatus);
        }
        var meta = await query.GetMetaData(request.PaginationState, cancellationToken);

        var models = await query
            .PaginatedListAsync(paginationState: request.PaginationState)
            .Select(x => new GetAllUserOrderByFilterResponseModel
            {
                Id = x.Id,
                Amount = x.Amount,
                PackageId = x.PackageId ?? 0,
                TransactionId = x.TransactionId,
                PaymentStatus = x.PaymentStatus,
                PaymentDate = x.PaymentDate,
                UserId = x.UserId,
                UserAddressId = x.UserAddressId,
                PaymentMethod = x.PaymentMethod,
                UserAddressText = x.UserAddress.Address,
                FactorDetails = x.FactorDetails.Select(fd => new GetAllUserOrderByFilterResponseModelFactorDetail
                {
                    ProductId = fd.ProductId,
                    ProductTitle = fd.Product.Title,
                    ProductThumbnailPath = fd.Product.ThumbnailPath,
                    UnitPrice = fd.UnitPrice,
                    Count = fd.Count,
                    UnitDiscountPrice = fd.UnitDiscountPrice
                }).ToList(),
                DeliveryStatus = x.DeliveryStatus,
                TrackingCode = x.TrackingCode,
                DeliveryDescription = x.DeliveryDescription,
                UserFullName = (x.User.FirstName ?? string.Empty) + " " + (x.User.LastName ?? string.Empty),
                UserNationalCode = x.User.NationalCode,
                VatAmount = x.OrderVAT != null ? x.OrderVAT.VATAmount : 0,
                VatPercentage = x.OrderVAT != null ? (double)(x.OrderVAT.VATRate * 100) : 0
            })
            .ToListAsync(cancellationToken);

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