import * as validation from "@jet/environment/json/validation";
import { Shelf, Trailers, Video, } from "../../api/models";
import { metricsFromMediaApiObject, } from "../../foundation/media/data-structure";
import { hasAttributes } from "../../foundation/media/attributes";
import { isDefinedNonNullNonEmpty, isNullOrEmpty } from "../../foundation/json-parsing/server-data";
import { Parameters, Path, Protocol } from "../../foundation/network/url-constants";
import { URL } from "../../foundation/network/urls";
import * as lockups from "../../common/lockups/lockups";
import * as metricsHelpersImpressions from "../../common/metrics/helpers/impressions";
import * as videoDefaults from "../../common/constants/video-constants";
import * as content from "../../common/content/content";
import { newLocationTracker, nextPosition, popLocation, pushContentLocation, } from "../metrics/helpers/location";
export function createArcadeSeeAllGamesPaginationToken(_objectGraph, requestDescriptor, pageInformation) {
    const locationTracker = newLocationTracker();
    const paginationUrl = URL.fromComponents(Protocol.internal, null, `/${Path.arcadeSeeAllGames}/${Path.arcadeSeeAllGamesLoadMore}`).build();
    const paginationToken = {
        url: paginationUrl,
        metricsPageInformation: pageInformation,
        metricsLocationTracker: locationTracker,
        remainingGroups: [],
        lastShelfIndex: 0,
        isCompactMode: requestDescriptor.isCompactMode,
    };
    return paginationToken;
}
export function createShelves(objectGraph, groups, paginationToken) {
    return validation.context("createShelves", () => {
        const shelves = [];
        if (groups.length === 0) {
            return shelves;
        }
        let shouldStartPagination = false;
        for (const group of groups) {
            // Start pagination if we hit a group who's first item has not been hydrated
            shouldStartPagination = shouldStartPagination || !hasAttributes(group.data[0]);
            if (shouldStartPagination) {
                paginationToken.remainingGroups.push(group);
            }
            else {
                const shelfToken = {
                    index: paginationToken.lastShelfIndex,
                    title: shelfTitleForGroup(objectGraph, group),
                    contentType: shelfContentTypeForMode(objectGraph, paginationToken.isCompactMode),
                    shouldFilter: false,
                    remainingContent: group.data,
                    groupKind: group.kind,
                    isCompactMode: paginationToken.isCompactMode,
                    hasExistingContent: false,
                    isFirstRender: true,
                    metricsPageInformation: paginationToken.metricsPageInformation,
                    metricsLocationTracker: paginationToken.metricsLocationTracker,
                };
                const shelf = createShelf(objectGraph, shelfToken);
                shelves.push(shelf);
                paginationToken.lastShelfIndex++;
            }
        }
        return shelves;
    });
}
const defaultRowsPerColumn = 3;
export function createShelf(objectGraph, shelfToken) {
    const shelfItems = [];
    const shelf = new Shelf(shelfToken.contentType);
    shelf.title = shelfToken.title;
    shelf.presentationHints = { showSupplementaryText: false };
    if (objectGraph.client.isVision) {
        shelf.isHorizontal =
            (shelfToken.groupKind === "comingSoonGrouping" && !shelfToken.isCompactMode) ||
                shelfToken.groupKind === "category";
        shelf.presentationHints = {
            ...shelf.presentationHints,
            isSAGComingSoon: true,
        };
    }
    else {
        shelf.isHorizontal = shelfToken.groupKind === "comingSoonGrouping" || shelfToken.groupKind === "category";
    }
    const shelfMetricsOptions = {
        id: `${shelfToken.index}`,
        kind: null,
        softwareType: null,
        targetType: "swoosh",
        title: shelf.title,
        pageInformation: shelfToken.metricsPageInformation,
        locationTracker: shelfToken.metricsLocationTracker,
        idType: "sequential",
    };
    /// add impression fields
    metricsHelpersImpressions.addImpressionFields(objectGraph, shelf, shelfMetricsOptions);
    pushContentLocation(objectGraph, shelfMetricsOptions, shelf.title);
    while (isDefinedNonNullNonEmpty(shelfToken.remainingContent) && hasAttributes(shelfToken.remainingContent[0])) {
        const lockupData = shelfToken.remainingContent.shift();
        const lockupOptions = {
            metricsOptions: {
                pageInformation: shelfToken.metricsPageInformation,
                locationTracker: shelfToken.metricsLocationTracker,
                recoMetricsData: metricsFromMediaApiObject(lockupData),
            },
            artworkUseCase: 1 /* content.ArtworkUseCase.LockupIconSmall */,
            canDisplayArcadeOfferButton: content.shelfContentTypeCanDisplayArcadeOfferButtons(objectGraph, shelfToken.contentType),
            shouldHideArcadeHeader: objectGraph.featureFlags.isEnabled("hide_arcade_header_on_arcade_tab"),
            isContainedInPreorderExclusiveShelf: shelfToken.groupKind === "comingSoonGrouping",
        };
        const cropCode = objectGraph.client.isVision ? "sr" : null;
        const lockup = lockups.mixedMediaLockupFromData(objectGraph, lockupData, lockupOptions, videoDefaults.defaultVideoConfiguration(objectGraph), null, cropCode);
        const lockupHasVideos = ensureLockupHasVideos(objectGraph, lockup, lockupData);
        if (!lockupHasVideos) {
            continue;
        }
        lockup.editorialTagline = null;
        lockup.developerTagline = null;
        shelfItems.push(lockup);
        nextPosition(shelfToken.metricsLocationTracker);
    }
    shelf.mergeWhenFetched = shelfToken.hasExistingContent;
    shelfToken.hasExistingContent = shelfToken.hasExistingContent || shelfItems.length > 0;
    shelf.items = shelfItems;
    if (isDefinedNonNullNonEmpty(shelfToken.remainingContent)) {
        shelf.url = shelfUrlForToken(shelfToken);
    }
    else if (objectGraph.client.deviceType !== "tv" &&
        shelfToken.isCompactMode &&
        shelf.items.length < defaultRowsPerColumn) {
        shelf.rowsPerColumn = shelf.items.length;
    }
    popLocation(shelfToken.metricsLocationTracker);
    return shelf;
}
function shelfContentTypeForMode(objectGraph, isCompactMode) {
    if (isCompactMode) {
        return "smallLockup";
    }
    else if (objectGraph.client.isTV) {
        return "mixedMediaLockup";
    }
    else {
        return "appTrailerLockup";
    }
}
function shelfTitleForGroup(objectGraph, group) {
    let shelfTitle;
    let dateComponents = null;
    let groupDateForTitle = null;
    let sentence;
    // rdar://104719340 (Arcade See All Games section has a missing name)
    // Temporary(?) work around for MAPI sometimes not returning a group.name
    if ((!group.name || group.name.length === 0) && group.kind !== "comingSoonGrouping") {
        return "";
    }
    switch (group.kind) {
        case "releaseDateByDay":
            dateComponents = group.name.split("-");
            groupDateForTitle = new Date(parseInt(dateComponents[0]), parseInt(dateComponents[1]) - 1, parseInt(dateComponents[2]));
            sentence = objectGraph.loc.string("ALL_GAMES_SECTION_TITLE_RELEASE_DATE_SENTENCE");
            shelfTitle = objectGraph.loc.formatDateInSentence(sentence, "MMMM d, y", groupDateForTitle);
            break;
        case "lastUpdatedByDay":
            dateComponents = group.name.split("-");
            groupDateForTitle = new Date(parseInt(dateComponents[0]), parseInt(dateComponents[1]) - 1, parseInt(dateComponents[2]));
            sentence = objectGraph.loc.string("ALL_GAMES_SECTION_TITLE_LAST_UPDATED_SENTENCE");
            shelfTitle = objectGraph.loc.formatDateInSentence(sentence, "MMMM d, y", groupDateForTitle);
            break;
        case "comingSoonGrouping":
            shelfTitle = objectGraph.loc.string("Arcade.SeeAllGames.ComingSoonShelf.Title");
            break;
        default:
            shelfTitle = group.name;
            break;
    }
    return shelfTitle;
}
function shelfUrlForToken(shelfToken) {
    if (isNullOrEmpty(shelfToken.remainingContent)) {
        return null;
    }
    return `${Protocol.internal}:/${Path.arcadeSeeAllGames}/${Path.shelf}/?${Parameters.token}=${encodeURIComponent(JSON.stringify(shelfToken))}`;
}
// region Fallback Data
function ensureLockupHasVideos(objectGraph, lockup, lockupData) {
    // In visionOS, the bin-compat apps usually have trailer from iPad which using 4:3 video
    // But SAG lockup preferred 16:9 video, so even we already have lockup.trailers, we still want to override it
    // with the editorial splash video `splashVideo16x9`.
    // If there is no editorial splash video found, we fallback to the current `lockup.trailers` or create a dump video.
    if (isNullOrEmpty(lockup.trailers) || objectGraph.client.isVision) {
        const uberVideo = content.editorialSplashVideoFromData(objectGraph, lockupData);
        if (isDefinedNonNullNonEmpty(uberVideo)) {
            const uberTrailer = new Trailers();
            uberVideo.playbackControls = videoDefaults.standardControls(objectGraph);
            uberVideo.autoPlayPlaybackControls = videoDefaults.autoPlayControls(objectGraph);
            uberVideo.canPlayFullScreen = true;
            uberTrailer.videos = [uberVideo];
            lockup.trailers = [uberTrailer];
        }
    }
    if (isNullOrEmpty(lockup.trailers)) {
        /**
         * <rdar://problem/55328972> See All Games: Bring back screenshots
         * In the very rare case that an arcade game has absolutely no videos,
         * that means no app trailer, no editorial video in any form. We're going to create a fake
         * video that uses the first screenshot as a preview frame. This allows us to
         * use the same AppTrailersLockup and get uniform sizing for lockups.
         */
        addFakeVideoToMixedMediaLockup(lockup);
    }
    return isDefinedNonNullNonEmpty(lockup.trailers);
}
const fakeVideoURL = "x-as3-internal:/today/test";
function addFakeVideoToMixedMediaLockup(lockup) {
    const screenshots = lockup.screenshots[0];
    if (isNullOrEmpty(screenshots)) {
        return;
    }
    const firstScreenshot = screenshots.artwork[0];
    const fakeVideo = new Video(fakeVideoURL, firstScreenshot, {
        allowsAutoPlay: false,
        looping: false,
        canPlayFullScreen: false,
        autoPlayPlaybackControls: {},
        playbackControls: {},
    });
    const fakeTrailers = new Trailers();
    fakeTrailers.videos = [fakeVideo];
    lockup.trailers = [fakeTrailers];
}
// endregion
//# sourceMappingURL=render-arcade-see-all-games-page.js.map