// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/parcel_tracking/parcel_tracking_util.h"
#import <string>
#import <vector>
#import "base/functional/bind.h"
#import "base/functional/callback_helpers.h"
#import "base/strings/sys_string_conversions.h"
#import "components/commerce/core/commerce_types.h"
#import "components/commerce/core/shopping_service.h"
#import "components/signin/public/base/consent_level.h"
#import "ios/chrome/browser/commerce/model/shopping_service_factory.h"
#import "ios/chrome/browser/ntp/shared/metrics/home_metrics.h"
#import "ios/chrome/browser/parcel_tracking/features.h"
#import "ios/chrome/browser/parcel_tracking/metrics.h"
#import "ios/chrome/browser/parcel_tracking/parcel_tracking_opt_in_status.h"
#import "ios/chrome/browser/parcel_tracking/parcel_tracking_prefs.h"
#import "ios/chrome/browser/shared/model/application_context/application_context.h"
#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
#import "ios/chrome/browser/shared/public/commands/parcel_tracking_opt_in_commands.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
namespace {
const CGFloat parcelLimit = 5;
} // namespace
bool IsUserEligibleParcelTrackingOptInPrompt(
PrefService* pref_service,
commerce::ShoppingService* shopping_service) {
return IsIOSParcelTrackingEnabled() &&
!IsParcelTrackingDisabled(
IsHomeCustomizationEnabled()
? pref_service
: GetApplicationContext()->GetLocalState()) &&
!pref_service->GetBoolean(
prefs::kIosParcelTrackingOptInPromptDisplayLimitMet) &&
shopping_service->IsParcelTrackingEligible();
}
std::vector<std::pair<commerce::ParcelIdentifier::Carrier, std::string>>
ConvertCustomTextCheckingResult(NSArray<CustomTextCheckingResult*>* result) {
std::vector<std::pair<commerce::ParcelIdentifier::Carrier, std::string>>
new_parcel_list;
for (CustomTextCheckingResult* parcel : result) {
commerce::ParcelIdentifier::Carrier carrier =
static_cast<commerce::ParcelIdentifier::Carrier>(parcel.carrier);
std::string tracking_number = base::SysNSStringToUTF8(parcel.carrierNumber);
new_parcel_list.push_back(std::make_pair(carrier, tracking_number));
}
return new_parcel_list;
}
void TrackParcels(
commerce::ShoppingService* shopping_service,
NSArray<CustomTextCheckingResult*>* parcels,
std::string domain,
id<ParcelTrackingOptInCommands> parcel_tracking_commands_handler,
bool display_infobar,
TrackingSource source) {
shopping_service->StartTrackingParcels(
ConvertCustomTextCheckingResult(parcels), domain,
base::BindOnce(
[](bool display_infobar,
id<ParcelTrackingOptInCommands> parcel_tracking_commands_handler,
NSArray<CustomTextCheckingResult*>* parcels, TrackingSource source,
bool success,
std::unique_ptr<std::vector<commerce::ParcelTrackingStatus>>
parcel_status) {
if (success) {
RecordModuleFreshnessSignal(
ContentSuggestionsModuleType::kParcelTracking);
parcel_tracking::RecordParcelsTracked(source, parcels.count);
if (display_infobar) {
[parcel_tracking_commands_handler
showParcelTrackingInfobarWithParcels:parcels
forStep:
ParcelTrackingStep::
kNewPackageTracked];
}
}
},
display_infobar, parcel_tracking_commands_handler, parcels, source));
}
void FilterParcelsAndShowParcelTrackingUI(
commerce::ShoppingService* shopping_service,
NSArray<CustomTextCheckingResult*>* parcels,
id<ParcelTrackingOptInCommands> parcel_tracking_commands_handler) {
shopping_service->GetAllParcelStatuses(base::BindOnce(
[](id<ParcelTrackingOptInCommands> parcel_tracking_commands_handler,
NSArray<CustomTextCheckingResult*>* parcels, bool success,
std::unique_ptr<std::vector<commerce::ParcelTrackingStatus>>
statuses) {
NSMutableSet* parcel_numbers = [NSMutableSet
setWithArray:[parcels valueForKeyPath:@"carrierNumber"]];
// Remove the tracking numbers of already tracked parcels from
// parcel_numbers array.
for (commerce::ParcelTrackingStatus status : *statuses) {
NSString* tracking_id = base::SysUTF8ToNSString(status.tracking_id);
if ([parcel_numbers containsObject:tracking_id]) {
[parcel_numbers removeObject:tracking_id];
}
}
// Add the remaining parcels to filtered_parcels array.
NSMutableArray<CustomTextCheckingResult*>* filtered_parcels =
[[NSMutableArray alloc] init];
for (CustomTextCheckingResult* parcel : parcels) {
if ([parcel_numbers containsObject:parcel.carrierNumber]) {
[filtered_parcels addObject:parcel];
}
}
// Only track or offer to track when number of packages is less than 6.
if (filtered_parcels.count > 0 &&
filtered_parcels.count <= parcelLimit) {
[parcel_tracking_commands_handler
showTrackingForFilteredParcels:filtered_parcels];
}
},
parcel_tracking_commands_handler, parcels));
}