import * as models from "../../../api/models";
import * as serverData from "../../../foundation/json-parsing/server-data";
import * as mediaAttributes from "../../../foundation/media/attributes";
import * as mediaDataStructure from "../../../foundation/media/data-structure";
import * as mediaRelationship from "../../../foundation/media/relationships";
import * as adIncidents from "../../ads/ad-incident-recorder";
import * as adStitch from "../../ads/ad-stitcher";
import { searchLandingPagePositionInfo } from "../../ads/on-device-ad-stitch";
import * as mediaUrlMapping from "../../builders/url-mapping";
import * as videoDefaults from "../../constants/video-constants";
import * as content from "../../content/content";
import { CollectionShelfDisplayStyle } from "../../editorial-pages/editorial-page-types";
import * as filtering from "../../filtering";
import * as adLockups from "../../lockups/ad-lockups";
import * as lockupsEditorialContext from "../../lockups/editorial-context";
import * as lockups from "../../lockups/lockups";
import * as metricsHelpersClicks from "../../metrics/helpers/clicks";
import * as metricsHelpersLocation from "../../metrics/helpers/location";
import * as placeholders from "../../placeholders/placeholders";
import * as room from "../../room/room-common";
import * as topChartsCommon from "../../top-charts-common";
import * as pageCommon from "../../util/page-common";
import * as groupingTypes from "../grouping-types";
import * as groupingShelfControllerCommon from "./grouping-shelf-controller-common";
import * as color from "../../../foundation/util/color-util";
import { pageRouter } from "../../builders/routing";
import { isNothing, isSome } from "@jet/environment/types/optional";
import * as modelsBase from "../../../api/models/base";
import * as metricsLocation from "../../../common/metrics/helpers/location";
import { makeGameCenterHeader, openGamesUIAction } from "../../arcade/arcade-common";
import { makeRoomPageIntent } from "../../../api/intents/room-page-intent";
import { makeChartsPageIntent } from "../../../api/intents/charts-page-intent";
import { makeChartsPageURL } from "../../../common/charts/charts-page-url";
import { getLocale } from "../../locale";
import { getPlatform } from "../../preview-platform";
import { genreIdFromChartURL } from "../../../common/grouping/render-grouping-page";
import { injectCrossfireFlowForGameCenter } from "./grouping-game-center-popular-with-your-friends-shelf-controller";
/**
 * Determine the shelfContentType to use for a shelf given the shelf token
 * @param objectGraph
 * @param mediaApiData
 * @param shelfToken
 * @param groupingParseContext
 */
