/**
 * A builder for all SearchResultsContainers variants except for `SearchLockupCollection`.
 * To be cleaned in the future.
 */
import * as validation from "@jet/environment/json/validation";
import { isSome } from "@jet/environment/types/optional";
import * as models from "../../../api/models";
import { EditorialSearchResult } from "../../../api/models";
import * as serverData from "../../../foundation/json-parsing/server-data";
import * as mediaAttributes from "../../../foundation/media/attributes";
import * as mediaRelationship from "../../../foundation/media/relationships";
import * as errors from "../../../foundation/util/errors";
import * as client from "../../../foundation/wrappers/client";
import * as appEvents from "../../app-promotions/app-event";
import * as appPromotionsCommon from "../../app-promotions/app-promotions-common";
import { createArtworkForResource } from "../../content/artwork/artwork";
import * as content from "../../content/content";
import { editorialDisplayOptionsFromClientParams, extractEditorialClientParams, } from "../../editorial-pages/editorial-data-util";
import * as filtering from "../../filtering";
import * as lockups from "../../lockups/lockups";
import * as metricsHelpersImpressions from "../../metrics/helpers/impressions";
import * as metricsHelpersUtil from "../../metrics/helpers/util";
import * as onDevicePersonalization from "../../personalization/on-device-personalization";
import { defaultTodayCardConfiguration, todayCardFromData } from "../../today/today-card-util";
import { TodayCardDisplayStyle, TodayParseContext } from "../../today/today-types";
import * as common from "./search-content-common";
import * as searchLockupCollection from "./search-lockup-collection";
export function searchResultFromData(objectGraph, resultData, searchResponseMetadata, personalizationDataContainer, metricsOptions, isNetworkConstrained, searchEntity, searchExperimentsData) {
    return validation.context("searchResultFromData", () => {
        let searchResult = null;
        const resultType = resultData.type;
        const standardLockupOptions = {
            metricsOptions: {
                pageInformation: metricsOptions.pageInformation,
                locationTracker: metricsOptions.locationTracker,
                targetType: "card",
                createUniqueImpressionId: true,
            },
            hideZeroRatings: true,
            artworkUseCase: 8 /* content.ArtworkUseCase.SearchIcon */,
            isNetworkConstrained: isNetworkConstrained,
            canDisplayArcadeOfferButton: content.shelfContentTypeCanDisplayArcadeOfferButtons(objectGraph, "mixedMediaLockup"),
            clientIdentifierOverride: clientIdentifierOverrideForSearchEntity(objectGraph, searchEntity),
            isMultilineTertiaryTitleAllowed: false,
        };
        const condensedBehavior = condensedBehaviorForData(objectGraph, resultData, searchExperimentsData);
        switch (resultType) {
            case "rooms":
            case "multirooms":
            case "developers":
            case "editorial-items":
            case "groupings":
                if (resultType !== "editorial-items" && resultType !== "developers" && objectGraph.client.isVision) {
                    return null;
                }
                const todayCardConfig = defaultTodayCardConfiguration(objectGraph);
                todayCardConfig.isSearchContext = true;
                const todayCard = todayCardFromData(objectGraph, resultData, todayCardConfig, new TodayParseContext(metricsOptions.pageInformation, metricsOptions.locationTracker));
                if (todayCard && todayCard.media && todayCard.media.kind === "inAppPurchase") {
                    if (objectGraph.client.isVision) {
                        return null;
                    }
                    const iapMedia = todayCard.media;
                    const todayCardInAppPurchaseLockup = iapMedia.lockup;
                    todayCardInAppPurchaseLockup.theme = "dark";
                    searchResult = new models.InAppPurchaseSearchResult(todayCardInAppPurchaseLockup);
                }
                else if (searchLockupCollection.resultDataShouldRenderLockupCollection(objectGraph, resultData, searchResponseMetadata)) {
                    const lockupCollection = searchLockupCollection.lockupCollectionFromResultData(objectGraph, resultData, metricsOptions);
                    if (lockupCollection) {
                        searchResult = lockupCollection;
                    }
                }
                else {
                    const editorialSearchResult = editorialSearchResultFromData(objectGraph, resultData, standardLockupOptions.metricsOptions, condensedBehavior);
                    if (editorialSearchResult) {
                        if (editorialSearchResult.title) {
                            editorialSearchResult.title = editorialSearchResult.title.replace(/\n/g, " ");
                        }
                        if (editorialSearchResult instanceof EditorialSearchResult && editorialSearchResult.subtitle) {
                            editorialSearchResult.subtitle = editorialSearchResult.subtitle.replace(/\n/g, " ");
                        }
                        searchResult = editorialSearchResult;
                    }
                }
                break;
            case "in-apps":
                if (objectGraph.client.isVision || objectGraph.client.isWeb) {
                    return null;
                }
                // Ensure the parent app data is available before proceeding with building the lockup.
                const parentData = lockups.parentDataFromInAppData(objectGraph, resultData);
                if (serverData.isNullOrEmpty(parentData)) {
                    return null;
                }
                const inAppPurchaseLockup = lockups.inAppPurchaseLockupFromData(objectGraph, resultData, standardLockupOptions);
                inAppPurchaseLockup.theme = "dark";
                modifyMetadataBadgeForSearchExperiment(objectGraph, inAppPurchaseLockup, searchExperimentsData);
                searchResult = new models.InAppPurchaseSearchResult(inAppPurchaseLockup);
                break;
            case "apps":
            case "app-bundles":
            default:
                // There should never be an iad in the non-ad search results, so remove it here
                // before creating the lockups.
                delete resultData.attributes["iad"];
                if (resultType === "app-bundles") {
                    if (objectGraph.client.isVision) {
                        return null;
                    }
                    standardLockupOptions.shouldIncludeScreenshotsForChildren =
                        objectGraph.featureFlags.isEnabled("voyager_bundles_2025A");
                    const bundleLockup = lockups.lockupFromData(objectGraph, resultData, standardLockupOptions);
                    bundleLockup.showMetadataInformationInLockup = true;
                    modifyMetadataBadgeForSearchExperiment(objectGraph, bundleLockup, searchExperimentsData);
                    searchResult = new models.BundleSearchResult(bundleLockup);
                }
                else {
                    const lockup = lockups.mixedMediaLockupFromData(objectGraph, resultData, standardLockupOptions, {
                        canPlayFullScreen: false,
                        playbackControls: {},
                    }, searchExperimentsData);
                    modifyMetadataBadgeForSearchExperiment(objectGraph, lockup, searchExperimentsData);
                    // Extract out any associated app event from meta
                    const appEventSearchResult = appEventSearchResultFromData(objectGraph, resultData, lockup, standardLockupOptions, personalizationDataContainer, metricsOptions);
                    if (serverData.isDefinedNonNull(appEventSearchResult)) {
                        searchResult = appEventSearchResult;
                        searchResult.condensedBehavior = "never";
                    }
                    else {
                        // If no app event in meta, fallback to a regular mixed media lockup
                        searchResult = new models.AppSearchResult(lockup);
                    }
                }
                break;
        }
        if (serverData.isDefinedNonNull(searchResult) && serverData.isNull(searchResult.condensedBehavior)) {
            searchResult.condensedBehavior = condensedBehavior;
        }
        return searchResult;
    });
}
/**
 * Indicates whether a search result will display an app event
 * @param objectGraph The object graph
 * @param searchResultData The data for the search result
 * @param installStates A mapping of adamIDs to their respective install states that is used to determine if the app is currently installed by the user
 * @param appStates A mapping of adamIDs to their respective app states that is used to determine if the app has been installed by the user in the past
 * @param metricsOptions Metrics options for built lockups
 * @param personalizationDataContainer Personalization criteria used for sorting and filtering app events
 * @returns a boolean result
 */
