[Shopcard] Link card 1,2, to Magic stack.

Currently does not use ranking.

Tested:
card1: screen/53Ybpp9BVVSoAFK
card2: screen/BmGpAhoJrsymq5F

Change-Id: I91c041c4ee4a3041afbeea0f2154b2ba3ae7b773
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6238754
Commit-Queue: Siddhartha S <ssid@chromium.org>
Reviewed-by: Chris Lu <thegreenfrog@chromium.org>
Reviewed-by: Siddhartha S <ssid@chromium.org>
Auto-Submit: Gloria Fang <gloriafang@google.com>
Reviewed-by: David Maunder <davidjm@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1417581}
NOKEYCHECK=True
GitOrigin-RevId: 4002b5f4e1d49ad05327bf1f56302f376eb32b15
diff --git a/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm b/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
index e040331..23a405e 100644
--- a/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
+++ b/chrome/browser/ui/content_suggestions/content_suggestions_coordinator.mm
@@ -153,6 +153,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_show_more_view_controller.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_tap_delegate.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/utils.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_mediator.h"
 #import "ios/chrome/browser/ui/content_suggestions/tips/tips_magic_stack_mediator.h"
 #import "ios/chrome/browser/ui/content_suggestions/tips/tips_metrics.h"
@@ -274,6 +275,7 @@
   MostVisitedTilesMediator* _mostVisitedTilesMediator;
   TabResumptionMediator* _tabResumptionMediator;
   PriceTrackingPromoMediator* _priceTrackingPromoMediator;
+  ShopCardMediator* _shopCardMediator;
   SendTabPromoMediator* _sendTabPromoMediator;
 
   MagicStackCollectionViewController* _magicStackCollectionView;
@@ -421,6 +423,16 @@
     _priceTrackingPromoMediator.NTPActionsDelegate = self.NTPActionsDelegate;
     [moduleMediators addObject:_priceTrackingPromoMediator];
   }
