import { isSome, isNothing } from "@jet/environment/types/optional";
import { FlowAction, GenericPage, Shelf } from "../../api/models";
import { attributeAsNumber, attributeAsString } from "../../foundation/media/attributes";
import { dataFromDataContainer } from "../../foundation/media/data-structure";
import { asNumber, isDefinedNonNull, isDefinedNonNullNonEmpty, isNull, } from "../../foundation/json-parsing/server-data";
import { hasRelationship, relationship } from "../../foundation/media/relationships";
import { URL } from "../../foundation/network/urls";
import { appStoreIdentifier } from "../../foundation/wrappers/client";
import { createArtworkForResource } from "../content/artwork/artwork";
import { addMetricsEventsToPageWithInformation, metricsPageInformationFromMediaApiResponse, } from "../metrics/helpers/page";
import { newPageRefreshControllerFromResponse, pageRefreshPolicyForController, } from "../refresh/page-refresh-controller";
import { metricsData } from "../personalization/on-device-personalization";
import { impressionEventsFromData } from "../personalization/on-device-impression-demotion";
import { combinedRecoMetricsDataFromMetricsData } from "../metrics/helpers/util";
import { newLocationTracker } from "../metrics/helpers/location";
import { flattenMediaApiGroupingData, insertInitialShelvesIntoGroupingParseContext, shelfForFooterButtons, shelfForTermsAndConditions, shelfForUnifiedMessage, } from "./grouping-common";
import { addBatchGroupsToPage } from "./shelf-batching";
import { nameFromGroupingData } from "../lockups/lockups";
// The key that contains the impression data for the grouping page fetched as an additional request.
export const GroupingImpressionAdditionalDataKey = "amdImpressionData";
export function groupingParseContextFromDataContainer(objectGraph, data, additionalPageRequirements) {
    const mediaApiGroupingData = dataFromDataContainer(objectGraph, data);
    if (isNothing(mediaApiGroupingData)) {
        return null;
    }
    const metricsPageInformation = metricsPageInformationFromMediaApiResponse(objectGraph, "Genre", mediaApiGroupingData.id, data);
    const onDevicePersonalizationMetricsData = metricsData(objectGraph);
    metricsPageInformation.recoMetricsData = combinedRecoMetricsDataFromMetricsData(metricsPageInformation.recoMetricsData, null, onDevicePersonalizationMetricsData);
    return {
        shelves: [],
        metricsPageInformation: metricsPageInformation,
        metricsLocationTracker: newLocationTracker(),
        pageGenreAdamId: attributeAsString(mediaApiGroupingData, "id"),
        pageGenreId: null,
        hasAuthenticatedUser: isDefinedNonNull(objectGraph.user.dsid),
        refreshController: newPageRefreshControllerFromResponse(data),
        recoImpressionData: impressionEventsFromData(objectGraph, additionalPageRequirements === null || additionalPageRequirements === void 0 ? void 0 : additionalPageRequirements[GroupingImpressionAdditionalDataKey]),
    };
}
export function flattenedGroupingFromDataContainer(objectGraph, data) {
    const mediaApiGroupingData = dataFromDataContainer(objectGraph, data);
    if (!mediaApiGroupingData) {
        return null;
    }
    if (!hasRelationship(mediaApiGroupingData, "tabs")) {
        return null;
    }
    return flattenMediaApiGroupingData(objectGraph, mediaApiGroupingData);
}
// TODO: Once 18E is in we need to get the genreId from the chart URL
export function genreIdFromChartURL(chartURLString) {
    if (isNull(chartURLString)) {
        return null;
    }
    const chartURL = URL.from(chartURLString);
    return asNumber(chartURL.query, "genre");
}
function groupingPageTitleForData(objectGraph, groupingData, genreId) {
    var _a;
    let pageTitle = null;
    switch (genreId) {
        case 36 /* GenreIds.Apps */:
            if (objectGraph.host.clientIdentifier === appStoreIdentifier && !objectGraph.client.isWatch) {
                if (objectGraph.client.isMac) {
                    pageTitle = macDiscoverPageTitleForData(objectGraph, groupingData);
                }
                else {
                    pageTitle = objectGraph.loc.string("GROUPING_APPS");
                }
            }
            else {
                if (objectGraph.client.isTV) {
                    pageTitle = objectGraph.loc.string("GROUPING_APPS");
                }
                else if (objectGraph.client.isWeb) {
                    pageTitle =
                        ((_a = objectGraph.activeIntent) === null || _a === void 0 ? void 0 : _a.previewPlatform) === "mac"
                            ? macDiscoverPageTitleForData(objectGraph, groupingData)
                            : objectGraph.loc.string("GROUPING_APPS");
                }
                else {
                    pageTitle = objectGraph.loc.string("GROUPING_APP_STORE", "App Store");
                }
            }
            break;
        case 39 /* GenreIds.Discover */:
            pageTitle = objectGraph.loc.string("GROUPING_DISCOVER");
            break;
        default:
            pageTitle = nameFromGroupingData(objectGraph, groupingData);
            break;
    }
    return pageTitle;
}
/**
 * Create a shelf for header buttons, e.g. "Search".
 *
 * @return Shelf configured to display header buttons.
 */