export function searchResultWillUseAppEventDisplay(objectGraph, searchResultData, installStates, appStates, metricsOptions, personalizationDataContainer) {
    const appEventEligibleToDisplay = searchResultIsEligibleToDisplayAppEvent(objectGraph, searchResultData);
    if (!appEventEligibleToDisplay) {
        return false;
    }
    const { dataItems } = selectedAppEventDataItems(objectGraph, searchResultData, personalizationDataContainer);
    let appEvent;
    for (const appEventDataItem of dataItems) {
        appEvent = sanitizedAppEvent(objectGraph, appEventDataItem, searchResultData, metricsOptions, undefined, undefined);
        if (serverData.isDefinedNonNull(appEvent)) {
            break;
        }
    }
    const appIsInstalled = serverData.isDefinedNonNull(installStates) && serverData.isDefinedNonNull(installStates[searchResultData.id])
        ? installStates[searchResultData.id]
        : false;
    const appHasBeenInstalled = serverData.isDefinedNonNull(appStates) && serverData.isDefinedNonNull(appStates[searchResultData.id])
        ? ["downloadable"].includes(appStates[searchResultData.id])
        : false;
    // App Events are only displayed in native when the user has installed the app previously and there is a valid app event
    return (appIsInstalled || appHasBeenInstalled) && serverData.isDefinedNonNull(appEvent);
}
/**
 * Derive the condensed behavior from a search result
 * @param objectGraph The global object graph instance
 * @param resultData The data blob for this specific search result
 * @param pageSearchExperimentsData The page level search experiments data object
 */
