import { isNothing, isSome } from "@jet/environment";
import { Video } from "../../../api/models";
import { asDictionary, asNumber, asString } from "../../../foundation/json-parsing/server-data";
import { editorialCardFromData } from "../../../foundation/media/associations";
import * as mediaAttributes from "../../../foundation/media/attributes";
import { autoPlayControls, standardControls } from "../../constants/video-constants";
import { artworkFromApiArtwork, joeColorSetFromData } from "../../content/content";
import { cardDisplayStyleFromData } from "../today-card-util";
import { TodayCardDisplayStyle } from "../today-types";
import { categoryDetailMotion16x9Configuration, categoryDetailStatic16x9Configuration, dayCardConfiguration, eventCardConfiguration, generalCardConfiguration, listCardMotion21x9Configuration, listCardStatic21x9Configuration, mediaCardConfiguration, storeFrontVideo4x3Configuration, storeFrontVideoConfiguration, storyCardMotion16x9Configuration, storyCardStatic16x9Configuration, storyCenteredMotion16x9Configuration, storyCenteredStatic16x9Configuration, storySearchStatic16x9Configuration, universalAConfigurations, } from "./media-configurations";
/**
 * Retrieves the artwork details for a today card. This function will determine the
 * appropriate media configuration to use based on the card display style and the
 * media data available in the card response.
 *
 * @param objectGraph - The object graph of the app store.
 * @param data - The media data.
 * @param cardConfig - The configuration for the today card.
 * @returns The artwork details for the today card, or undefined if no artwork is available.
 */