function shelfForHeaderButtons(objectGraph) {
    const shelf = new Shelf("action");
    const items = [];
    const searchFlowAction = new FlowAction("search");
    searchFlowAction.title = objectGraph.loc.string("SEARCH", "Search");
    searchFlowAction.artwork = createArtworkForResource(objectGraph, "systemimage://magnifyingglass");
    items.push(searchFlowAction);
    shelf.items = items;
    return shelf;
}
/**
 * Returns the page title for the Discover tab on macOS
 *
 * @param objectGraph
 * @param {Data} groupingData MAPI data blob describing the grouping
 * @return Page title string
 */
function macDiscoverPageTitleForData(objectGraph, groupingData) {
    const tabs = relationship(groupingData, "tabs");
    if (isDefinedNonNull(tabs) && isDefinedNonNull(tabs.data)) {
        for (const tabData of tabs.data) {
            const tabName = attributeAsString(tabData, "name");
            const featuredContentId = attributeAsNumber(tabData, "editorialElementKind");
            const token = attributeAsString(tabData, "token");
            if (isSome(tabName) &&
                tabName.length > 0 &&
                isDefinedNonNull(featuredContentId) &&
                isDefinedNonNullNonEmpty(token) &&
                token === "macOS" &&
                featuredContentId === 414 /* FeaturedContentID.AppStore_TabRoot */) {
                return tabName;
            }
        }
    }
    return objectGraph.loc.string("GROUPING_DISCOVER");
}
/**
 * Insert the unified message shelves into the arcade page
 *
 * @param objectGraph The App Store dependency graph
 * @param page The generic page to insert shelves into
 * @param genreId The genre Id of the generic page, e.g. Apps or Games
 */
