public async Task <IActionResult> Update(long id, ProductViewModel productVM)
        {
            if (id != productVM.Product.Id)
            {
                return(BadRequest());
            }

            var productFromDb = await _context.Products.AsNoTracking().FirstOrDefaultAsync(p => p.Id == id);

            if (productFromDb == null)
            {
                return(NotFound());
            }

            try
            {
                var currentProductCategoryMapping = await _context.ProductCategories.Include(x => x.Category)
                                                    .Where(x => x.ProductId == productVM.Product.Id)
                                                    .ToListAsync();

                var productAuditTrail = new ProductAuditTrail
                {
                    ProductId     = productVM.Product.Id,
                    Name          = productVM.Product.Name,
                    Description   = productVM.Product.Description,
                    Price         = productVM.Product.Price,
                    ImageUrl      = productVM.Product.ImageUrl,
                    IsAvailable   = productVM.Product.IsAvailable,
                    Categories    = string.Join(",", currentProductCategoryMapping.Select(x => x.Category.Name).ToList()),
                    ActionTypeId  = (long)SD.EntityActionType.Update,
                    PerformedBy   = productVM.Product.UpdatedBy,
                    PerformedDate = productVM.Product.UpdatedAt
                };
                _context.ProductCategories.RemoveRange(currentProductCategoryMapping);
                _context.ProductAuditTrails.Add(productAuditTrail);

                foreach (var categoryId in productVM.CategoryIds)
                {
                    await _context.ProductCategories.AddAsync(new ProductCategory
                    {
                        ProductId  = productVM.Product.Id,
                        CategoryId = categoryId
                    });
                }

                _context.Entry(productVM.Product).State = EntityState.Modified;
                await _context.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error occurred while updating product {@ProductVM} in database", productVM);
                return(StatusCode(Convert.ToInt32(HttpStatusCode.InternalServerError)));
            }

            return(NoContent());
        }
        public async Task <IActionResult> Delete(long id, string userId)
        {
            Product product = await _context.Products.FindAsync(id);

            if (product == null)
            {
                _logger.LogWarning("Attempt to delete non-existing product of ID {ProductId}", id);
                return(NotFound());
            }

            try
            {
                var currentProductCategoryMapping = await _context.ProductCategories.Include(x => x.Category)
                                                    .Where(x => x.ProductId == product.Id)
                                                    .ToListAsync();

                var productAuditTrail = new ProductAuditTrail
                {
                    ProductId     = product.Id,
                    Name          = product.Name,
                    Description   = product.Description,
                    Price         = product.Price,
                    ImageUrl      = product.ImageUrl,
                    IsAvailable   = product.IsAvailable,
                    Categories    = string.Join(",", currentProductCategoryMapping.Select(x => x.Category.Name).ToList()),
                    ActionTypeId  = (long)SD.EntityActionType.Delete,
                    PerformedBy   = userId,
                    PerformedDate = DateTime.Now
                };
                _context.ProductAuditTrails.Add(productAuditTrail);

                product.IsAvailable = !product.IsAvailable; // Just mark it instead of deleting it
                _context.Products.Update(product);
                await _context.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error occurred while changing product {@Product} availability in database", product);
                return(StatusCode(Convert.ToInt32(HttpStatusCode.InternalServerError)));
            }

            return(NoContent());
        }