export function shelfContentType(objectGraph, mediaApiData, shelfToken, groupingParseContext) {
    const featuredContentId = shelfToken.featuredContentId;
    if (featuredContentId === 557 /* groupingTypes.FeaturedContentID.AppStore_CategoryBreakoutMarker */ ||
        featuredContentId === 418 /* groupingTypes.FeaturedContentID.AppStore_Shelf */ ||
        featuredContentId === 495 /* groupingTypes.FeaturedContentID.AppStore_PopularWithYourFriendsMarker */ ||
        groupingTypes.isRecommendationsLockupShelf(featuredContentId)) {
        let displayStyle = mediaAttributes.attributeAsString(mediaApiData, "displayStyle");
        if (!displayStyle) {
            if (featuredContentId === 311 /* groupingTypes.FeaturedContentID.Sundance_RecommendedAppsShelf */ ||
                featuredContentId === 312 /* groupingTypes.FeaturedContentID.Sundance_RecommendedGamesShelf */) {
                displayStyle = "large";
            }
            else if (featuredContentId === 495 /* groupingTypes.FeaturedContentID.AppStore_PopularWithYourFriendsMarker */ ||
                featuredContentId === 557 /* groupingTypes.FeaturedContentID.AppStore_CategoryBreakoutMarker */) {
                displayStyle = "medium";
            }
            else {
                displayStyle = "small";
            }
        }
        return `${displayStyle}Lockup`;
    }
    else if (featuredContentId === 431 /* groupingTypes.FeaturedContentID.AppStore_iAPShelf */) {
        return "inAppPurchaseTiledLockup";
    }
    else if (featuredContentId === 429 /* groupingTypes.FeaturedContentID.AppStore_ScreenShotShelf */) {
        return "screenshotsLockup";
    }
    else if (featuredContentId === 304 /* groupingTypes.FeaturedContentID.Sundance_iPhoneAppTrailerShelf */ ||
        featuredContentId === 305 /* groupingTypes.FeaturedContentID.Sundance_iPadAppTrailerShelf */ ||
        featuredContentId === 430 /* groupingTypes.FeaturedContentID.AppStore_VideoShelf */ ||
        featuredContentId === 420 /* groupingTypes.FeaturedContentID.AppStore_TrailerShelf */) {
        return "appTrailerLockup";
    }
    else if (groupingTypes.isTopChart(featuredContentId)) {
        return "smallLockup";
    }
    else if (featuredContentId === 497 /* groupingTypes.FeaturedContentID.AppStore_ComingSoon */) {
        return "posterLockup";
    }
    else {
        switch (groupingParseContext.shelves.length % 3) {
            case 0: {
                return "smallLockup";
            }
            case 1: {
                return "mediumLockup";
            }
            default: {
                return "largeLockup";
            }
        }
    }
}
// region Shelf Token
export function lockupShelfTokenFromBaseTokenAndMediaApiData(objectGraph, mediaApiData, baseShelfToken, groupingParseContext) {
    const lockupShelfToken = {
        ...baseShelfToken,
        shouldFilter: !mediaAttributes.attributeAsBooleanOrFalse(mediaApiData, "doNotFilter"),
        chartUrl: mediaAttributes.attributeAsString(mediaApiData, "chartHref"),
        chartIdentifier: mediaAttributes.attributeAsString(mediaApiData, "chart"),
        roomRelationshipData: mediaRelationship.relationshipData(objectGraph, mediaApiData, "room"),
    };
    if (groupingTypes.isTopChart(lockupShelfToken.featuredContentId)) {
        lockupShelfToken.seeAllUrl = topChartsCommon.makeSeeAllUrlFromMediaApiData(objectGraph, mediaApiData, // chart shelf data includes selected chart
        groupingParseContext.chartSet);
        lockupShelfToken.showOrdinals = true;
        lockupShelfToken.shouldFilter = false;
    }
    else if (serverData.isDefinedNonNullNonEmpty(lockupShelfToken.roomRelationshipData)) {
        lockupShelfToken.seeAllUrl = mediaUrlMapping.hrefToRoutableUrl(objectGraph, lockupShelfToken.roomRelationshipData.href);
    }
    lockupShelfToken.shelfStyle = shelfContentType(objectGraph, mediaApiData, lockupShelfToken, groupingParseContext);
    lockupShelfToken.clientIdentifierOverride = lockupsEditorialContext.clientIdentifierForEditorialContextInData(objectGraph, mediaApiData);
    return lockupShelfToken;
}
// endregion
// region Shelf Creation
/**
 *
 * @param objectGraph The App Store dependency graph
 * @param shelfToken The shelf shelfToken for this current shelf creation request
 * @param shelfData The media api shelfContents array for this shelf
 * @param groupingParseContext The parse context used to generate the grouping page on the initial page load,
 * this will be missing when this controller renders a secondary or incomplete shelf fetch.
 */