function insertUnifiedMessageShelves(objectGraph, page, genreId) {
    if (page.shelves.length <= 0) {
        return;
    }
    // Insert Unified message shelves. These are hidden by default and act as 'placeholder' locations
    // for the marketing teams to target with inline banners or bubble tip messages
    switch (genreId) {
        case 36 /* GenreIds.Apps */:
            page.shelves.splice(0, 0, shelfForUnifiedMessage(objectGraph, "appsPageHeader"));
            page.shelves.splice(6, 0, shelfForUnifiedMessage(objectGraph, "appsPageMid"));
            page.shelves.push(shelfForUnifiedMessage(objectGraph, "appsPageFooter"));
            break;
        case 6014 /* GenreIds.Games */:
            page.shelves.splice(0, 0, shelfForUnifiedMessage(objectGraph, "gamesPageHeader"));
            page.shelves.splice(6, 0, shelfForUnifiedMessage(objectGraph, "gamesPageMid"));
            page.shelves.push(shelfForUnifiedMessage(objectGraph, "gamesPageFooter"));
            break;
        default:
            break;
    }
}
export function groupingPageFromFlattenedGrouping(objectGraph, flattenedGrouping, groupingParseContext) {
    groupingParseContext.pageGenreId =
        attributeAsNumber(flattenedGrouping.originalGroupingData, "genre") ||
            genreIdFromChartURL(attributeAsString(flattenedGrouping.originalGroupingData, "chartUrl"));
    // Construct the shelves
    insertInitialShelvesIntoGroupingParseContext(objectGraph, flattenedGrouping, groupingParseContext);
    if (objectGraph.client.isWatch) {
        // Remove title of first shelf with cards if needed.
        if (groupingParseContext.shelves.length > 0 && groupingParseContext.shelves[0].contentType === "todayCard") {
            groupingParseContext.shelves[0].title = undefined;
        }
        // Prepend Header Buttons
        if (objectGraph.client.deviceType !== "watch") {
            const headerButtonShelf = shelfForHeaderButtons(objectGraph);
            groupingParseContext.shelves.unshift(headerButtonShelf);
        }
    }
    // TODO: Add for ATV
    // Append Footer Buttons
    if (objectGraph.client.deviceType !== "tv" && objectGraph.client.deviceType !== "web") {
        const footerButtonShelf = shelfForFooterButtons(objectGraph, groupingParseContext.metricsPageInformation, groupingParseContext.metricsLocationTracker);
        if (footerButtonShelf) {
            groupingParseContext.shelves.push(footerButtonShelf);
        }
    }
    // TODO: Add for ATV
    // Append T&C
    if (objectGraph.client.deviceType !== "watch" && objectGraph.client.deviceType !== "tv") {
        const url = objectGraph.bag.termsAndConditionsURL;
        if (!isNull(url)) {
            const termsAndConditionsShelf = shelfForTermsAndConditions(objectGraph, url);
            groupingParseContext.shelves.push(termsAndConditionsShelf);
        }
    }
    // Determine the title
    const pageTitle = groupingPageTitleForData(objectGraph, flattenedGrouping.originalGroupingData, groupingParseContext.pageGenreId);
    // Build the page
    const page = new GenericPage(groupingParseContext.shelves);
    switch (objectGraph.client.deviceType) {
        case "tv":
            page.title = pageTitle;
            break;
        case "watch":
            page.title = pageTitle;
            page.presentationOptions = ["prefersLargeTitleWhenRoot"];
            break;
        case "web":
            page.title = pageTitle;
            page.presentationOptions = ["prefersLargeTitleWhenRoot"];
            const firstShelfType = page.shelves[0].contentType;
            if (["heroCarousel", "editorialCard", "largeStoryCard"].includes(firstShelfType)) {
                page.presentationOptions.push("prefersOverlayedPageHeader");
            }
            break;
        default:
            page.title = pageTitle;
            if ((groupingParseContext.pageGenreId === 39 /* GenreIds.Discover */ ||
                (groupingParseContext.pageGenreId === 36 /* GenreIds.Apps */ && objectGraph.client.isMac)) &&
                !objectGraph.client.isIconArtworkCapable) {
                page.presentationOptions = ["prefersRevealNavigationBarOnMouseOver"];
            }
            else {
                page.presentationOptions = ["prefersLargeTitleWhenRoot"];
            }
            break;
    }
    if (objectGraph.client.isiOS) {
        if (groupingParseContext.shelves[0].contentType === "mediaPageHeader") {
            page.presentationOptions.push("prefersNonStandardBackButton");
            page.presentationOptions.push("prefersHiddenPageTitle");
            page.presentationOptions.push("prefersOverlayedPageHeader");
        }
    }
    page.pageRefreshPolicy = pageRefreshPolicyForController(objectGraph, groupingParseContext === null || groupingParseContext === void 0 ? void 0 : groupingParseContext.refreshController);
    addMetricsEventsToPageWithInformation(objectGraph, page, groupingParseContext.metricsPageInformation);
    // Add unified message shelves
    if (objectGraph.client.isiOS) {
        insertUnifiedMessageShelves(objectGraph, page, groupingParseContext.pageGenreId);
    }
    addBatchGroupsToPage(page);
    return page;
}
//# sourceMappingURL=render-grouping-page.js.map