function condensedBehaviorForData(objectGraph, resultData, pageSearchExperimentsData) {
    var _a, _b;
    /// Guard early against incompatible client devices
    if (!canHaveCondensedBehaviorForClient(objectGraph)) {
        return "never";
    }
    const itemSearchExperimentData = resultData.meta;
    const itemCondensedStyle = (_a = itemSearchExperimentData === null || itemSearchExperimentData === void 0 ? void 0 : itemSearchExperimentData.displayStyle) === null || _a === void 0 ? void 0 : _a.condensed;
    if (serverData.isDefinedNonNull(itemCondensedStyle)) {
        return condensedBehaviorFromStyle(objectGraph, itemCondensedStyle);
    }
    const pageCondensedStyle = (_b = pageSearchExperimentsData === null || pageSearchExperimentsData === void 0 ? void 0 : pageSearchExperimentsData.displayStyle) === null || _b === void 0 ? void 0 : _b.condensed;
    if (serverData.isDefinedNonNull(pageCondensedStyle)) {
        return condensedBehaviorFromStyle(objectGraph, pageCondensedStyle);
    }
    return defaultCondensedBehaviorForClient(objectGraph);
}
/**
 * Gets the condensed behavior from a given condensed style, or a default behavior based on the client type
 * @param objectGraph The global object graph instance
 * @param condensedStyle The condensed style on the data model
 * @returns The condensed behavior for the native search result view
 */
function condensedBehaviorFromStyle(objectGraph, condensedStyle) {
    switch (condensedStyle) {
        case "always":
            return "always";
        case "never":
            return "never";
        case "when-installed":
            return "whenInstalled";
        default:
            return defaultCondensedBehaviorForClient(objectGraph);
    }
}
/**
 * Determines the default condensed behavior based for a given client type
 * @param objectGraph The global object graph instance
 * @param condensedStyle The condensed style on the data model
 * @returns The condensed behavior for the native search result view
 */
function defaultCondensedBehaviorForClient(objectGraph) {
    switch (objectGraph.client.deviceType) {
        case "phone":
            return "whenInstalled";
        default:
            return "never";
    }
}
/**
 * Determines if the current client type supports condensed behavior
 * @param objectGraph The global object graph instance
 * @returns Whether condensed behavior is allowed
 */
function canHaveCondensedBehaviorForClient(objectGraph) {
    switch (objectGraph.client.deviceType) {
        case "phone":
            return true;
        default:
            return false;
    }
}
/**
 * Modifies the editor's choice badge based on whether the search experiment overrides the metadataPrecendence
 * for the badge
 * @param objectGraph App Store ObjectGraph
 * @param lockup The lockup we need to modify for the experiment
 * @param searchExperimentData The experiment data to pull the metadata info from
 */
function modifyMetadataBadgeForSearchExperiment(objectGraph, lockup, searchExperimentData) {
    const shouldShowEditorsChoice = metadataPrecedenceTypePreceedsType(objectGraph, searchExperimentData, "editorialBadgeInfo", "userRating");
    if (serverData.isDefinedNonNull(shouldShowEditorsChoice)) {
        lockup.isEditorsChoice = lockup.isEditorsChoice && shouldShowEditorsChoice;
    }
}
/**
 * Determines whether the first metadata type should precede the second type for the given experiment data
 * @param objectGraph App Store ObjectGraph
 * @param experimentData The experiment data to pull the metadata info from
 * @param firstType Does this precede the second type in the experiment order
 * @param secondType Does this succeed the second type in the experiment order
 * @returns whether the first type precedes the second type
 */
