public virtual IActionResult ProductDetails(string productId, string updatecartitemid = "")
        {
            var product = _productService.GetProductById(productId);

            if (product == null)
            {
                return(InvokeHttp404());
            }

            var customer = _workContext.CurrentCustomer;

            //published?
            if (!_catalogSettings.AllowViewUnpublishedProductPage)
            {
                //Check whether the current user has a "Manage catalog" permission
                //It allows him to preview a product before publishing
                if (!product.Published && !_permissionService.Authorize(StandardPermissionProvider.ManageProducts, customer))
                {
                    return(InvokeHttp404());
                }
            }

            //ACL (access control list)
            if (!_aclService.Authorize(product, customer))
            {
                return(InvokeHttp404());
            }

            //Store mapping
            if (!_storeMappingService.Authorize(product))
            {
                return(InvokeHttp404());
            }

            //availability dates
            if (!product.IsAvailable() && !(product.ProductType == ProductType.Auction))
            {
                return(InvokeHttp404());
            }

            //visible individually?
            if (!product.VisibleIndividually)
            {
                //is this one an associated products?
                var parentGroupedProduct = _productService.GetProductById(product.ParentGroupedProductId);
                if (parentGroupedProduct == null)
                {
                    return(RedirectToRoute("HomePage"));
                }

                return(RedirectToRoute("Product", new { SeName = parentGroupedProduct.GetSeName() }));
            }
            //update existing shopping cart item?
            ShoppingCartItem updatecartitem = null;

            if (_shoppingCartSettings.AllowCartItemEditing && !String.IsNullOrEmpty(updatecartitemid))
            {
                var cart = customer.ShoppingCartItems
                           .LimitPerStore(_storeContext.CurrentStore.Id)
                           .ToList();
                updatecartitem = cart.FirstOrDefault(x => x.Id == updatecartitemid);
                //not found?
                if (updatecartitem == null)
                {
                    return(RedirectToRoute("Product", new { SeName = product.GetSeName() }));
                }
                //is it this product?
                if (product.Id != updatecartitem.ProductId)
                {
                    return(RedirectToRoute("Product", new { SeName = product.GetSeName() }));
                }
            }

            //prepare the model
            var model = _productWebService.PrepareProductDetailsPage(product, updatecartitem, false);

            //product template
            var productTemplateViewPath = _productWebService.PrepareProductTemplateViewPath(product.ProductTemplateId);

            //save as recently viewed
            _recentlyViewedProductsService.AddProductToRecentlyViewedList(customer.Id, product.Id);

            //display "edit" (manage) link
            if (_permissionService.Authorize(StandardPermissionProvider.AccessAdminPanel, customer) &&
                _permissionService.Authorize(StandardPermissionProvider.ManageProducts, customer))
            {
                //a vendor should have access only to his products
                if (_workContext.CurrentVendor == null || _workContext.CurrentVendor.Id == product.VendorId)
                {
                    DisplayEditLink(Url.Action("Edit", "Product", new { id = product.Id, area = "Admin" }));
                }
            }

            //activity log
            _customerActivityService.InsertActivity("PublicStore.ViewProduct", product.Id, _localizationService.GetResource("ActivityLog.PublicStore.ViewProduct"), product.Name);
            _customerActionEventService.Viewed(customer, this.HttpContext.Request.Path.ToString(), this.Request.Headers[HeaderNames.Referer].ToString() != null ? Request.Headers[HeaderNames.Referer].ToString() : "");
            _productService.UpdateMostView(productId, 1);

            return(View(productTemplateViewPath, model));
        }