export function todayCardArtworkDetails(objectGraph, data, cardConfig) {
    var _a;
    // Watch uses different artwork lookup logic
    const isWebViewingWatch = objectGraph.client.isWeb && ((_a = objectGraph.activeIntent) === null || _a === void 0 ? void 0 : _a.previewPlatform) === "watch";
    if (objectGraph.client.isWatch || isWebViewingWatch) {
        return todayCardArtworkDetailsForWatch(objectGraph, data, cardConfig);
    }
    const cardDisplayStyle = cardDisplayStyleFromData(data, cardConfig.coercedCollectionTodayCardDisplayStyle);
    // Determine our preferred ranking of media flavors for the display style,
    // then get the highest ranked media available on the card response.
    const mediaSearchOrder = cardConfig.isHorizontalShelfContext
        ? horizontalShelfMediaSearchOrderForCardDisplayStyle(objectGraph, cardConfig)
        : mediaSearchOrderForCardDisplayStyle(objectGraph, cardDisplayStyle, cardConfig);
    let mediaConfigurationForCard;
    let isUsingEditorialCardOverride = false;
    const editorialCardData = editorialCardFromData(data);
    if (mediaAttributes.hasAttributes(editorialCardData)) {
        mediaConfigurationForCard = mediaSearchOrder.find((conf) => {
            return isSome(mediaAttributes.attributeAsDictionary(editorialCardData, conf.objectPath));
        });
        isUsingEditorialCardOverride = isSome(mediaConfigurationForCard);
    }
    if (isNothing(mediaConfigurationForCard)) {
        mediaConfigurationForCard = mediaSearchOrder.find((conf) => {
            return isSome(mediaAttributes.attributeAsDictionary(data, conf.objectPath));
        });
    }
    if (!mediaConfigurationForCard) {
        return undefined;
    }
    const mediaData = isUsingEditorialCardOverride
        ? mediaAttributes.attributeAsDictionary(editorialCardData, mediaConfigurationForCard.objectPath)
        : mediaAttributes.attributeAsDictionary(data, mediaConfigurationForCard.objectPath);
    if (mediaConfigurationForCard.type === "image") {
        // Return an Artwork and cardArtLayout
        const artworks = mediaConfigurationForCard.crops.map((crop) => {
            let cropCodeToUse = crop;
            if (cardConfig.isSearchContext && isSome(cardConfig.prevailingCropCodes)) {
                cropCodeToUse = cardConfig.prevailingCropCodes.defaultCrop;
            }
            else if (isSome(cardConfig.prevailingCropCodes) &&
                isSome(cardConfig.prevailingCropCodes[mediaConfigurationForCard.objectPath])) {
                cropCodeToUse = cardConfig.prevailingCropCodes[mediaConfigurationForCard.objectPath];
            }
            const artwork = artworkFromApiArtwork(objectGraph, mediaData, {
                withJoeColorPlaceholder: true,
                cropCode: cropCodeToUse,
                useCase: 15 /* ArtworkUseCase.TodayCardMedia */,
                overrideHeight: mediaConfigurationForCard.sourceHeight,
                overrideWidth: mediaConfigurationForCard.sourceWidth,
            });
            return artwork;
        });
        const joeColors = joeColorSetFromData(mediaData);
        return {
            artworks: artworks,
            videos: [],
            artworkLayoutsWithMetrics: mediaConfigurationForCard.cardArtLayoutMetrics,
            joeColors: joeColors,
        };
    }
    else {
        // Return a Video and cardArtLayout
        const previewArtworkData = asDictionary(mediaData, "previewFrame");
        // All TodayCardArtworkLayouts are specified in landscape aspect ratio,
        // but videos can come back in either landscape or portrait. If we
        // receive a portrait video, we need to flip the TodayCardArtworkLayout
        const previewArtworkWidth = asNumber(previewArtworkData, "width");
        const previewArtworkHeight = asNumber(previewArtworkData, "height");
        const isPortrait = previewArtworkHeight >= previewArtworkWidth;
        let overrideHeight = mediaConfigurationForCard.sourceHeight;
        let overrideWidth = mediaConfigurationForCard.sourceWidth;
        if (isPortrait) {
            [overrideHeight, overrideWidth] = [overrideWidth, overrideHeight];
        }
        const previewArtwork = artworkFromApiArtwork(objectGraph, previewArtworkData, {
            withJoeColorPlaceholder: true,
            cropCode: mediaConfigurationForCard.crops[0],
            useCase: 15 /* ArtworkUseCase.TodayCardMedia */,
            overrideHeight: overrideHeight,
            overrideWidth: overrideWidth,
        });
        if (isNothing(previewArtwork)) {
            return undefined;
        }
        let playbackControls = standardControls(objectGraph);
        if (isSome(cardConfig.videoPlaybackControls)) {
            playbackControls = cardConfig.videoPlaybackControls;
        }
        if (objectGraph.client.isMac) {
            playbackControls.scrubber = true;
        }
        let autoplayPlaybackControls = autoPlayControls(objectGraph);
        if (isSome(cardConfig.videoPlaybackControls)) {
            autoplayPlaybackControls = cardConfig.videoAutoplayPlaybackControls;
        }
        const videoUrl = asString(mediaData, "video");
        if (isNothing(videoUrl)) {
            return undefined;
        }
        const video = new Video(videoUrl, previewArtwork, {
            playbackControls: playbackControls,
            autoPlayPlaybackControls: autoplayPlaybackControls,
            canPlayFullScreen: cardConfig.enableFullScreenVideo,
        });
        const joeColors = joeColorSetFromData(previewArtworkData);
        return {
            artworks: [],
            videos: [video],
            artworkLayoutsWithMetrics: mediaConfigurationForCard.cardArtLayoutMetrics,
            joeColors: joeColors,
        };
    }
}
function mediaSearchOrderForCardDisplayStyle(objectGraph, cardDisplayStyle, cardConfig) {
    // Hero position, non-list card display styles, on iPad requires the UniversalA flavor artwork to be considered valid,
    // so we'll only check those 2 configurations in this scenario.
    const listCardDisplayStyles = new Set([TodayCardDisplayStyle.List, TodayCardDisplayStyle.NumberedList]);
    if (objectGraph.client.isPad && cardConfig.isHeroCard && !listCardDisplayStyles.has(cardDisplayStyle)) {
        return universalAConfigurations(objectGraph, cardConfig.isHeroCard);
    }
    switch (cardDisplayStyle) {
        case TodayCardDisplayStyle.AppEventCard:
            return [
                storyCardMotion16x9Configuration(objectGraph),
                storyCardStatic16x9Configuration(objectGraph),
                storyCenteredMotion16x9Configuration(objectGraph),
                storyCenteredStatic16x9Configuration(objectGraph),
                ...universalAConfigurations(objectGraph, cardConfig.isHeroCard),
                eventCardConfiguration(objectGraph),
            ];
        case TodayCardDisplayStyle.AppOfTheDay:
        case TodayCardDisplayStyle.GameOfTheDay:
            return [
                storyCardMotion16x9Configuration(objectGraph),
                storyCardStatic16x9Configuration(objectGraph),
                storyCenteredMotion16x9Configuration(objectGraph),
                storyCenteredStatic16x9Configuration(objectGraph),
                ...universalAConfigurations(objectGraph, cardConfig.isHeroCard),
                dayCardConfiguration(objectGraph),
            ];
        case TodayCardDisplayStyle.List:
        case TodayCardDisplayStyle.NumberedList:
            return [listCardMotion21x9Configuration(objectGraph), listCardStatic21x9Configuration(objectGraph)];
        case TodayCardDisplayStyle.ShortImage:
            if (cardConfig.isSearchContext) {
                return [
                    generalCardConfiguration(objectGraph),
                    storyCardMotion16x9Configuration(objectGraph),
                    storyCardStatic16x9Configuration(objectGraph),
                    storyCenteredMotion16x9Configuration(objectGraph),
                    storyCenteredStatic16x9Configuration(objectGraph),
                    ...universalAConfigurations(objectGraph, cardConfig.isHeroCard),
                    storeFrontVideoConfiguration(objectGraph),
                    storeFrontVideo4x3Configuration(objectGraph),
                    mediaCardConfiguration(objectGraph),
                ];
            }
            else {
                return [
                    storyCardMotion16x9Configuration(objectGraph),
                    storyCardStatic16x9Configuration(objectGraph),
                    storyCenteredMotion16x9Configuration(objectGraph),
                    storyCenteredStatic16x9Configuration(objectGraph),
                    ...universalAConfigurations(objectGraph, cardConfig.isHeroCard),
                    storeFrontVideoConfiguration(objectGraph),
                    storeFrontVideo4x3Configuration(objectGraph),
                    generalCardConfiguration(objectGraph),
                    mediaCardConfiguration(objectGraph),
                ];
            }
        case TodayCardDisplayStyle.FullBleedImage:
            const fullBleedConfigurations = [
                storyCardMotion16x9Configuration(objectGraph),
                storyCardStatic16x9Configuration(objectGraph),
                categoryDetailMotion16x9Configuration(objectGraph),
                categoryDetailStatic16x9Configuration(objectGraph),
                storyCenteredMotion16x9Configuration(objectGraph),
                storyCenteredStatic16x9Configuration(objectGraph),
                ...universalAConfigurations(objectGraph, cardConfig.isHeroCard),
                storeFrontVideoConfiguration(objectGraph),
                storeFrontVideo4x3Configuration(objectGraph),
                mediaCardConfiguration(objectGraph),
                generalCardConfiguration(objectGraph),
            ];
            if (objectGraph.client.isVision && isSome(cardConfig.isSearchContext) && cardConfig.isSearchContext) {
                fullBleedConfigurations.unshift(storySearchStatic16x9Configuration(objectGraph));
            }
            return fullBleedConfigurations;
        case TodayCardDisplayStyle.SingleApp:
        case TodayCardDisplayStyle.Video:
        default:
            const configurations = [
                storyCardMotion16x9Configuration(objectGraph),
                storyCardStatic16x9Configuration(objectGraph),
                storyCenteredMotion16x9Configuration(objectGraph),
                storyCenteredStatic16x9Configuration(objectGraph),
                ...universalAConfigurations(objectGraph, cardConfig.isHeroCard),
                storeFrontVideoConfiguration(objectGraph),
                storeFrontVideo4x3Configuration(objectGraph),
                mediaCardConfiguration(objectGraph),
                generalCardConfiguration(objectGraph),
            ];
            if (objectGraph.client.isVision && isSome(cardConfig.isSearchContext) && cardConfig.isSearchContext) {
                configurations.unshift(storySearchStatic16x9Configuration(objectGraph));
            }
            return configurations;
    }
}
function horizontalShelfMediaSearchOrderForCardDisplayStyle(objectGraph, cardConfig) {
    const searchOrder = [];
    if (objectGraph.client.isiOS || objectGraph.client.isWeb) {
        searchOrder.push(storyCenteredStatic16x9Configuration(objectGraph, ["SCS.ApDPCS01"]));
    }
    if (cardConfig.horizontalCardContentType === "largeStoryCard") {
        searchOrder.push(storeFrontVideoConfiguration(objectGraph));
    }
    const shouldUseHorizontalCardCrop = objectGraph.client.isiOS || objectGraph.client.isMac;
    searchOrder.push(mediaCardConfiguration(objectGraph, shouldUseHorizontalCardCrop ? ["sr"] : undefined), generalCardConfiguration(objectGraph, shouldUseHorizontalCardCrop ? ["sr"] : undefined));
    return searchOrder;
}
/**
 * Watch uses a more straightforward artwork lookup than other platforms.
 * @param objectGraph The AppStoreObjectGraph
 * @param data MAPI data for a Today Card
 * @param cardConfig The TodayCardConfiguration
 * @returns TodayCardArtworkDetails appropriate for display on Apple Watch
 */
function todayCardArtworkDetailsForWatch(objectGraph, data, cardConfig) {
    var _a, _b;
    const mediaData = mediaAttributes.attributeAsDictionary(data, "editorialArtwork.subscriptionHero");
    const artwork = artworkFromApiArtwork(objectGraph, mediaData, {
        withJoeColorPlaceholder: true,
        cropCode: (_b = (_a = cardConfig.prevailingCropCodes) === null || _a === void 0 ? void 0 : _a.defaultCrop) !== null && _b !== void 0 ? _b : "SH.ApHXS01",
        useCase: 15 /* ArtworkUseCase.TodayCardMedia */,
    });
    const joeColors = joeColorSetFromData(mediaData);
    // Don't return an array containing `undefined`
    const artworks = isSome(artwork) ? [artwork] : [];
    return {
        artworks: artworks,
        videos: [],
        artworkLayoutsWithMetrics: [],
        joeColors: joeColors,
    };
}
//# sourceMappingURL=today-artwork-util.js.map