public async Task <CatalogSearchResult> SearchAsync(CatalogSearchCriteria criteria)
        {
            var retVal = new CatalogSearchResult();

            var workContext = _workContextFactory();

            var searchCriteria = new VirtoCommerceDomainCatalogModelSearchCriteria
            {
                StoreId                    = workContext.CurrentStore.Id,
                Keyword                    = criteria.Keyword,
                ResponseGroup              = criteria.ResponseGroup.ToString(),
                SearchInChildren           = criteria.SearchInChildren,
                CategoryId                 = criteria.CategoryId,
                CatalogId                  = criteria.CatalogId,
                Currency                   = workContext.CurrentCurrency.Code,
                HideDirectLinkedCategories = true,
                Terms        = criteria.Terms.ToStrings(),
                PricelistIds = workContext.CurrentPricelists.Where(p => p.Currency == workContext.CurrentCurrency.Code).Select(p => p.Id).ToList(),
                Skip         = criteria.Start,
                Take         = criteria.PageSize,
                Sort         = criteria.SortBy
            };

            var searchTask = _searchApi.SearchModuleSearchAsync(searchCriteria);

            if (criteria.CategoryId != null)
            {
                var category = await _catalogModuleApi.CatalogModuleCategoriesGetAsync(criteria.CategoryId);

                if (category != null)
                {
                    retVal.Category = category.ToWebModel(workContext.CurrentLanguage);
                }
            }
            var result = await searchTask;


            if (result != null)
            {
                if (result.Products != null && result.Products.Any())
                {
                    var products = result.Products.Select(x => x.ToWebModel(workContext.CurrentLanguage, workContext.CurrentCurrency)).ToArray();
                    retVal.Products = new StorefrontPagedList <Product>(products, criteria.PageNumber, criteria.PageSize, result.ProductsTotalCount.Value, page => workContext.RequestUrl.SetQueryParameter("page", page.ToString()).ToString());

                    await Task.WhenAll(_pricingService.EvaluateProductPricesAsync(retVal.Products), LoadProductsInventoriesAsync(retVal.Products));
                }

                if (result.Categories != null && result.Categories.Any())
                {
                    retVal.Categories = result.Categories.Select(x => x.ToWebModel(workContext.CurrentLanguage));
                }

                if (result.Aggregations != null)
                {
                    retVal.Aggregations = result.Aggregations.Select(x => x.ToWebModel()).ToArray();
                }
            }

            return(retVal);
        }
        public async Task <CatalogSearchResult> SearchAsync(CatalogSearchCriteria criteria)
        {
            var retVal = new CatalogSearchResult();

            string sort      = "manual";
            string sortOrder = "asc";

            if (!string.IsNullOrEmpty(criteria.SortBy))
            {
                var splittedSortBy = criteria.SortBy.Split('-');
                if (splittedSortBy.Length > 1)
                {
                    sort      = splittedSortBy[0].Equals("title", StringComparison.OrdinalIgnoreCase) ? "name" : splittedSortBy[0];
                    sortOrder = splittedSortBy[1].IndexOf("descending", StringComparison.OrdinalIgnoreCase) >= 0 ? "desc" : "asc";
                }
            }

            var result = await _searchApi.SearchModuleSearchAsync(
                criteriaStoreId : _workContext.CurrentStore.Id,
                criteriaKeyword : criteria.Keyword,
                criteriaResponseGroup : criteria.ResponseGroup.ToString(),
                criteriaSearchInChildren : true,
                criteriaCategoryId : criteria.CategoryId,
                criteriaCatalogId : criteria.CatalogId,
                criteriaCurrency : _workContext.CurrentCurrency.Code,
                criteriaHideDirectLinkedCategories : true,
                criteriaTerms : criteria.Terms.ToStrings(),
                criteriaPricelistIds : _workContext.CurrentPriceListIds.ToList(),
                criteriaSkip : criteria.PageSize *(criteria.PageNumber - 1),
                criteriaTake : criteria.PageSize,
                criteriaSort : sort,
                criteriaSortOrder : sortOrder);

            if (criteria.CategoryId != null)
            {
                var category = await _catalogModuleApi.CatalogModuleCategoriesGetAsync(criteria.CategoryId);

                if (category != null)
                {
                    retVal.Category = category.ToWebModel();
                }
            }

            if (result != null)
            {
                if (result.Products != null && result.Products.Any())
                {
                    var products = result.Products.Select(x => x.ToWebModel(_workContext.CurrentLanguage, _workContext.CurrentCurrency)).ToArray();
                    retVal.Products = new StorefrontPagedList <Product>(products, criteria.PageNumber, criteria.PageSize, result.ProductsTotalCount.Value, page => _workContext.RequestUrl.SetQueryParameter("page", page.ToString()).ToString());

                    LoadProductsPrices(retVal.Products.ToArray());
                    LoadProductsInventories(retVal.Products.ToArray());
                }

                if (result.Categories != null && result.Categories.Any())
                {
                    retVal.Categories = result.Categories.Select(x => x.ToWebModel());
                }

                if (result.Aggregations != null)
                {
                    retVal.Aggregations = result.Aggregations.Select(x => x.ToWebModel()).ToArray();
                }
            }

            return(retVal);
        }