function metadataPrecedenceTypePreceedsType(objectGraph, experimentData, firstType, secondType) {
    var _a;
    if (serverData.isNull(experimentData) || !objectGraph.client.isPhone) {
        return null;
    }
    const order = (_a = experimentData === null || experimentData === void 0 ? void 0 : experimentData.displayStyle) === null || _a === void 0 ? void 0 : _a.metadataPrecedenceOrder;
    if (!serverData.isDefinedNonNullNonEmpty(order)) {
        return null;
    }
    const firstIndex = order.indexOf(firstType);
    const secondIndex = order.indexOf(secondType);
    if (firstIndex === -1 && secondIndex === -1) {
        return null;
    }
    if (firstIndex === -1) {
        return false;
    }
    if (secondIndex === -1) {
        return true;
    }
    return firstIndex < secondIndex;
}
function editorialSearchResultFromData(objectGraph, resultData, metricsOptions, resultCondensedBehavior) {
    return validation.context("editorialSearchResultFromData", () => {
        let searchResult;
        const title = mediaAttributes.attributeAsString(resultData, "name");
        const resultType = resultData.type;
        switch (resultType) {
            case "groupings": {
                const editorialSearchResult = new models.EditorialSearchResult(title);
                const collectionAdamIds = mediaAttributes.attributeAsArrayOrEmpty(resultData, "contentIds");
                if (serverData.isDefinedNonNullNonEmpty(collectionAdamIds)) {
                    editorialSearchResult.collectionAdamIds = collectionAdamIds;
                }
                else {
                    const iconArtwork = content.artworkFromApiArtwork(objectGraph, mediaAttributes.attributeAsDictionary(resultData, "artwork"), {
                        useCase: 9 /* content.ArtworkUseCase.SearchEditorialResult */,
                        allowingTransparency: true,
                    });
                    editorialSearchResult.iconArtwork = iconArtwork;
                }
                editorialSearchResult.type = "category";
                searchResult = editorialSearchResult;
                break;
            }
            case "rooms":
            case "multirooms": {
                const editorialSearchResult = new models.EditorialSearchResult(title);
                editorialSearchResult.artwork = content.artworkFromApiArtwork(objectGraph, mediaAttributes.attributeAsDictionary(resultData, "artwork"), {
                    useCase: 9 /* content.ArtworkUseCase.SearchEditorialResult */,
                    cropCode: "sr",
                });
                editorialSearchResult.collectionAdamIds = mediaAttributes.attributeAsArrayOrEmpty(resultData, "contentIds");
                editorialSearchResult.type = "collection";
                searchResult = editorialSearchResult;
                break;
            }
            case "editorial-items": {
                if (objectGraph.bag.searchFilterEditorialItemIds.has(resultData.id)) {
                    return null;
                }
                // Bridge objects to Today builder.
                const todayParseContext = new TodayParseContext(metricsOptions.pageInformation, metricsOptions.locationTracker);
                const shouldResultBeCondensed = resultCondensedBehavior === "always";
                const editorialSearchResult = editorialSearchResultFromTodayCardData(objectGraph, resultData, todayParseContext, shouldResultBeCondensed);
                searchResult = editorialSearchResult;
                break;
            }
            case "developers": {
                const editorialSearchResult = new models.EditorialSearchResult(title);
                editorialSearchResult.artwork = content.artworkFromApiArtwork(objectGraph, mediaAttributes.attributeAsDictionary(resultData, "editorialArtwork.bannerUber"), {
                    useCase: 9 /* content.ArtworkUseCase.SearchEditorialResult */,
                    cropCode: "sr",
                });
                editorialSearchResult.type = "developer";
                if (isSome(editorialSearchResult.artwork)) {
                    searchResult = editorialSearchResult;
                }
                else {
                    let topApps = mediaRelationship.relationshipCollection(resultData, "top-apps");
                    topApps = topApps.filter((topApp) => {
                        return !filtering.shouldFilter(objectGraph, topApp, 76532 /* filtering.Filter.DeveloperPage */);
                    });
                    const topAppIds = [];
                    const topAppArtwork = [];
                    topApps.forEach((app) => {
                        topAppIds.push(app.id);
                        const appIcon = content.iconFromData(objectGraph, app, {
                            useCase: 9 /* content.ArtworkUseCase.SearchEditorialResult */,
                        });
                        if (serverData.isDefinedNonNull(appIcon)) {
                            topAppArtwork.push(appIcon);
                        }
                    });
                    editorialSearchResult.collectionAdamIds = topAppIds;
                    editorialSearchResult.collectionAppIcons = topAppArtwork;
                    // On visionOS, the developer result falls back to a lockup collection if no art is available.
                    if (objectGraph.client.isVision) {
                        const lockupCollection = searchLockupCollection.lockupCollectionFromResultData(objectGraph, resultData, metricsOptions);
                        searchResult = lockupCollection;
                    }
                    else {
                        searchResult = editorialSearchResult;
                    }
                }
                break;
            }
            default:
                break;
        }
        if (serverData.isNull(searchResult)) {
            return null;
        }
        if (searchResult instanceof EditorialSearchResult) {
            if (searchResult.collectionAdamIds != null && searchResult.collectionAdamIds.length) {
                const lockupCount = searchResult.collectionAdamIds.length;
                if (lockupCount <= 5) {
                    searchResult.artworkGridType = "extraLarge";
                }
                else if (lockupCount <= 8) {
                    searchResult.artworkGridType = "large";
                }
                else if (lockupCount <= 16) {
                    searchResult.artworkGridType = "mixed";
                }
                else {
                    searchResult.artworkGridType = "small";
                }
            }
            if (objectGraph.client.isVision) {
                let badgeText;
                let badgeArtwork = createArtworkForResource(objectGraph, "systemimage://appstore");
                switch (searchResult.type) {
                    case "developer":
                        badgeText = objectGraph.loc.string("EDITORIAL_SEARCH_RESULT_TYPE_DEVELOPER_TITLE_CASE");
                        badgeArtwork = createArtworkForResource(objectGraph, "systemimage://person.crop.square");
                        break;
                    case "category":
                        badgeText = objectGraph.loc.string("EDITORIAL_SEARCH_RESULT_TYPE_CATEGORY_TITLE_CASE");
                        break;
                    case "collection":
                        badgeText = objectGraph.loc.string("EDITORIAL_SEARCH_RESULT_TYPE_COLLECTION_TITLE_CASE");
                        break;
                    case "story":
                        badgeText = objectGraph.loc.string("EDITORIAL_SEARCH_RESULT_TYPE_STORY_TITLE_CASE");
                        break;
                    default:
                        break;
                }
                searchResult.badgeText = badgeText;
                searchResult.badgeArtwork = badgeArtwork;
            }
        }
        const impressionOptions = metricsHelpersImpressions.impressionOptions(objectGraph, resultData, searchResult.title, metricsOptions);
        searchResult.clickAction = lockups.actionFromData(objectGraph, resultData, impressionOptions, null);
        metricsHelpersImpressions.addImpressionFields(objectGraph, searchResult, impressionOptions);
        return searchResult;
    });
}
function editorialSearchResultFromTodayCardData(objectGraph, cardData, todayParseContext, shouldResultBeCondensed) {
    // Card configuration to use for building TodayCards that will be converted into editorial search results.
    const cardConfig = defaultTodayCardConfiguration(objectGraph);
    cardConfig.isSearchContext = true;
    if (!objectGraph.client.isVision) {
        cardConfig.prevailingCropCodes =
            shouldResultBeCondensed && objectGraph.client.isPhone
                ? { defaultCrop: "DMGE.AppST01" }
                : { defaultCrop: "fo" };
    }
    // If we are on visionOS, drop any EIs that have a not-compatible app as the primary content.
    if (objectGraph.client.isVision) {
        const primaryContent = content.primaryContentForData(objectGraph, cardData);
        if (isSome(primaryContent)) {
            const runnableOnDevice = content.runnableOnDeviceWithData(objectGraph, primaryContent, objectGraph.client.deviceType, objectGraph.appleSilicon.isSupportEnabled);
            if (!runnableOnDevice) {
                return null;
            }
        }
    }
    const todayCard = todayCardFromData(objectGraph, cardData, cardConfig, todayParseContext);
    if (!todayCard) {
        return null;
    }
    const editorialSearchResult = new models.EditorialSearchResult(todayCard.title);
    editorialSearchResult.type = "story";
    editorialSearchResult.clickAction = todayCard.clickAction;
    let collectionLockups = null;
    if (todayCard.media) {
        switch (todayCard.media.kind) {
            case "brandedSingleApp":
                const mediaSingleApp = todayCard.media;
                editorialSearchResult.artwork = mediaSingleApp.artworks[0];
                if (serverData.isNull(editorialSearchResult.artwork)) {
                    editorialSearchResult.iconArtwork = mediaSingleApp.icon;
                }
                const cardDisplayStyle = mediaAttributes.attributeAsString(cardData, "cardDisplayStyle");
                switch (cardDisplayStyle) {
                    case TodayCardDisplayStyle.AppOfTheDay:
                    case TodayCardDisplayStyle.GameOfTheDay:
                        const relatedContentData = mediaRelationship.relationshipData(objectGraph, cardData, "card-contents");
                        if (relatedContentData) {
                            editorialSearchResult.title =
                                mediaAttributes.attributeAsString(relatedContentData, "name") ||
                                    editorialSearchResult.title;
                        }
                        break;
                    default:
                        break;
                }
                break;
            case "list":
                const mediaList = todayCard.media;
                collectionLockups = mediaList.lockups;
                break;
            case "river":
                const mediaRiver = todayCard.media;
                collectionLockups = mediaRiver.lockups;
                break;
            case "artwork":
                const mediaArtwork = todayCard.media;
                editorialSearchResult.artwork = mediaArtwork.artworks[0];
                break;
            case "grid":
                const mediaGrid = todayCard.media;
                collectionLockups = mediaGrid.lockups;
                break;
            case "multiApp":
                const multiApp = todayCard.media;
                collectionLockups = multiApp.lockups;
                break;
            case "video":
                const mediaVideo = todayCard.media;
                editorialSearchResult.artwork = mediaVideo.videos[0].preview;
                editorialSearchResult.video = mediaVideo.videos[0];
                if (todayCard.overlay instanceof models.TodayCardThreeLineOverlay) {
                    const overlay = todayCard.overlay;
                    editorialSearchResult.title = overlay.title;
                    editorialSearchResult.subtitle = overlay.description;
                }
                else {
                    editorialSearchResult.subtitle = mediaVideo.description;
                }
                break;
            case "appEvent":
                const media = todayCard.media;
                editorialSearchResult.artwork = media.artworks[0];
                editorialSearchResult.appEventFormattedDates = media.formattedDates;
                editorialSearchResult.subtitle = todayCard.inlineDescription;
                editorialSearchResult.tintColor = media.tintColor;
                editorialSearchResult.type = "appEventStory";
                if (serverData.isDefinedNonNull(todayCard.style)) {
                    switch (todayCard.style) {
                        case "light":
                        case "white":
                            editorialSearchResult.mediaOverlayStyle = "light";
                            break;
                        case "dark":
                            editorialSearchResult.mediaOverlayStyle = "dark";
                            break;
                        default:
                            errors.unreachable(todayCard.style);
                            break;
                    }
                }
                break;
            default:
                break;
        }
    }
    if (todayCard.overlay) {
        switch (todayCard.overlay.kind) {
            case "lockup":
                const cardOverlayLockup = todayCard.overlay;
                if (!editorialSearchResult.artwork || objectGraph.client.isVision) {
                    collectionLockups = [cardOverlayLockup.lockup];
                }
                break;
            case "lockupList":
                const cardOverlayList = todayCard.overlay;
                collectionLockups = cardOverlayList.lockups;
                break;
            case "paragraph":
                const cardOverlayParagraph = todayCard.overlay;
                editorialSearchResult.subtitle = cardOverlayParagraph.paragraph.text;
                break;
            default:
                break;
        }
    }
    if (serverData.isDefinedNonNull(collectionLockups)) {
        editorialSearchResult.collectionAdamIds = [];
        editorialSearchResult.collectionAppIcons = [];
        for (const lockup of collectionLockups) {
            editorialSearchResult.collectionAdamIds.push(lockup.adamId);
            editorialSearchResult.collectionAppIcons.push(lockup.icon);
        }
        if (collectionLockups.length === 1) {
            editorialSearchResult.lockup = collectionLockups[0];
        }
    }
    const editorialClientParams = extractEditorialClientParams(objectGraph, cardData);
    editorialSearchResult.editorialDisplayOptions = editorialDisplayOptionsFromClientParams(editorialClientParams);
    /**
     * Editorial tagline
     */
    const storyTagline = common.editorialSearchResultTagline(objectGraph, cardData);
    if ((storyTagline === null || storyTagline === void 0 ? void 0 : storyTagline.length) > 0 && storyTagline !== editorialSearchResult.title) {
        editorialSearchResult.tagline = storyTagline;
    }
    const heroMedia = todayCard.heroMedia;
    if (serverData.isDefinedNonNullNonEmpty(heroMedia)) {
        if (serverData.isDefinedNonNullNonEmpty(heroMedia.artworks[0])) {
            editorialSearchResult.artwork = heroMedia.artworks[0];
            editorialSearchResult.artwork.crop = "em";
        }
        else if (serverData.isDefinedNonNullNonEmpty(heroMedia.videos[0])) {
            editorialSearchResult.video = heroMedia.videos[0];
        }
    }
    if (editorialSearchResult.video) {
        editorialSearchResult.video.canPlayFullScreen = false;
        editorialSearchResult.video.playbackControls = {};
    }
    if (!editorialSearchResult.collectionAdamIds &&
        !editorialSearchResult.artwork &&
        !editorialSearchResult.iconArtwork) {
        return null;
    }
    return editorialSearchResult;
}
/// Gets the client identifier (or null) that should be used when building lockups for a given search entity.
function clientIdentifierOverrideForSearchEntity(objectGraph, searchEntity) {
    return searchEntity === "watch" ? client.watchIdentifier : null;
}
/**
 * Indicates whether a search result meets basic sanity requirements to display app events. This does not include business rules for massaging a valid app event. For that, see `sanitizedAppEvent` function
 * @param objectGraph The object graph
 * @param searchResultData The data for the search result
 * @returns a boolean result
 */