+  if (base::FeatureList::IsEnabled(commerce::kShopCard) &&
+      (commerce::kShopCardVariation.Get() == commerce::kShopCardArm1 ||
+       commerce::kShopCardVariation.Get() == commerce::kShopCardArm2)) {
+    // If ShopCard experiment is on, create the ShopCard mediator.
+    // Note at this point we don't know which of the 4 variants will show.
+    _shopCardMediator = [[ShopCardMediator alloc]
+        initWithShoppingService:commerce::ShoppingServiceFactory::GetForProfile(
+                                    profile)];
+    [moduleMediators addObject:_shopCardMediator];
+  }
 
   if (IsIOSParcelTrackingEnabled() &&
       !IsParcelTrackingDisabled(
diff --git a/chrome/browser/ui/content_suggestions/magic_stack/BUILD.gn b/chrome/browser/ui/content_suggestions/magic_stack/BUILD.gn
index 2dd4667..2eac570 100644
--- a/chrome/browser/ui/content_suggestions/magic_stack/BUILD.gn
+++ b/chrome/browser/ui/content_suggestions/magic_stack/BUILD.gn
@@ -68,6 +68,7 @@
     "//ios/chrome/browser/ui/content_suggestions/send_tab_to_self",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:utils",
+    "//ios/chrome/browser/ui/content_suggestions/shop_card",
     "//ios/chrome/browser/ui/content_suggestions/tab_resumption",
     "//ios/chrome/browser/ui/content_suggestions/tips",
     "//ui/base",
@@ -149,8 +150,10 @@
     "//ios/chrome/browser/ui/content_suggestions/set_up_list",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:constants",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:utils",
+    "//ios/chrome/browser/ui/content_suggestions/shop_card",
     "//ios/chrome/browser/ui/content_suggestions/shop_card:price_tracking_shop_card",
     "//ios/chrome/browser/ui/content_suggestions/shop_card:shop_card_data",
+    "//ios/chrome/browser/ui/content_suggestions/shop_card:shop_card_data",
     "//ios/chrome/browser/ui/content_suggestions/tab_resumption",
     "//ios/chrome/browser/ui/content_suggestions/tips",
     "//ios/chrome/common/ui/colors",
@@ -267,6 +270,7 @@
     "//ios/chrome/browser/ui/content_suggestions/safety_check",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:utils",
+    "//ios/chrome/browser/ui/content_suggestions/shop_card",
     "//ios/chrome/browser/ui/content_suggestions/shop_card:unit_tests",
     "//ios/chrome/browser/ui/content_suggestions/tab_resumption",
     "//ios/chrome/browser/ui/content_suggestions/tips",
diff --git a/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm b/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm
index 689f751..66588eb 100644
--- a/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm
+++ b/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_container.mm
@@ -26,6 +26,8 @@
 #import "ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_utils.h"
 #import "ios/chrome/browser/ui/content_suggestions/safety_check/safety_check_state.h"
 #import "ios/chrome/browser/ui/content_suggestions/safety_check/utils.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_data.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_item.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
@@ -430,6 +432,17 @@
     case ContentSuggestionsModuleType::kSendTabPromo:
       // Send Tab and Price Tracking Promo design do not use title.
       return @"";
+    case ContentSuggestionsModuleType::kShopCard: {
+      ShopCardItem* shopCardItem = static_cast<ShopCardItem*>(config);
+      if (shopCardItem.shopCardData.shopCardItemType ==
+          ShopCardItemType::kPriceDropForTrackedProducts) {
+        return l10n_util::GetNSString(
+            IDS_IOS_CONTENT_SUGGESTIONS_SHOPCARD_PRICE_TRACKING_TITLE);
+      } else {
+        return l10n_util::GetNSString(
+            IDS_IOS_CONTENT_SUGGESTIONS_SHOPCARD_REVIEWS_TITLE);
+      }
+    }
     case ContentSuggestionsModuleType::kTipsWithProductImage:
     case ContentSuggestionsModuleType::kTips:
       return l10n_util::GetNSString(IDS_IOS_MAGIC_STACK_TIP_TITLE);
diff --git a/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_contents_factory.mm b/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_contents_factory.mm
index edef597..092f1db 100644
--- a/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_contents_factory.mm
+++ b/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_module_contents_factory.mm
@@ -31,7 +31,9 @@
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_mediator.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/utils.h"
 #import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_data.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_price_tracking_view.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_view.h"
 #import "ios/chrome/browser/ui/content_suggestions/standalone_module_view.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_view.h"
@@ -84,6 +86,10 @@
           static_cast<PriceTrackingPromoItem*>(config);
       return [self priceTrackingPromoViewForConfig:item];
     }
+    case ContentSuggestionsModuleType::kShopCard: {
+      ShopCardItem* item = static_cast<ShopCardItem*>(config);
+      return [self shopCardViewForConfig:item];
+    }
     case ContentSuggestionsModuleType::kSendTabPromo: {
       SendTabPromoItem* item = static_cast<SendTabPromoItem*>(config);
       return [self sendTabPromoViewForConfig:item];
@@ -178,6 +184,14 @@
   return view;
 }
 
+- (UIView*)shopCardViewForConfig:(ShopCardItem*)shopCardItem {
+  ShopCardModuleView* view =
+      [[ShopCardModuleView alloc] initWithFrame:CGRectZero];
+  view.commandHandler = shopCardItem.commandHandler;
+  [view configureView:shopCardItem];
+  return view;
+}
+
 - (UIView*)safetyCheckViewForConfigState:(SafetyCheckState*)state
                      contentViewDelegate:
                          (id<MagicStackModuleContentViewDelegate>)
diff --git a/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm b/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm
index 780f03b..79cb1d4 100644
--- a/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm
+++ b/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm
@@ -69,6 +69,8 @@
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_view_data.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_mediator.h"
 #import "ios/chrome/browser/ui/content_suggestions/set_up_list/utils.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_item.h"
+#import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_helper_delegate.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/tab_resumption/tab_resumption_mediator.h"
@@ -90,6 +92,7 @@
                                       PriceTrackingPromoMediatorDelegate,
                                       SafetyCheckMagicStackMediatorDelegate,
                                       SendTabPromoMediatorDelegate,
+                                      ShopCardMediatorDelegate,
                                       SetUpListMediatorAudience,
                                       ShortcutsMediatorDelegate,
                                       TabResumptionHelperDelegate,
@@ -120,6 +123,7 @@
   TabResumptionMediator* _tabResumptionMediator;
   ParcelTrackingMediator* _parcelTrackingMediator;
   PriceTrackingPromoMediator* _priceTrackingPromoMediator;
+  ShopCardMediator* _shopCardMediator;
   ShortcutsMediator* _shortcutsMediator;
   SafetyCheckMagicStackMediator* _safetyCheckMediator;
   SendTabPromoMediator* _sendTabPromoMediator;
@@ -166,6 +170,9 @@
       } else if ([mediator isKindOfClass:[TabResumptionMediator class]]) {
         _tabResumptionMediator = static_cast<TabResumptionMediator*>(mediator);
         _tabResumptionMediator.delegate = self;
+      } else if ([mediator isKindOfClass:[ShopCardMediator class]]) {
+        _shopCardMediator = static_cast<ShopCardMediator*>(mediator);
+        _shopCardMediator.delegate = self;
       } else if ([mediator isKindOfClass:[ShortcutsMediator class]]) {
         _shortcutsMediator = static_cast<ShortcutsMediator*>(mediator);
         _shortcutsMediator.delegate = self;
@@ -206,6 +213,7 @@
   _shortcutsMediator = nil;
   _safetyCheckMediator = nil;
   _sendTabPromoMediator = nil;
+  _shopCardMediator = nil;
   _tipsMediator = nil;
   _tipsManager = nil;
 }
