import * as models from "../../../api/models";
import * as mediaDataFetching from "../../../foundation/media/data-fetching";
import * as mediaNetwork from "../../../foundation/media/network";
import * as urls from "../../../foundation/network/urls";
import * as lockups from "../../lockups/lockups";
import * as metricsHelpersLocation from "../../metrics/helpers/location";
import { GroupingShelfController } from "./grouping-shelf-controller";
import * as validation from "@jet/environment/json/validation";
import { ResponseMetadata } from "../../../foundation/network/network";
import * as groupingShelfControllerCommon from "./grouping-shelf-controller-common";
import { Parameters, Path, Protocol } from "../../../foundation/network/url-constants";
import * as content from "../../content/content";
import { developerAttributes } from "../../../common/developer/developer-request";
import { lockupShelfTokenFromBaseTokenAndMediaApiData } from "./grouping-lockup-shelf-controller-common";
import { isNothing, isSome } from "@jet/environment/types/optional";
import { arcadeOnboardingSubscriptionStatusFromString } from "../../../api/models";
import * as metricsHelpersImpressions from "../../metrics/helpers/impressions";
export class ArcadeDownloadPackShelfController extends GroupingShelfController {
    constructor() {
        super("ArcadeDownloadPackShelfController");
        // Stable identifier of the shelf to match in native.
        // Used to make a shelf refresh request after user finishes onboarding.
        this.shelfId = "arcadeDownloadPackShelf";
        this.supportedFeaturedContentIds = new Set([566 /* groupingTypes.FeaturedContentID.AppStore_ArcadeDownloadPackMarker */]);
    }
    shelfRoute(objectGraph) {
        return [
            ...super.shelfRoute(objectGraph),
            {
                protocol: Protocol.internal,
                path: `/${Path.grouping}/${Path.shelf}/{token}`,
                query: [Parameters.isArcadeDownloadPackShelfPlaceholder],
            },
        ];
    }
    shelfTokenFromBaseTokenAndMediaApiData(objectGraph, mediaApiData, baseShelfToken, groupingParseContext) {
        return lockupShelfTokenFromBaseTokenAndMediaApiData(objectGraph, mediaApiData, baseShelfToken, groupingParseContext);
    }
    initialShelfDataFromGroupingMediaApiData(objectGraph, mediaApiData) {
        return {
            shelfContents: [],
            categoriesContents: [],
            apps: [],
            title: "",
        };
    }
    async secondaryShelfDataForShelfUrl(objectGraph, shelfUrl, shelfToken, parameters) {
        const downloadPackData = objectGraph.arcade.getDownloadPackGames(objectGraph.bag.arcadeDownloadPackShelfTTLInSeconds);
        if (isNothing(downloadPackData) || downloadPackData.apps.length === 0) {
            return {
                shelfContents: [],
                categoriesContents: [],
                apps: [],
                title: "",
            };
        }
        const downloadPackApps = downloadPackData.apps;
        const shelfTitle = this.shelfTitle(objectGraph, arcadeOnboardingSubscriptionStatusFromString(downloadPackData.subscriptionStatus));
        // Check whether it was a call from native to render a placeholder.
        if (isSome(shelfUrl.query[Parameters.isArcadeDownloadPackShelfPlaceholder])) {
            return {
                shelfContents: [],
                categoriesContents: [],
                apps: downloadPackApps,
                title: shelfTitle,
            };
        }
        // Do hydration call otherwise.
        const adamIDs = downloadPackApps.map((app) => app.adamId);
        const categoryIDs = downloadPackApps.map((app) => app.categoryId);
        const appsType = "apps";
        const categoriesType = "editorial-items";
        const batchRequest = new mediaDataFetching.Request(objectGraph)
            .addingQuery(`ids[${appsType}]`, Array.from(adamIDs).join(","))
            .addingQuery(`ids[${categoriesType}]`, Array.from(categoryIDs).join(","))
            .includingAdditionalPlatforms(mediaDataFetching.defaultAdditionalPlatformsForClient(objectGraph))
            .includingAttributes(developerAttributes(objectGraph));
        return await mediaNetwork
            .fetchData(objectGraph, batchRequest)
            .then(async (dataContainer) => {
            const shelfData = {
                shelfContents: dataContainer.data.filter((data) => {
                    return data.type === appsType;
                }),
                categoriesContents: dataContainer.data.filter((data) => {
                    return data.type === categoriesType;
                }),
                apps: downloadPackApps,
                title: shelfTitle,
                responseTimingValues: dataContainer[ResponseMetadata.timingValues],
            };
            return shelfData;
        });
    }
    _createShelf(objectGraph, shelfToken, shelfData, groupingParseContext) {
        if (shelfToken.isFirstRender) {
            const downloadPackData = objectGraph.arcade.getDownloadPackGames(objectGraph.bag.arcadeDownloadPackShelfTTLInSeconds);
            if (isNothing(downloadPackData) || downloadPackData.apps.length === 0) {
                // No suggested games to display. Adding an empty hidden shelf with `refreshUrl` for future refresh from native when onboarding ends.
                const shelf = this.emptyShelfWithRefreshUrl(objectGraph);
                shelf.refreshUrl = this.shelfRefreshURL(shelfToken);
                // Even though the shelf is hidden, need to increase position here, so when it becomes visible the index stays the same.
                metricsHelpersLocation.nextPosition(groupingParseContext.metricsLocationTracker);
                return shelf;
            }
            else {
                const shelf = this.placeholderShelf(objectGraph, shelfToken, downloadPackData.apps, this.shelfTitle(objectGraph, arcadeOnboardingSubscriptionStatusFromString(downloadPackData.subscriptionStatus)));
                metricsHelpersLocation.nextPosition(groupingParseContext.metricsLocationTracker);
                return shelf;
            }
        }
        else {
            // If `shelfData` contains only `records` then it was a request for a placeholder shelf from native.
            if (shelfData.apps.length > 0 &&
                (isNothing(shelfData.shelfContents) || shelfData.shelfContents.length === 0)) {
                return this.placeholderShelf(objectGraph, shelfToken, shelfData.apps, shelfData.title);
            }
            else {
                const shelfMetricsOptions = this.shelfMetrics(shelfData.title, shelfToken);
                metricsHelpersLocation.pushContentLocation(objectGraph, shelfMetricsOptions, shelfData.title);
                const shelf = this.downloadPackShelf(objectGraph, shelfToken, shelfData);
                // `refreshUrl` allows to update the shelf content if the onboarding experience was triggered again.
                shelf.refreshUrl = this.shelfRefreshURL(shelfToken);
                metricsHelpersLocation.popLocation(shelfToken.metricsLocationTracker);
                metricsHelpersImpressions.addImpressionFields(objectGraph, shelf, shelfMetricsOptions);
                return shelf;
            }
        }
    }
    shelfMetricsOptionsFromBaseMetricsOptions(objectGraph, shelfToken, baseMetricsOptions) {
        // Otherwise `baseMetricsOptions` will be used, however, at this point shelf doesn't have a title.
        return null;
    }
    emptyShelfWithRefreshUrl(objectGraph) {
        const shelf = new models.Shelf(this.useCustomDownloadPackCardShelf(objectGraph) ? "arcadeDownloadPackCard" : "smallLockup");
        shelf.id = this.shelfId;
        shelf.isHidden = true;
        return shelf;
    }
    placeholderShelf(objectGraph, shelfToken, downloadPackApps, title) {
        const shelf = this.useCustomDownloadPackCardShelf(objectGraph)
            ? this.downloadPackCardPlaceholderShelf(objectGraph, shelfToken, downloadPackApps.length)
            : this.smallLockupsPlaceholderShelf(objectGraph, shelfToken, downloadPackApps);
        shelf.url = urls.URL.from(groupingShelfControllerCommon.groupingShelfUrl(shelfToken)).build();
        shelf.title = title;
        return shelf;
    }
    downloadPackCardPlaceholderShelf(objectGraph, shelfToken, expectedItemCount) {
        const shelf = new models.Shelf("arcadeDownloadPackCard");
        shelf.id = this.shelfId;
        // For `arcadeDownloadPackCard` the same `ArcadeDownloadPackCard` model is used to render lockup placeholders.
        const card = new models.ArcadeDownloadPackCard();
        card.numberOfPlaceholders = expectedItemCount;
        shelf.items = [card];
        // See `shelfFetchShouldMergeWhenFetched` where `shelfToken.shelfStyle` is used to override `shelf.mergeWhenFetched` flag.
        shelfToken.shelfStyle = shelf.contentType;
        return shelf;
    }
    smallLockupsPlaceholderShelf(objectGraph, shelfToken, downloadPackApps) {
        const shelf = new models.Shelf("smallLockup");
        shelf.id = this.shelfId;
        shelf.items = [];
        shelf.isHorizontal = true;
        shelf.rowsPerColumn = 2;
        // Use standard small lockup placeholders for iPad shelf.
        shelf.items = Array(downloadPackApps.length).fill(new models.Placeholder());
        shelf.placeholderContentType = shelf.contentType;
        shelf.contentType = "placeholder";
        shelfToken.showingPlaceholders = true;
        shelfToken.remainingItems = downloadPackApps.map((value) => {
            return {
                id: value.adamId,
                type: "apps",
            };
        });
        return shelf;
    }
    downloadPackShelf(objectGraph, shelfToken, shelfData) {
        const categories = this.categoriesMapFromResponse(objectGraph, shelfData.categoriesContents, shelfData.apps);
        const useCustomShelf = this.useCustomDownloadPackCardShelf(objectGraph);
        const contentType = useCustomShelf ? "arcadeDownloadPackCard" : "smallLockup";
        const apps = this.lockupsFromResponse(objectGraph, shelfToken, categories, useCustomShelf, // In the custom `arcadeDownloadPack` shelf app lockups the game category goes into lockup header, otherwise, in a standard shelf, it goes into subtitle.
        useCustomShelf, // In the custom `arcadeDownloadPack` shelf app lockups have dark environment.
        content.artworkUseCaseFromShelfStyle(objectGraph, contentType), isSome(shelfData.shelfContents) ? shelfData.shelfContents : [], shelfData.apps);
        const shelf = new models.Shelf(contentType);
        shelf.id = this.shelfId;
        shelf.title = shelfData.title;
        if (useCustomShelf) {
            const card = new models.ArcadeDownloadPackCard();
            card.lockups = apps;
            shelf.items = [card];
        }
        else {
            shelf.items = apps;
            shelf.isHorizontal = true;
            shelf.rowsPerColumn = 2;
        }
        shelf.isHidden = apps.length === 0;
        return shelf;
    }
    // On iPhone there is a bespoke 'arcadeDownloadPackCard' games card shelf.
    // On iPad, always use `smallLockup` instead of `shelfToken.shelfStyle` from server
    // to make editorial configuration work easier.
    useCustomDownloadPackCardShelf(objectGraph) {
        return objectGraph.client.isPhone;
    }
    shelfRefreshURL(shelfToken) {
        return urls.URL.from(groupingShelfControllerCommon.groupingShelfUrl(shelfToken))
            .param(Parameters.isArcadeDownloadPackShelfPlaceholder, "true")
            .build();
    }
    lockupsFromResponse(objectGraph, shelfToken, categoryTitlesForAdamIDs, showCategoryHeader, darkEnvironment, artworkUseCase, responseData, records) {
        return validation.context("lockupsFromResponse", () => {
            const lockupDataMap = new Map();
            for (const lockupData of responseData) {
                lockupDataMap.set(lockupData.id, lockupData);
            }
            const locationTracker = shelfToken.metricsLocationTracker;
            const pageInformation = shelfToken.metricsPageInformation;
            // Order of the apps from the local storage (records) must be preserved,
            // so user always sees the same list of the apps like it was on the onboarding game suggestions screen.
            const items = [];
            for (const app of records) {
                const lockupData = lockupDataMap.get(app.adamId);
                if (isNothing(lockupData)) {
                    continue;
                }
                const lockup = lockups.lockupFromData(objectGraph, lockupData, {
                    offerStyle: darkEnvironment ? "transparent" : undefined,
                    offerEnvironment: darkEnvironment ? "dark" : undefined,
                    metricsOptions: {
                        pageInformation: pageInformation,
                        locationTracker: locationTracker,
                        badges: {
                            categoryId: app.categoryId,
                        },
                    },
                    metricsClickOptions: {
                        id: lockupData.id,
                        pageInformation: pageInformation,
                        locationTracker: locationTracker,
                        badges: {
                            categoryId: app.categoryId,
                        },
                    },
                    artworkUseCase: artworkUseCase,
                    shouldHideArcadeHeader: true,
                    isSubtitleHidden: showCategoryHeader,
                });
                if (isNothing(lockup)) {
                    continue;
                }
                lockups.cleanupArcadeDownloadPackLockupMetricsIfNeeded(lockup, objectGraph);
                metricsHelpersLocation.nextPosition(locationTracker);
                if (showCategoryHeader) {
                    lockup.heading = categoryTitlesForAdamIDs.get(lockup.adamId);
                }
                else {
                    lockup.subtitle = categoryTitlesForAdamIDs.get(lockup.adamId);
                }
                items.push(lockup);
            }
            return items;
        });
    }
    categoriesMapFromResponse(objectGraph, responseData, records) {
        const result = new Map();
        for (const app of records) {
            const category = responseData.find((data) => data.id === app.categoryId);
            if (!category) {
                continue;
            }
            const editorialNotesName = content.editorialNotesFromData(objectGraph, category, "name");
            result.set(app.adamId, editorialNotesName);
        }
        return result;
    }
    shelfTitle(objectGraph, subscriptionStatus) {
        return objectGraph.loc.string(subscriptionStatus === "new" ? "Arcade.DownloadPack.ShelfTitle.NewUser" : "Arcade.DownloadPack.ShelfTitle");
    }
    shelfMetrics(title, shelfToken) {
        return {
            id: shelfToken.id,
            kind: null,
            softwareType: "Arcade",
            targetType: "swoosh",
            title: title,
            pageInformation: shelfToken.metricsPageInformation,
            locationTracker: shelfToken.metricsLocationTracker,
            idType: "its_contentId",
            fcKind: shelfToken.featuredContentId,
        };
    }
}
//# sourceMappingURL=arcade-download-pack-shelf-controller.js.map