function searchResultIsEligibleToDisplayAppEvent(objectGraph, searchResultData) {
    if (!appPromotionsCommon.appEventsAreEnabled(objectGraph) || serverData.isNull(searchResultData.meta)) {
        return false;
    }
    // The first organic can't use CPP data from the ad if it has an app event that will be displayed.
    // In this case, it should continue to use DPP assets
    const appEventDataItems = serverData.asArrayOrEmpty(searchResultData.meta, "associations.app-events.data");
    const hasInAppEvents = appEventDataItems.length > 0;
    // App events can be displayed on most search result types, except for these ones
    const typesIneligibleToDisplayAppEvent = [
        "rooms",
        "multirooms",
        "developers",
        "editorial-items",
        "groupings",
        "in-apps",
        "app-bundles",
    ];
    const typeIsEligibleToDisplayAppEvent = !typesIneligibleToDisplayAppEvent.includes(searchResultData.type);
    return typeIsEligibleToDisplayAppEvent && hasInAppEvents;
}
/**
 * Sorts and filters app event for personalization, if applicable. May filter app events, and may select just the best one
 * @param objectGraph The object graph
 * @param resultData The data for the search result
 * @param personalizationDataContainer Personalization criteria used for sorting and filtering app events
 * @returns an object representing the personalized app events for a user, along with the personalization result
 */