export function createLockupShelf(objectGraph, shelfToken, shelfData, groupingParseContext) {
    const filterType = groupingTypes.isMacTopChart(shelfToken.featuredContentId)
        ? 84862 /* filtering.Filter.ChartsMac */
        : 80894 /* filtering.Filter.All */;
    let items = [];
    // Stitch First Position Ad (only if lockup array is nonempty)
    if (serverData.isDefinedNonNullNonEmpty(shelfData.shelfContents)) {
        const adLockup = lockupFromAdStitcher(objectGraph, groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.adStitcher, groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.adIncidentRecorder, searchLandingPagePositionInfo, shelfToken);
        if (adLockup && adLockup instanceof models.Lockup) {
            items.push(adLockup);
            metricsHelpersLocation.nextPosition(shelfToken.metricsLocationTracker);
            shelfToken.ordinalIndex++;
            shelfData.shelfContents = shelfData.shelfContents.filter((data) => data.id !== adLockup.adamId); // Filter dupe
        }
    }
    // Data to use for `seeAllContents` in Category Breakout shelf
    let seeAllContents;
    // Build Lockups
    for (const lockupData of shelfData.shelfContents) {
        // If we encounter a type of app-events, this means they have been incorrectly programmed,
        // and we should throw the shelf away.
        if (lockupData.type === "app-events") {
            return null;
        }
        // If we encounter a type of `editorial-items` in
        // Category Breakout shelf, it is to use for `seeAllContents`.
        if (shelfToken.featuredContentId === 557 /* groupingTypes.FeaturedContentID.AppStore_CategoryBreakoutMarker */ &&
            lockupData.type === "editorial-items") {
            seeAllContents = lockupData;
            continue;
        }
        if (serverData.isNull(lockupData.attributes) || groupingShelfControllerCommon.shouldDefer(shelfToken)) {
            shelfToken.isDeferring = true;
            shelfToken.remainingItems.push(lockupData);
            continue;
        }
        // Filter out unwanted content
        if (filtering.shouldFilter(objectGraph, lockupData, filterType)) {
            continue;
        }
        const lockup = lockupFromData(objectGraph, lockupData, shelfToken);
        if (lockup) {
            items.push(lockup);
            metricsHelpersLocation.nextPosition(shelfToken.metricsLocationTracker);
            shelfToken.ordinalIndex++;
        }
    }
    // Truncate non-Arcade top charts to multiples of 3
    if (groupingTypes.isTopChart(shelfToken.featuredContentId) &&
        !groupingTypes.isArcadeTopChart(shelfToken.featuredContentId) &&
        !groupingTypes.isGameCenterTopChart(shelfToken.featuredContentId) &&
        !objectGraph.client.isMac) {
        items = pageCommon.truncateItems(items, 3);
    }
    // We don't need this in our incomplete shelf URL, so we'll preemptively remove it.
    delete shelfToken.maxItemCount;
    // Create shelf header
    let shelfHeader;
    if (groupingTypes.isGameCenterTopChart(shelfToken.featuredContentId)) {
        // Show Game Center eyebrow for Game Center top chart shelves
        shelfHeader = makeGameCenterHeader(objectGraph, shelfToken.title);
    }
    else {
        shelfHeader = {
            eyebrow: shelfToken.eyebrow,
            eyebrowArtwork: shelfToken.eyebrowArtwork,
            title: shelfToken.title,
            titleArtwork: shelfToken.titleArtwork,
            subtitle: shelfToken.subtitle,
            configuration: shelfToken.shelfHeaderConfiguration,
        };
    }
    // Create shelf
    const shelf = new models.Shelf(shelfToken.shelfStyle);
    shelf.isHorizontal = true;
    shelf.items = items;
    shelf.shouldFilterApps = shelfToken.shouldFilter;
    if (groupingTypes.isGameCenterTopChart(shelfToken.featuredContentId)) {
        shelf.footerTitle = objectGraph.loc.string("Lockup.Footer.GamesApp");
        shelf.footerAction = openGamesUIAction(objectGraph);
        shelf.footerStyle = {
            $kind: "games",
            bundleID: "com.apple.games",
            width: 16,
            height: 16,
        };
        shelf.items.forEach((lockup, index) => {
            if (isSome(lockup) && lockup instanceof models.Lockup) {
                lockup.clickAction = injectCrossfireFlowForGameCenter(objectGraph, lockup.clickAction);
            }
        });
    }
    if (shelfToken.featuredContentId === 557 /* groupingTypes.FeaturedContentID.AppStore_CategoryBreakoutMarker */) {
        // Configure Category Breakout shelf
        configureCategoryBreakoutShelf(objectGraph, shelfToken, shelf, shelfHeader, items, seeAllContents, groupingParseContext);
    }
    else if (!objectGraph.props.enabled("redownloadButtonTintUsingOfferTheme")) {
        shelf.items.forEach((lockup, index) => {
            if (isSome(lockup) && lockup instanceof models.Lockup) {
                lockup.redownloadButtonTint = color.named("systemBlue");
            }
        });
    }
    // If no items should we display placeholders for this shelf?
    const willHydrateShelfLater = shelf && serverData.isNullOrEmpty(shelf.items) && shelfToken.isFirstRender;
    if (willHydrateShelfLater && placeholders.placeholdersEnabled(objectGraph)) {
        placeholders.insertPlaceholdersIntoGenericPageShelf(objectGraph, shelf, shelfToken, shelfToken.featuredContentId);
    }
    // Create the action
    let action;
    if (groupingTypes.isTopChart(shelfToken.featuredContentId)) {
        action = new models.FlowAction("topCharts");
    }
    else {
        action = new models.FlowAction("page");
        // The web client makes a separate request for See All pages, so we don't sidepack for web.
        if (!placeholders.isPlaceholderShelf(shelf) && !objectGraph.client.isWeb) {
            // Create the sidepacked room page
            const preferredShelfStyle = preferredRoomSeeAllShelfStyle(objectGraph, shelfToken.shelfStyle);
            action.pageData = room.seeAllPage(objectGraph, shelfToken.title, preferredShelfStyle);
        }
    }
    if (objectGraph.client.isWeb) {
        if (groupingTypes.isTopChart(shelfToken.featuredContentId)) {
            const genre = (shelfToken.seeAllUrl && genreIdFromChartURL(shelfToken.seeAllUrl)) || shelfToken.pageGenreId || "";
            const destination = makeChartsPageIntent({
                ...getLocale(objectGraph),
                ...getPlatform(objectGraph),
                chart: shelfToken.chartIdentifier,
                genreId: genre.toString(),
            });
            action.destination = destination;
            action.pageUrl = makeChartsPageURL(objectGraph, destination);
        }
        else {
            const destination = makeRoomPageIntent({
                ...getLocale(objectGraph),
                ...getPlatform(objectGraph),
                id: shelfToken.id,
            });
            action.destination = destination;
            action.pageUrl = room.makeCanonicalRoomPageUrl(objectGraph, destination);
        }
    }
    else {
        action.pageUrl = shelfToken.seeAllUrl;
    }
    action.title = objectGraph.loc.string("ACTION_SEE_ALL");
    action.referrerUrl = shelfToken.metricsPageInformation.pageUrl;
    metricsHelpersClicks.addClickEventToSeeAllAction(objectGraph, action, shelfToken.seeAllUrl, {
        pageInformation: shelfToken.metricsPageInformation,
        locationTracker: shelfToken.metricsLocationTracker,
    });
    const shouldIncludeSeeAllAction = shouldShowSeeAll(objectGraph, shelf.items, shelfToken);
    const seeAllActionIsValid = serverData.isDefinedNonNull(action.pageUrl) || serverData.isDefinedNonNull(action.pageData);
    if (shouldIncludeSeeAllAction && seeAllActionIsValid) {
        groupingShelfControllerCommon.replaceShelfHeaderSeeAllAction(objectGraph, shelfHeader, action);
    }
    if (shelfToken.shelfStyle === "screenshotsLockup" || shelfToken.shelfStyle === "appTrailerLockup") {
        // `suppressTagline` is passed from MediaAPI as a string (see rdar://89933411)
        const shouldShowSupplementaryText = mediaAttributes.attributeAsString(shelfToken.featuredContentData, "suppressTagline") !== "true";
        if (serverData.isNull(shelf.presentationHints)) {
            shelf.presentationHints = { showSupplementaryText: shouldShowSupplementaryText };
        }
        else {
            shelf.presentationHints = {
                ...shelf.presentationHints,
                showSupplementaryText: shouldShowSupplementaryText,
            };
        }
    }
    // On macOS, posters should take up the full width unless the shelf has enough items.
    if (shelfToken.shelfStyle === "posterLockup" && objectGraph.client.isMac && shelf.items.length < 3) {
        if (serverData.isNull(shelf.presentationHints)) {
            shelf.presentationHints = { isLowDensity: true };
        }
        else {
            shelf.presentationHints = { ...shelf.presentationHints, isLowDensity: true };
        }
    }
    shelf.header = shelfHeader;
    shelf.url = groupingShelfControllerCommon.createShelfTokenUrlIfNecessaryForShelf(objectGraph, shelf, shelfToken);
    return shelf;
}
// endregion
// region Lockup Creation
/**
 * Create a lockup for shelfContents to display within a grouping shelf
 * @param objectGraph
 * @param lockupData shelfContents to create lockup for.
 * @param shelfToken Shelf shelfToken
 */