@@ -631,6 +639,13 @@
                          withCompletion:nil];
 }
 
+- (void)removeShopCard {
+  [self.delegate magicStackRankingModel:self
+                          didRemoveItem:_shopCardMediator.shopCardItemToShow
+                                animate:YES
+                         withCompletion:nil];
+}
+
 // Starts a fetch of the Segmentation module ranking.
 - (void)fetchMagicStackModuleRankingFromSegmentationPlatform {
   if (!base::FeatureList::IsEnabled(segmentation_platform::features::
@@ -749,8 +764,12 @@
     } else if (label == segmentation_platform::kPriceTrackingPromo) {
       [magicStackOrder
           addObject:@(int(ContentSuggestionsModuleType::kPriceTrackingPromo))];
+    } else if (label == segmentation_platform::kShopCard) {
+      [magicStackOrder
+          addObject:@(int(ContentSuggestionsModuleType::kShopCard))];
     }
   }
+
   _magicStackOrderFromSegmentationReceived = YES;
   _magicStackOrderFromSegmentation = magicStackOrder;
   _latestMagicStackConfigOrder = [self latestMagicStackConfigRank];
@@ -871,6 +890,11 @@
       case ContentSuggestionsModuleType::kShortcuts:
         [magicStackOrder addObject:_shortcutsMediator.shortcutsConfig];
         break;
+      case ContentSuggestionsModuleType::kShopCard:
+        if (_shopCardMediator && _shopCardMediator.shopCardItemToShow) {
+          [magicStackOrder addObject:_shopCardMediator.shopCardItemToShow];
+        }
+        break;
       case ContentSuggestionsModuleType::kParcelTracking:
         if (IsIOSParcelTrackingEnabled() &&
             !IsParcelTrackingDisabled(
diff --git a/chrome/browser/ui/content_suggestions/shop_card/BUILD.gn b/chrome/browser/ui/content_suggestions/shop_card/BUILD.gn
index a981ff7..32ea839 100644
--- a/chrome/browser/ui/content_suggestions/shop_card/BUILD.gn
+++ b/chrome/browser/ui/content_suggestions/shop_card/BUILD.gn
@@ -12,6 +12,7 @@
     ":price_tracking_shop_card",
     ":shop_card_data",
     "//base:base",
+    "//components/commerce/core:feature_list",
     "//ios/chrome/browser/ui/content_suggestions:constants",
     "//ios/chrome/browser/ui/content_suggestions/magic_stack:public",
   ]
diff --git a/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.mm b/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.mm
index 90ddd90..aca7a6b 100644
--- a/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.mm
+++ b/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_mediator.h"
 
 #import "base/memory/raw_ptr.h"
+#import "components/commerce/core/commerce_feature_list.h"
 #import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_data.h"
 #import "ios/chrome/browser/ui/content_suggestions/shop_card/shop_card_item.h"
 
@@ -39,15 +40,15 @@
 
 - (void)fetchLatestShopCardItem {
   // Populate the item if it is not already initialized.
-  // This is a placeholder and may get replaced when we fetch actual data.
-  if (self->_shopCardItem.shopCardData) {
-    return;
-  }
   _shopCardItem = [[ShopCardItem alloc] init];
   _shopCardItem.shopCardData = [[ShopCardData alloc] init];
-  // TODO: crbug.com/394638800 - set this to the correct type based on
-  // experiment.
-  _shopCardItem.shopCardData.shopCardItemType = ShopCardItemType::kUnknown;
+
+  if (commerce::kShopCardVariation.Get() == commerce::kShopCardArm1) {
+    _shopCardItem.shopCardData.shopCardItemType =
+        ShopCardItemType::kPriceDropForTrackedProducts;
+  } else if (commerce::kShopCardVariation.Get() == commerce::kShopCardArm2) {
+    _shopCardItem.shopCardData.shopCardItemType = ShopCardItemType::kReviews;
+  }
 }
 
 - (ShopCardItem*)shopCardItemToShow {
diff --git a/chrome/browser/ui/content_suggestions/shop_card/shop_card_view.mm b/chrome/browser/ui/content_suggestions/shop_card/shop_card_view.mm
index 120c0ef..e3f91c0 100644
--- a/chrome/browser/ui/content_suggestions/shop_card/shop_card_view.mm
+++ b/chrome/browser/ui/content_suggestions/shop_card/shop_card_view.mm
@@ -17,7 +17,7 @@
 
 - (void)configureView:(ShopCardItem*)config {
   if (config.shopCardData.shopCardItemType ==
-      ShopCardItemType::kPriceDropOnTab) {
+      ShopCardItemType::kPriceDropForTrackedProducts) {
     // TODO: crbug.com/394638800 - render correct view when data available
   } else if (config.shopCardData.shopCardItemType ==
              ShopCardItemType::kReviews) {