function selectedAppEventDataItems(objectGraph, resultData, personalizationDataContainer) {
    const alwaysShowAppEvent = serverData.asBooleanOrFalse(resultData.meta, "associations.app-events.attributes.forceAppEvent");
    const appEventDataItems = serverData.asArrayOrEmpty(resultData.meta, "associations.app-events.data");
    if (alwaysShowAppEvent) {
        // In this scenario, there should always be only one event to choose from,
        // and we don't want to do any personalization.
        return { dataItems: [appEventDataItems[0]] };
    }
    const personalizedDataResult = onDevicePersonalization.personalizeDataItems(objectGraph, "search", appEventDataItems, false, personalizationDataContainer, false, undefined, resultData.id);
    const personalizedDataItems = personalizedDataResult.personalizedData;
    if (personalizedDataItems.length <= 0) {
        return { dataItems: [] };
    }
    return { dataItems: personalizedDataItems, personalizationData: personalizedDataResult };
}
/**
 * Sanitizes a raw app event metadata into an AppEvent model. If the event is not hydratable or has not started, this returns null.
 * @param objectGraph The object graph
 * @param appEventDataItem The app event that needs to be processed
 * @param resultData The data for the search result
 * @param baseMetricsOptions Metrics options for built lockups
 * @param offerEnvironment Offer environment for the lockup. Typically comes from lockup options
 * @param offerStyle Offer style for the lockup. Typically comes from lockup options
 * @returns the processed app event with all business rules applied, or null if the app event was disqualified
 */