export function lockupFromData(objectGraph, lockupData, shelfToken) {
    if (serverData.isNullOrEmpty(lockupData)) {
        return null;
    }
    // Set the ordinal
    let ordinalString;
    if (shelfToken.showOrdinals) {
        ordinalString = objectGraph.loc.decimal(shelfToken.ordinalIndex);
    }
    let offerStyle = null;
    if (serverData.isDefinedNonNull(shelfToken.shelfBackground) &&
        (shelfToken.shelfBackground.type === "color" || shelfToken.shelfBackground.type === "interactive")) {
        offerStyle = "white";
    }
    let clientIdentifierOverride;
    if (serverData.isDefinedNonNullNonEmpty(shelfToken)) {
        clientIdentifierOverride = shelfToken.clientIdentifierOverride;
    }
    // Create the lockup
    const lockupOptions = {
        ordinal: ordinalString,
        metricsOptions: {
            pageInformation: shelfToken.metricsPageInformation,
            locationTracker: shelfToken.metricsLocationTracker,
            recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(lockupData),
            isAdvert: adLockups.isAdvert(objectGraph, lockupData),
        },
        clientIdentifierOverride: clientIdentifierOverride,
        artworkUseCase: content.artworkUseCaseFromShelfStyle(objectGraph, shelfToken.shelfStyle),
        offerStyle: offerStyle,
        canDisplayArcadeOfferButton: content.shelfContentTypeCanDisplayArcadeOfferButtons(objectGraph, shelfToken.shelfStyle),
        isContainedInPreorderExclusiveShelf: shelfToken.featuredContentId === 497 /* groupingTypes.FeaturedContentID.AppStore_ComingSoon */,
        shouldHideArcadeHeader: objectGraph.featureFlags.isEnabled("hide_arcade_header_on_arcade_tab") && shelfToken.isArcadePage,
    };
    let lockup;
    switch (shelfToken.shelfStyle) {
        case "appTrailerLockup":
            lockup = lockups.trailersLockupFromData(objectGraph, lockupData, lockupOptions, videoDefaults.defaultVideoConfiguration(objectGraph));
            break;
        case "screenshotsLockup":
            lockup = lockups.screenshotsLockupFromData(objectGraph, lockupData, lockupOptions);
            break;
        case "posterLockup":
            lockup = lockups.posterLockupFromData(objectGraph, lockupData, lockupOptions);
            break;
        case "inAppPurchaseLockup":
        case "inAppPurchaseTiledLockup":
            lockup = lockups.inAppPurchaseLockupFromData(objectGraph, lockupData, lockupOptions);
            break;
        case "smallImageLockup":
        case "mediumImageLockup":
        case "largeImageLockup":
            lockup = lockups.imageLockupFromData(objectGraph, lockupData, lockupOptions, CollectionShelfDisplayStyle.EditorialLockupLarge);
            break;
        default:
            lockup = lockups.lockupFromData(objectGraph, lockupData, lockupOptions);
    }
    if (serverData.isNull(lockup) || !lockup.isValid()) {
        return null;
    }
    return lockup;
}
// endregion
// region See All
/**
 * Determine whether lockup shelves should show "See All" on given platforms.
 * This covers both top charts shelves and lockup shelves.
 * Special care should be taken to not make assumptions about the hydration state of the lockup shelves.
 *
 * @param objectGraph The App Store object graph.
 * @param readyItems Items that will be vended as part of `shelf.items` in this shelf. This may be subset of items in shelf following subsequent fetch.
 * @param shelfToken Grouping shelf shelfToken for shelf. This is used for determining whether shelf is part of initial page render, and to check whether there are more items to load.
 * @return Whether or not a lockup shelf with given properties should have a "See All" action.
 */
