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 lockups from "../../lockups/lockups";
import * as metricsHelpersClicks from "../../metrics/helpers/clicks";
import * as metricsHelpersImpressions from "../../metrics/helpers/impressions";
import * as metricsHelpersLocation from "../../metrics/helpers/location";
import { GroupingShelfController } from "./grouping-shelf-controller";
import * as groupingShelfControllerCommon from "./grouping-shelf-controller-common";
export class GroupingCategoryShelfController extends GroupingShelfController {
    // region Constructors
    constructor() {
        super("GroupingCategoryShelfController");
        this.supportedFeaturedContentIds = new Set([425 /* groupingTypes.FeaturedContentID.AppStore_GenreStack */]);
    }
    // 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) {
        const childListBoxes = mediaRelationship.relationshipData(objectGraph, mediaApiData, "children");
        if (childListBoxes) {
            return { shelfContents: mediaRelationship.relationshipCollection(childListBoxes, "children") };
        }
        else {
            return { shelfContents: [] };
        }
    }
    /**
     * 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) => {
            const childListBoxes = mediaRelationship.relationshipData(objectGraph, shelfToken.featuredContentData, "children");
            if (childListBoxes) {
                const hydratedListBoxSections = groupingShelfControllerCommon.mergeContentDataIntoEditorialData(shelfData.shelfContents, mediaRelationship.relationshipCollection(childListBoxes, "children"));
                return { shelfContents: hydratedListBoxSections };
            }
            else {
                return { shelfContents: [] };
            }
        });
    }
    /**
     * 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) {
        return baseShelfToken;
    }
    // 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) {
        var _a;
        if (serverData.isNullOrEmpty(shelfData.shelfContents)) {
            return null;
        }
        const items = [];
        let itemsHaveRectangularArtwork = false;
        for (const category of shelfData.shelfContents) {
            const grouping = mediaRelationship.relationshipData(objectGraph, category, "grouping");
            if (serverData.isNull(grouping)) {
                continue;
            }
            const adamId = groupingShelfControllerCommon.contentIdFromContentItem(objectGraph, grouping);
            if (serverData.isNull(category.attributes) ||
                serverData.isNull(grouping.attributes) ||
                groupingShelfControllerCommon.shouldDefer(shelfToken)) {
                shelfToken.isDeferring = true;
                shelfToken.remainingItems.push(grouping);
                continue;
            }
            const metricsBase = {
                targetType: "listItem",
                pageInformation: shelfToken.metricsPageInformation,
                locationTracker: shelfToken.metricsLocationTracker,
                recoMetricsData: mediaDataStructure.metricsFromMediaApiObject(category),
            };
            const action = lockups.actionFromData(objectGraph, grouping, { ...metricsBase, id: adamId }, shelfToken.clientIdentifierOverride);
            metricsHelpersImpressions.addImpressionFields(objectGraph, action, {
                ...metricsBase,
                kind: "link",
                softwareType: serverData.asBooleanOrFalse(groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.isArcadePage) ? "Arcade" : null,
                title: action.title,
                id: adamId,
            });
            const artwork = mediaAttributes.attributeAsDictionary(grouping, "artwork");
            if (artwork.width > artwork.height) {
                itemsHaveRectangularArtwork = true;
            }
            if (serverData.isDefinedNonNullNonEmpty(artwork)) {
                action.artwork = content.artworkFromApiArtwork(objectGraph, artwork, {
                    allowingTransparency: true,
                    useCase: 20 /* content.ArtworkUseCase.CategoryIcon */,
                });
            }
            items.push(action);
            metricsHelpersLocation.nextPosition(shelfToken.metricsLocationTracker);
        }
        // The top level shelf on mac should always be sorted
        // <rdar://problem/40954563> LOC: Global: MAS: Order of categories appears in English alphabetical order instead of in each language's alphabetical order.
        if (objectGraph.client.isMac) {
            this.sortCategories(objectGraph, items);
        }
        const shelf = this.shelfForCategoryActions(objectGraph, items, shelfToken);
        shelf.title = shelfToken.title;
        shelf.subtitle = shelfToken.subtitle;
        shelf.url = groupingShelfControllerCommon.createShelfTokenUrlIfNecessaryForShelf(objectGraph, shelf, shelfToken);
        if (itemsHaveRectangularArtwork) {
            const existingPresentationHints = (_a = shelf.presentationHints) !== null && _a !== void 0 ? _a : {};
            shelf.presentationHints = {
                ...existingPresentationHints,
                itemsHaveRectangularArtwork: true,
            };
        }
        return shelf;
    }
    shelfForCategoryActions(objectGraph, categories, shelfToken) {
        const shelf = new models.Shelf("action");
        // Limit for number of items (`null` when there's no limit).
        let itemLimit;
        // Configure shelf orientation and limit
        switch (objectGraph.client.deviceType) {
            case "tv":
                shelf.isHorizontal = true;
                itemLimit = 8;
                break;
            case "mac":
                shelf.isHorizontal = false;
                itemLimit = null;
                break;
            case "web":
                shelf.isHorizontal = true;
                shelf.rowsPerColumn = 3;
                itemLimit = 24;
                break;
            default:
                shelf.isHorizontal = false;
                itemLimit = 6;
                break;
        }
        // Apply limit (if any)
        if (itemLimit !== null && categories.length > itemLimit) {
            shelf.items = categories.slice(0, itemLimit);
            const allCategoriesAction = new models.FlowAction("page");
            allCategoriesAction.title = objectGraph.loc.string("ACTION_SEE_ALL");
            metricsHelpersClicks.addClickEventToSeeAllAction(objectGraph, allCategoriesAction, null, {
                pageInformation: shelfToken.metricsPageInformation,
                locationTracker: shelfToken.metricsLocationTracker,
            });
            shelf.seeAllAction = allCategoriesAction;
            const allCategoriesShelf = new models.Shelf("action");
            allCategoriesShelf.isHorizontal = false;
            this.sortCategories(objectGraph, categories);
            allCategoriesShelf.items = categories;
            const allCategoriesPage = new models.GenericPage([allCategoriesShelf]);
            allCategoriesPage.title = objectGraph.loc.string("PAGE_TITLE_CATEGORIES");
            allCategoriesAction.pageData = allCategoriesPage;
        }
        else {
            shelf.items = categories;
        }
        return shelf;
    }
    // region Helpers
    /**
     * Sort the category actions alphabetically
     * @param objectGraph
     * @param categories The cateogries we're going to be displaying
     */
    sortCategories(objectGraph, categories) {
        categories.sort((category1, category2) => {
            try {
                return category1.title.localeCompare(category2.title, objectGraph.loc.safeIdentifier, {
                    usage: "sort",
                });
            }
            catch (e) {
                return 0;
            }
        });
    }
}
//# sourceMappingURL=grouping-category-shelf-controller.js.map