function sanitizedAppEvent(objectGraph, appEventDataItem, resultData, baseMetricsOptions, offerEnvironment, offerStyle) {
    const metricsOptions = {
        ...baseMetricsOptions,
        targetType: "eventModule",
    };
    const appEventOrDate = appEvents.appEventOrPromotionStartDateFromData(objectGraph, appEventDataItem, resultData, false, true, offerEnvironment, offerStyle, false, metricsOptions, false, true, null, false, false);
    // Ignore a future AppEvent promotionStartDate here.
    if (serverData.isNull(appEventOrDate) || appEventOrDate instanceof Date) {
        return null;
    }
    else {
        return appEventOrDate;
    }
}
/**
 * Creates an app event search result from the data and associated lockup, if an app event exists in the metadata
 * @param resultData The data blob
 * @param lockup The associated mixed media lockup
 * @param standardLockupOptions: The standard lockup options for search results
 * @param personalizationDataContainer The data container to use for personalizing the selected app event
 * @param baseMetricsOptions Base metrics options for this result
 * @returns {AppEventSearchResult} The app event search result, or null
 */
function appEventSearchResultFromData(objectGraph, resultData, lockup, standardLockupOptions, personalizationDataContainer, baseMetricsOptions) {
    return validation.context("appEventSearchResultFromData", () => {
        const appEventEligibleToDisplay = searchResultIsEligibleToDisplayAppEvent(objectGraph, resultData);
        if (!appEventEligibleToDisplay) {
            return null;
        }
        const { dataItems, personalizationData } = selectedAppEventDataItems(objectGraph, resultData, personalizationDataContainer);
        let appEvent;
        let parentAppData;
        for (const appEventDataItem of dataItems) {
            const appEventOrNull = sanitizedAppEvent(objectGraph, appEventDataItem, resultData, baseMetricsOptions, standardLockupOptions.offerEnvironment, standardLockupOptions.offerStyle);
            if (serverData.isDefinedNonNull(appEventOrNull)) {
                appEvent = appEventOrNull;
                parentAppData = resultData !== null && resultData !== void 0 ? resultData : mediaRelationship.relationshipData(objectGraph, appEventDataItem, "app");
                break;
            }
        }
        if (serverData.isNull(appEvent)) {
            return null;
        }
        const alwaysShowAppEvent = serverData.asBooleanOrFalse(resultData.meta, "associations.app-events.attributes.forceAppEvent");
        const searchResult = new models.AppEventSearchResult();
        searchResult.lockup = lockup;
        searchResult.appEvent = appEvent;
        searchResult.alwaysShowAppEvent = alwaysShowAppEvent;
        searchResult.clickAction = lockup.clickAction;
        const recoMetricsData = metricsHelpersUtil.combinedRecoMetricsDataFromMetricsData(null, personalizationData === null || personalizationData === void 0 ? void 0 : personalizationData.processingType, null);
        const impressionOptions = {
            ...baseMetricsOptions,
            id: appEvent.appEventId,
            kind: "inAppEvent",
            targetType: "eventModule",
            title: appEvent.title,
            softwareType: null,
            recoMetricsData: recoMetricsData,
        };
        if (serverData.isDefinedNonNull(parentAppData)) {
            impressionOptions.relatedSubjectIds = [parentAppData.id];
        }
        metricsHelpersImpressions.addImpressionFields(objectGraph, searchResult, impressionOptions);
        return searchResult;
    });
}
//# sourceMappingURL=search-results.js.map