export function shouldShowSeeAll(objectGraph, readyItems, shelfToken) {
    // We do not want to attach "See All" if the grouping type is a Category Breakout Marker.
    if (shelfToken.featuredContentId === 557 /* groupingTypes.FeaturedContentID.AppStore_CategoryBreakoutMarker */) {
        return false;
    }
    // We do not want to attach "See All" if the grouping type is one of the Arcade Top Chart types
    if (groupingTypes.isArcadeTopChart(shelfToken.featuredContentId)) {
        return false;
    }
    // We do not want to attach "See All" if the grouping type is one of the Game Center Top Chart types
    if (groupingTypes.isGameCenterTopChart(shelfToken.featuredContentId)) {
        return false;
    }
    // On tvOS, "See All" is exposed as a clickable cell in-line with lockup cells. We want to show "See All" cells for:
    //      1. Shelf that have completed loading, i.e. don't have `shelfToken.remainingItems`.
    //      2. Lockup shelves that have *a lot* of content, which we clip within grouping shelves and show in full only in in the "See All" page.
    //
    // *Note* that we are *NOT* showing "See All" for shelves that have a "See All" url configured on tvOS.
    // It appears that every shelf has a "See All" url, and that url returns the exact same contents as contents of shelf's `contents.data` as part of initial page fetch causing this:
    //      <rdar://problem/50230334> RFW4: Grouping: Shelves shouldn't have see all unless there's more to show.
    //
    // It appears we don't have capability to know in advance whether "See All" url has more to show than what is part of `contents.data` in initial page fetch.
    // In our experiments, it looks like they are always the same. If this changes, we'd also want:
    //          const hasSeeAllRoom = shelfToken.seeAllUrl?.length > 0;
    //          if (hasSeeAllRoom) {
    //              return true;
    //          }
    //
    // In it's current form, we don't do (2), since we don't limit the number of lockups in a shelf we display within groupings. That is tracked under:
    //      <rdar://problem/50671635> Grouping: Limit number of items in shelves
    if (objectGraph.client.isTV) {
        // Whether or not this shelf is a partially hydrated shelf. This means there should be a secondary fetch request which causes the shelf will grow.
        // We'll opt to *NEVER* show "See All" if the shelf will grow, and tack it on in the secondary shelf fetch.
        const willHaveSubsequentFetch = serverData.isDefinedNonNullNonEmpty(shelfToken.remainingItems);
        if (willHaveSubsequentFetch) {
            return false;
        }
        // Whether or not this shelf is a nonempty top charts.
        const isNonemptyTopCharts = groupingTypes.isTopChart(shelfToken.featuredContentId) && serverData.isDefinedNonNullNonEmpty(readyItems);
        if (isNonemptyTopCharts) {
            return true;
        }
        // Otherwise, don't show "See All" on tvOS.
        return false;
    }
    // On all other platforms, we always to attach "See All", except AppStore_ComingSoon,
    // which should not because the see all page won't drop lockups whose pre-order has
    // been released (which the AppStore_ComingSoon swoosh will).
    return shelfToken.featuredContentId !== 497 /* groupingTypes.FeaturedContentID.AppStore_ComingSoon */;
}
/**
 * Coerces the provided shelf content type into a type suitable for use in a 'See All' room.
 * @param objectGraph
 * @param originalShelfStyle The content type that defines the 'See All' parent.
 * @returns {models.ShelfContentType} The content type to use for the 'See All' room. Returns `null` if there is no
 * preference, at which point the room builder will provide its default.
 */
