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 content from "../../content/content";
import * as flowPreview from "../../content/flow-preview";
import * as lockupsEditorialContext from "../../lockups/editorial-context";
import * as metricsHelpersClicks from "../../metrics/helpers/clicks";
import * as metricsHelpersImpressions from "../../metrics/helpers/impressions";
import * as metricsHelpersLocation from "../../metrics/helpers/location";
import * as placeholders from "../../placeholders/placeholders";
import { GroupingShelfController } from "./grouping-shelf-controller";
import * as groupingShelfControllerCommon from "./grouping-shelf-controller-common";
import * as metricsLocation from "../../../common/metrics/helpers/location";
import { defaultLayoutSize } from "../../../foundation/media/data-fetching";
import * as color from "../../../foundation/util/color-util";
import { isSome } from "@jet/environment";
export class GroupingBrickShelfController extends GroupingShelfController {
    // region Constructors
    constructor() {
        super("GroupingBrickShelfController");
        this.supportedFeaturedContentIds = new Set([
            421 /* groupingTypes.FeaturedContentID.AppStore_BrickRow */,
            422 /* groupingTypes.FeaturedContentID.AppStore_Brick */,
            423 /* groupingTypes.FeaturedContentID.AppStore_CustomBrick */,
            261 /* groupingTypes.FeaturedContentID.Sundance_BrickRow */,
        ]);
    }
    // endregion
    // region Shelf Creation Prerequisites
    /**
     * For a given mediaApiData extract the actual shelfContents array needed to render this shelf
     *
     * @param mediaApiData The outer shelfContents object containing the shelf contents
     */
    initialShelfDataFromGroupingMediaApiData(objectGraph, mediaApiData) {
        return { shelfContents: mediaRelationship.relationshipCollection(mediaApiData, "children") };
    }
    /**
     * For a given url that this controller handles, we should return a promise that will result in the `ShelfData`
     * needed to render this shelf
     *
     * @param objectGraph The App Store dependency graph
     * @param shelfUrl The url that this controller handled on a secondary fetch
     * @param parameters The extracted parameters from the shelf url
     */
    async secondaryShelfDataForShelfUrl(objectGraph, shelfUrl, shelfToken, parameters) {
        return await GroupingShelfController.secondaryGroupingShelfDataForShelfUrl(objectGraph, shelfUrl, shelfToken, parameters).then((shelfData) => {
            return {
                shelfContents: groupingShelfControllerCommon.mergeContentDataIntoEditorialData(shelfData.shelfContents, mediaRelationship.relationshipCollection(shelfToken.featuredContentData, "children")),
            };
        });
    }
    /**
     * For a given mediaApiData create an updated shelf token that contains all the additional data for this specific shelf type
     *
     * @param objectGraph The App Store dependency graph
     * @param baseShelfToken The base grouping shelf token created by the grouping-controller
     * @param mediaApiData The outer data object containing the FC properties and data
     * @param groupingParseContext The parse context for the grouping page so far
     */
    shelfTokenFromBaseTokenAndMediaApiData(objectGraph, mediaApiData, baseShelfToken, groupingParseContext) {
        // If suppress text is not provided, default to hiding.
        let suppressText = mediaAttributes.attributeAsBoolean(mediaApiData, "suppressText");
        if (serverData.isNull(suppressText)) {
            suppressText = true;
        }
        const brickShelfToken = {
            ...baseShelfToken,
            showSupplementaryText: !suppressText,
        };
        brickShelfToken.clientIdentifierOverride = lockupsEditorialContext.clientIdentifierForEditorialContextInData(objectGraph, mediaApiData);
        return brickShelfToken;
    }
    // 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.
     */
    _createShelf(objectGraph, shelfToken, shelfData, groupingParseContext) {
        const items = [];
        const remainingBricks = []; // Data where metadata was missing.
        const displayStyle = serverData.asString(shelfToken.featuredContentData.attributes, "displayStyle");
        const isCategoryBrick = displayStyle === "small";
        let shelf;
        if (isCategoryBrick) {
            // i.e. category bricks shelf
            shelf = new models.Shelf("categoryBrick");
            const layoutSize = serverData.asNumber(shelfToken.featuredContentData.attributes, "layoutStyle.layoutSize");
            shelf.rowsPerColumn = layoutSize !== null && layoutSize !== void 0 ? layoutSize : defaultLayoutSize(objectGraph);
            metricsLocation.currentLocation(shelfToken.metricsLocationTracker).name = "Browse Categories";
        }
        else {
            // i.e. "medium", also the default bricks shelf
            shelf = new models.Shelf("brick");
        }
        shelf.isHorizontal = true;
        for (const brickData of shelfData.shelfContents) {
            const brickModel = GroupingBrickShelfController.createBrick(objectGraph, brickData, isCategoryBrick, shelfToken.metricsPageInformation, shelfToken.metricsLocationTracker, shelfToken, groupingParseContext);
            if (!brickModel) {
                remainingBricks.push(brickData);
                continue;
            }
            items.push(brickModel);
            metricsHelpersLocation.nextPosition(shelfToken.metricsLocationTracker);
        }
        if (serverData.isDefinedNonNull(shelfToken.presentationHints)) {
            shelf.presentationHints = shelfToken.presentationHints;
        }
        if (serverData.isDefinedNonNull(shelfToken.showSupplementaryText)) {
            shelf.presentationHints = {
                ...shelf.presentationHints,
                showSupplementaryText: shelfToken.showSupplementaryText,
            };
        }
        // We don't need this in our incomplete shelf URL, so we'll preemptively remove it.
        delete shelfToken.maxItemCount;
        // Override `featuredContentData` to only have remaining bricks that must be fetched.
        if (serverData.isDefinedNonNull(serverData.traverse(shelfToken.featuredContentData, "relationships.children.data"))) {
            shelfToken.featuredContentData.relationships["children"].data = remainingBricks;
        }
        // Set metadata
        shelf.title = shelfToken.title;
        shelf.subtitle = shelfToken.subtitle;
        if (isCategoryBrick) {
            const displayCount = serverData.asNumber(shelfToken.featuredContentData.attributes, "displayCount");
            shelf.items = items.slice(0, displayCount !== null && displayCount !== void 0 ? displayCount : items.length);
        }
        else {
            shelf.items = items;
        }
        // See all
        const hasSeeAll = serverData.asBooleanOrFalse(shelfToken.featuredContentData.attributes, "hasSeeAll");
        if (isCategoryBrick && hasSeeAll && !objectGraph.client.isWeb) {
            // Setup shelf
            const seeAllShelf = new models.Shelf("categoryBrick");
            seeAllShelf.items = this.sortCategories(objectGraph, items);
            seeAllShelf.presentationHints = { isSeeAllContext: true };
            // Setup Page
            const seeAllPage = new models.GenericPage([seeAllShelf]);
            seeAllPage.title = shelfToken.title;
            // Setup action
            const seeAllAction = new models.FlowAction("page");
            seeAllAction.title = objectGraph.loc.string("ACTION_SEE_ALL");
            seeAllAction.pageData = seeAllPage;
            // Connect action
            shelf.seeAllAction = seeAllAction;
            // Metrics
            metricsHelpersClicks.addClickEventToSeeAllAction(objectGraph, seeAllAction, null, {
                pageInformation: shelfToken.metricsPageInformation,
                locationTracker: shelfToken.metricsLocationTracker,
            });
        }
        // 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);
        }
        if (!willHydrateShelfLater &&
            GroupingBrickShelfController.shouldDisplayChooseYourFavoritesBrick(objectGraph, shelfToken, isCategoryBrick, groupingParseContext)) {
            const brickModel = GroupingBrickShelfController.createChooseYourFavoritesBrick(objectGraph, shelfToken.metricsPageInformation, shelfToken.metricsLocationTracker);
            shelf.items.splice(0, 0, brickModel);
        }
        shelfToken.presentationHints = shelf.presentationHints;
        shelf.url = groupingShelfControllerCommon.createShelfTokenUrlIfNecessaryForShelf(objectGraph, shelf, shelfToken);
        return shelf;
    }
    // region Static Helpers
    // Whether to display Choose Your Favorites brick.
    // It will return TRUE when:
    // - This is an Arcade page
    // - This is a Category brick
    // - Feature flag is enabled
    // - The user is subscribed or trial enrolled
    static shouldDisplayChooseYourFavoritesBrick(objectGraph, shelfToken, isCategoryBrick, groupingParseContext) {
        return (shelfToken.isArcadePage &&
            isCategoryBrick &&
            objectGraph.featureFlags.isEnabled("arcade_choose_your_favorites_brick_Future") &&
            isSome(groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.additionalShelfParameters) &&
            ((groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.additionalShelfParameters.isSubscribed) === "true" ||
                (groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.additionalShelfParameters.isTrialEnrolled) === "true"));
    }
    static createBrick(objectGraph, brickData, searchCategoryBricks, metricsPageInformation, metricsLocationTracker, shelfToken, groupingParseContext) {
        const metricsOptions = {
            targetType: searchCategoryBricks ? "tile" : "brick",
            pageInformation: metricsPageInformation,
            locationTracker: metricsLocationTracker,
            recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(brickData),
        };
        const metadata = groupingShelfControllerCommon.metadataForFCData(objectGraph, brickData, shelfToken, false, null, metricsOptions, groupingParseContext);
        if (!metadata) {
            return null;
        }
        const brickModel = new models.Brick();
        // Setup Artwork
        const artworkOptions = {
            useCase: 18 /* content.ArtworkUseCase.GroupingBrick */,
        };
        if (searchCategoryBricks) {
            const artworks = content.searchChartOrCategoryArtworkFromData(objectGraph, metadata.content, content.SearchChartOrCategoryBrickUseCase.categoryBreakout, models.GenericSearchPageShelfDisplayStyleDensity.Density1);
            brickModel.artworks = artworks;
        }
        else if (metadata.artwork &&
            (shelfToken === null || shelfToken === void 0 ? void 0 : shelfToken.featuredContentId) !== 261 /* groupingTypes.FeaturedContentID.Sundance_BrickRow */) {
            let artworkDict = serverData.asDictionary(metadata.artwork, "subscriptionHero");
            if (!artworkDict) {
                artworkDict = serverData.asDictionary(metadata.artwork, "originalFlowcaseBrick");
            }
            const artwork = groupingShelfControllerCommon.groupingArtworkFromApiArtwork(objectGraph, artworkDict, artworkOptions);
            brickModel.artworks = [artwork];
        }
        else {
            const artwork = groupingShelfControllerCommon.artworkFromFC(objectGraph, brickData, 1060, 520, artworkOptions);
            brickModel.artworks = [artwork];
        }
        brickModel.accessibilityLabel = metadata.title;
        // Set supplementary text.
        brickModel.shortEditorialDescription = metadata.title;
        // Set action
        brickModel.clickAction = metadata.action;
        // Set personalization
        const brickFeaturedContentId = mediaAttributes.attributeAsNumber(brickData, "editorialElementKind");
        if (brickFeaturedContentId === 435 /* groupingTypes.FeaturedContentID.AppStore_MSOBrickMarker */) {
            brickModel.personalizationStyle = "mso";
        }
        // Set flow preview actions
        const contentData = mediaRelationship.relationshipData(objectGraph, brickData, "contents");
        if (serverData.isDefinedNonNull(contentData)) {
            const metricsClickOptions = metricsHelpersClicks.clickOptionsForLockup(objectGraph, contentData, metricsOptions);
            brickModel.flowPreviewActionsConfiguration = flowPreview.flowPreviewActionsConfigurationForProductFromData(objectGraph, brickData, true, shelfToken === null || shelfToken === void 0 ? void 0 : shelfToken.clientIdentifierOverride, brickModel.clickAction, metricsOptions, metricsClickOptions);
        }
        // Configure impressions
        const impressionOptions = metricsHelpersImpressions.impressionOptions(objectGraph, brickData, metadata.title, metricsOptions);
        metricsHelpersImpressions.addImpressionFields(objectGraph, brickModel, impressionOptions);
        // Safe area
        brickModel.artworkSafeArea = models.ChartOrCategorySafeArea.defaultTileArtworkSafeArea;
        brickModel.textSafeArea = models.ChartOrCategorySafeArea.defaultTileTextSafeArea;
        if (!brickModel.isValid()) {
            return null;
        }
        return brickModel;
    }
    /// Creates and returns Choose Your Favorites brick.
    static createChooseYourFavoritesBrick(objectGraph, metricsPageInformation, metricsLocationTracker) {
        const brickModel = new models.Brick();
        // Artwork
        const artwork = new models.Artwork("", 1060, 520, [], color.fromHex("efac78"));
        brickModel.artworks = [artwork];
        // Labels
        const title = objectGraph.loc.string("ARCADE_CHOOSE_YOUR_FAVORITES_BRICK_TITLE");
        brickModel.accessibilityLabel = title;
        brickModel.shortEditorialDescription = title;
        // Action
        const flowAction = new models.FlowAction("arcadeDownloadPackCategories");
        flowAction.presentationContext = "presentModalFormSheet";
        flowAction.pageData = "unknown";
        brickModel.clickAction = flowAction;
        // Impressions
        const metricsOptions = {
            targetType: "brick",
            pageInformation: metricsPageInformation,
            locationTracker: metricsLocationTracker,
            recoMetricsData: null,
        };
        const impressionOptions = metricsHelpersImpressions.impressionOptionsForArcadeChooseYourFavoritesBrick(metricsOptions);
        metricsHelpersImpressions.addImpressionFields(objectGraph, brickModel, impressionOptions);
        // Safe area
        brickModel.artworkSafeArea = models.ChartOrCategorySafeArea.defaultTileArtworkSafeArea;
        brickModel.textSafeArea = models.ChartOrCategorySafeArea.defaultTileTextSafeArea;
        return brickModel;
    }
    // endregion
    // region Metrics
    /**
     * Return the shelf metrics options to use for this specific shelf. Using the base options from the grouping
     * page controller
     *
     * @param objectGraph The App Store dependency graph
     * @param shelfToken The shelf shelfToken for this current shelf creation request
     * @param baseMetricsOptions The minimum set of metrics options for this shelf, created by the
     * grouping page controller
     */
    shelfMetricsOptionsFromBaseMetricsOptions(objectGraph, shelfToken, baseMetricsOptions) {
        const shelfMetricsOptions = { ...baseMetricsOptions };
        const displayStyle = serverData.asString(shelfToken.featuredContentData.attributes, "displayStyle");
        // If this is a Category Bricks shelf, configure metrics title accordingly.
        if (displayStyle === "small") {
            shelfMetricsOptions.title = "Browse Categories";
        }
        return shelfMetricsOptions;
    }
    // endregion
    // region Sort
    sortCategories(objectGraph, categories) {
        return categories.sort((category1, category2) => {
            try {
                return category1.shortEditorialDescription.localeCompare(category2.shortEditorialDescription, objectGraph.loc.safeIdentifier, {
                    usage: "sort",
                });
            }
            catch (e) {
                return 0;
            }
        });
    }
}
//# sourceMappingURL=grouping-brick-shelf-controller.js.map