export function preferredRoomSeeAllShelfStyle(objectGraph, originalShelfStyle) {
    if (!originalShelfStyle) {
        return null;
    }
    switch (originalShelfStyle) {
        case "inAppPurchaseLockup":
        case "inAppPurchaseTiledLockup":
            return originalShelfStyle;
        default:
            return null;
    }
}
// endregion
// region Category Breakout
export function configureCategoryBreakoutShelf(objectGraph, shelfToken, shelf, shelfHeader, items, seeAllContents, groupingParseContext) {
    // If `seeAllContents` is not hydrated, fetch it from the relationship data.
    if (isNothing(seeAllContents)) {
        seeAllContents = mediaRelationship.relationshipData(objectGraph, shelfToken.featuredContentData, "see-all-contents");
    }
    // Trailing artwork
    shelfHeader.configuration.includeTrailingArtwork = true;
    // If `seeAllContents` is sparse, add it to the remaining items to hydrate.
    if (!mediaAttributes.hasAttributes(seeAllContents)) {
        const badge = mediaAttributes.attributeAsString(shelfToken.featuredContentData, "name");
        shelfHeader.eyebrow = badge;
        shelfHeader.title = "";
        shelf.footerTitle = "";
        shelfToken.isDeferring = true;
        shelfToken.remainingItems.push(seeAllContents);
        return;
    }
    // Badge
    const badge = mediaAttributes.attributeAsString(shelfToken.featuredContentData, "name");
    shelfHeader.eyebrow = badge;
    // Title
    const editorialNotes = mediaAttributes.attributeAsDictionary(seeAllContents, "editorialNotes");
    const title = serverData.asString(editorialNotes, "name");
    shelfHeader.title = title;
    // Configure location name to the updated title
    metricsLocation.currentLocation(shelfToken.metricsLocationTracker).name = title;
    // Configure impression name to the updated title if placeholder shelf used
    if (serverData.isDefinedNonNullNonEmpty(shelfToken.originalPlaceholderShelfImpressionMetrics)) {
        shelfToken.originalPlaceholderShelfImpressionMetrics.fields.name = title;
    }
    // Artwork
    const editorialArtwork = mediaAttributes.attributeAsDictionary(seeAllContents, "editorialArtwork");
    // Drop the shelf if there is no editorial artwork.
    if (isNothing(editorialArtwork)) {
        shelf.isHidden = true;
        return;
    }
    // Background artwork
    const backgroundArtworkDict = serverData.asDictionary(editorialArtwork, "storyBackgroundStatic16x9");
    const backgroundArtworkOptions = {
        useCase: 28 /* content.ArtworkUseCase.CategoryBreakoutShelf */,
        withJoeColorPlaceholder: true,
    };
    const backgroundArtwork = groupingShelfControllerCommon.groupingArtworkFromApiArtwork(objectGraph, backgroundArtworkDict, backgroundArtworkOptions);
    const backgroundStyle = color.isDarkColor(backgroundArtwork.backgroundColor) ? "dark" : "light";
    shelf.background = {
        type: "artwork",
        artwork: backgroundArtwork,
        style: backgroundStyle,
    };
    // Lockup offerDisplayProperties
    items.forEach((lockup, index) => {
        if (isSome(lockup) && lockup instanceof models.Lockup) {
            lockup.offerDisplayProperties = lockup.offerDisplayProperties.newOfferDisplayPropertiesChangingAppearance(false, "transparent", backgroundStyle);
            lockup.subtitleTextFilter = "plusLight";
            if (!objectGraph.props.enabled("redownloadButtonTintUsingOfferTheme")) {
                lockup.redownloadButtonTint = color.named("white");
            }
        }
    });
    // Trailing artwork
    const trailingArtworkDict = serverData.asDictionary(editorialArtwork, "contentGraphicTrimmed");
    // Drop the shelf if there is no trailing artwork.
    if (isNothing(trailingArtworkDict)) {
        shelf.isHidden = true;
        return;
    }
    const trailingArtworkOptions = {
        contentMode: modelsBase.ArtworkContentMode.scaleAspectFit,
        useCase: 18 /* content.ArtworkUseCase.GroupingBrick */,
    };
    const trailingArtwork = groupingShelfControllerCommon.groupingArtworkFromApiArtwork(objectGraph, trailingArtworkDict, trailingArtworkOptions);
    shelfHeader.trailingArtwork = trailingArtwork;
    // Footer
    const actionUrl = serverData.asString(seeAllContents.attributes, "url");
    const footerTitle = serverData.asString(seeAllContents.attributes, "breakoutCallToActionLabel");
    const clickOptions = {
        id: seeAllContents.id,
        idType: "its_id",
        targetType: "button",
        actionType: "navigate",
        pageInformation: shelfToken.metricsPageInformation,
        locationTracker: shelfToken.metricsLocationTracker,
    };
    if (isSome(actionUrl)) {
        // Footer title
        shelf.footerTitle = footerTitle;
        // Footer action
        const flowPage = objectGraph.required(pageRouter).fetchFlowPage(actionUrl);
        const flowAction = new models.FlowAction(flowPage);
        flowAction.title = footerTitle;
        flowAction.pageUrl = actionUrl;
        metricsHelpersClicks.addClickEventToAction(objectGraph, flowAction, clickOptions);
        shelf.footerAction = flowAction;
    }
    else {
        const metricsOptions = {
            targetType: "button",
            pageInformation: shelfToken.metricsPageInformation,
            locationTracker: shelfToken.metricsLocationTracker,
            recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(seeAllContents),
        };
        const metadata = groupingShelfControllerCommon.metadataForFCData(objectGraph, seeAllContents, shelfToken, false, null, metricsOptions, groupingParseContext);
        if (isSome(metadata.action)) {
            // Clear `actionMetrics` before adding a click event with updated `title`.
            metadata.action.actionMetrics.clearAll();
            metadata.action.title = footerTitle !== null && footerTitle !== void 0 ? footerTitle : serverData.asString(editorialNotes, "callToAction");
            metricsHelpersClicks.addClickEventToAction(objectGraph, metadata.action, clickOptions);
            shelf.footerAction = metadata.action;
            shelf.footerTitle = metadata.action.title;
        }
    }
}
// endregion
// region Ads
/**
 * Performs `lockupFromData`, but additional with Ad stitch related side-effects.
 * @param objectGraph The AppStore dependency graph
 * @param adStitcher Stitcher to source shelfContents from. May be undefined
 * @param adIncidentRecorder Incident recorder for adding ads.
 * @param positionInfo Position this ad is being stitched into.
 * @param shelfToken shelfToken for shelf this ad lockup will be in.
 */
export function lockupFromAdStitcher(objectGraph, adStitcher, adIncidentRecorder, positionInfo, shelfToken) {
    const task = adStitch.consumeTask(adStitcher, positionInfo);
    if (serverData.isNull(task)) {
        return null; // no task for position
    }
    // Try to create lockup
    const lockupData = task.data;
    const lockup = lockupFromData(objectGraph, lockupData, shelfToken);
    if (serverData.isDefinedNonNull(lockup)) {
        shelfToken.includedAdAdamIds = [lockupData.id];
    }
    else {
        adIncidents.recordLockupFromDataFailed(objectGraph, adIncidentRecorder, lockupData);
    }
    return lockup;
}
// endregion
//# sourceMappingURL=grouping-lockup-shelf-controller-common.js.map