import * as validation from "@jet/environment/json/validation";
import * as models from "../../../api/models";
import * as videoDefaults from "../../../common/constants/video-constants";
import * as metricsHelpersMedia from "../../../common/metrics/helpers/media";
import * as serverData from "../../../foundation/json-parsing/server-data";
import { shallowCopyOf } from "../../../foundation/util/objects";
import * as content from "../../content/content";
import { addMetricsEventsToPageWithInformation, fakeMetricsPageInformation } from "../../metrics/helpers/page";
import * as productPageVariants from "../product-page-variants";
import { ProductPageSectionMapping } from "../shelf-based/product-page-section-mapping";
import * as videoShelf from "./video-shelf";
import { isSome } from "@jet/environment";
const productMediaShelfPrefix = "product_media";
export function isProductMediaShelf(shelf) {
    var _a;
    return isSome(shelf) && ((_a = shelf.id) === null || _a === void 0 ? void 0 : _a.indexOf(productMediaShelfPrefix)) > -1;
}
export function create(objectGraph, data, clientIdentifierOverride, shelfMetrics) {
    return validation.context("productMediaShelves", () => {
        if (serverData.isNullOrEmpty(data)) {
            return null;
        }
        // <rdar://problem/50189280> REG: tvOS: Prevent tvOS Product Pages from creating media shelves for other platforms.
        // For certain platforms, we only show app media for that platform only.
        const includedAppPlatformsForProductMedia = includedAppPlatformsForProductMediaOnDevice(objectGraph, objectGraph.client.deviceType);
        // rdar://59908940 (CrashTracer: AppStore at AppStore: specialized static AnyComponentView.shelfLayout)
        // On TV / Watch, restrict the video previews to the client platform only.
        const includedAppPlatformsForPlatformVideoPreviews = includedAppPlatformsForPlatformVideoPreviewsOnDevice(objectGraph, objectGraph.client.deviceType);
        // Find all media
        const productVariantData = productPageVariants.productVariantDataForData(objectGraph, data);
        const allProductMedia = content.productMediaFromData(objectGraph, data, 11 /* content.ArtworkUseCase.ProductPageScreenshots */, includedAppPlatformsForProductMedia, productVariantData, clientIdentifierOverride);
        const platformVideoPreviews = content.platformVideoPreviewFromData(objectGraph, data, videoDefaults.defaultVideoConfiguration(objectGraph), includedAppPlatformsForPlatformVideoPreviews);
        // Find the first platform that has a video.
        let screenshotMediaWithCorrespondingVideo = null;
        if (platformVideoPreviews) {
            for (const screenshotMedia of allProductMedia) {
                if (screenshotMedia.mediaPlatform.isEqualTo(platformVideoPreviews.mediaPlatform)) {
                    screenshotMediaWithCorrespondingVideo = screenshotMedia;
                    break;
                }
            }
        }
        // For phone screenshots or on visionOS, we show the video(s) inline with the screenshots if-and-only-if the aspect ratios are
        // the same. Therefore, we store the prevailing aspect ratio of the screenshots that has a video.
        let overridingAspectRatio = null;
        if (screenshotMediaWithCorrespondingVideo) {
            const targetAppPlatform = screenshotMediaWithCorrespondingVideo.mediaPlatform.appPlatform;
            if (objectGraph.client.isVision || targetAppPlatform === "phone" || targetAppPlatform === "messages") {
                for (const item of screenshotMediaWithCorrespondingVideo.items) {
                    const screenshot = item.screenshot;
                    overridingAspectRatio = screenshot.width / screenshot.height;
                    if (overridingAspectRatio < 1) {
                        break;
                    }
                }
            }
        }
        // Determine which videos are eligible to be collapsed with screenshots.
        const collapsedVideoItems = [];
        const separatedVideos = [];
        if (screenshotMediaWithCorrespondingVideo && platformVideoPreviews && platformVideoPreviews.videos) {
            for (const video of platformVideoPreviews.videos) {
                const videoItem = new models.ProductMediaItem();
                videoItem.video = video;
                const videoAspectRatio = video.preview.width / video.preview.height;
                const isMatchingAspectRatio = overridingAspectRatio === null || Math.abs(videoAspectRatio - overridingAspectRatio) < 0.01;
                const isMatchingAppPlatform = screenshotMediaWithCorrespondingVideo.mediaPlatform.isEqualTo(platformVideoPreviews.mediaPlatform);
                if (isMatchingAspectRatio && isMatchingAppPlatform) {
                    collapsedVideoItems.push(videoItem);
                }
                else {
                    separatedVideos.push(video);
                }
                const metricsOptions = {
                    pageInformation: shelfMetrics.metricsPageInformation,
                    locationTracker: shelfMetrics.locationTracker,
                    id: data.id,
                    isAdvert: shelfMetrics.metricsPageInformation.iAdInfo
                        ? shelfMetrics.metricsPageInformation.iAdInfo.iAdIsPresent
                        : false,
                };
                metricsHelpersMedia.addMetricsEventsToVideo(objectGraph, video, metricsOptions);
            }
        }
        // Collapse the eligible videos into the first media row.
        if (screenshotMediaWithCorrespondingVideo) {
            screenshotMediaWithCorrespondingVideo.items = collapsedVideoItems.concat(screenshotMediaWithCorrespondingVideo.items);
        }
        let sectionMappings = [];
        let shelfMapping = {};
        for (let index = 0; index < allProductMedia.length; index++) {
            const productMedia = allProductMedia[index];
            const shelfId = `${productMediaShelfPrefix}_${productMedia.mediaPlatform.appPlatform}_${productMedia.mediaPlatform.supplementaryAppPlatforms.join("_")}`;
            sectionMappings.push(new ProductPageSectionMapping("shelf", shelfId));
            const mediaShelf = new models.Shelf("productMediaItem", null, productMedia.items);
            mediaShelf.isHorizontal = true;
            let hasPortraitMedia = false;
            let mediaAspectRatio = aspectRatioForMediaItem(objectGraph, productMedia.items[0]);
            for (const mediaItem of productMedia.items) {
                if ((serverData.isDefinedNonNullNonEmpty(mediaItem.screenshot) && mediaItem.screenshot.isPortrait()) ||
                    (serverData.isDefinedNonNullNonEmpty(mediaItem.video) && mediaItem.video.preview.isPortrait())) {
                    mediaAspectRatio = aspectRatioForMediaItem(objectGraph, mediaItem);
                    hasPortraitMedia = true;
                    break;
                }
            }
            mediaShelf.contentsMetadata = {
                type: "productMedia",
                platform: productMedia.mediaPlatform,
                allPlatforms: productMedia.allPlatforms,
                platformDescription: productMedia.platformDescription,
                allPlatformsDescription: productMedia.allPlatformsDescription,
                allPlatformsDescriptionPlacement: productMedia.allPlatformsDescriptionPlacement,
                hasPortraitMedia: hasPortraitMedia,
                expandProductMediaAction: null,
                viewProductMediaGalleryAction: createViewProductMediaGalleryAction(objectGraph, productMedia, data.id),
                aspectRatio: mediaAspectRatio,
            };
            shelfMetrics.addImpressionsToShelf(objectGraph, mediaShelf, "screenshots");
            if (index === 0 && objectGraph.client.deviceType !== "tv" && !objectGraph.client.isWeb) {
                mediaShelf.title = objectGraph.loc.string("ProductPage.Section.ScreenshotsPreview.Title");
            }
            shelfMapping[shelfId] = mediaShelf;
        }
        if (objectGraph.client.isVision && sectionMappings.length > 1) {
            const firstSectionMapping = sectionMappings[0];
            const mediaShelf = shelfMapping[firstSectionMapping.shelfId];
            if (mediaShelf.contentsMetadata.type === "productMedia") {
                mediaShelf.contentsMetadata.expandProductMediaAction = createExpandProductMediaAction(objectGraph, sectionMappings, shelfMapping);
            }
            // Now that we've created the expand action, we can strip out the other product media shelves,
            // as we will only be displaying the first in the non-expanded state.
            sectionMappings = [firstSectionMapping];
            const firstShelf = shelfMapping[firstSectionMapping.shelfId];
            shelfMapping = {
                [firstSectionMapping.shelfId]: firstShelf,
            };
        }
        // Videos that stay in the Videos Shelf
        if (separatedVideos.length > 0) {
            shelfMapping["videos"] = videoShelf.create(objectGraph, separatedVideos, shelfMetrics);
        }
        return {
            sectionMappings: sectionMappings,
            shelfMapping: shelfMapping,
            allProductMedia: allProductMedia,
        };
    });
}
/**
 * Returns the list of included app platforms for the product media shelves.
 * This is used to constrain some platforms to media type of just that platform, e.g. tvOS can only show tvOS screenshots and video.
 *
 * @param deviceType Device type to find the included app platforms for product media for.
 * @returns models.AppPlatform[] | null An array of supported app platforms for product media, or `null` if there are no constraints and should fallback to sorting logic in content.ts
 */
export function includedAppPlatformsForProductMediaOnDevice(objectGraph, deviceType) {
    // We want to return all product media platforms, so that we can generate
    // the appropriate platform selector description text.
    return null;
}
/**
 * Returns the list of included app platforms for the platform video previews
 * This is used to constrain some platforms to video previews of just that platform, e.g. tvOS can only show tvOS video previews.
 *
 * @param deviceType Device type to determine to app platforms we allow video previews for.
 * @returns models.AppPlatform[] | null An array of supported app platforms for video previews, or `null` if there are no constraints
 */
function includedAppPlatformsForPlatformVideoPreviewsOnDevice(objectGraph, deviceType) {
    if (objectGraph.client.isTV || objectGraph.client.isWatch) {
        return [content.currentAppPlatform(objectGraph)];
    }
    return null;
}
/**
 * Creates a flow action for navigating to the expanded product media page.
 *
 * @param objectGraph
 * @param sectionMappings The product media section mappings array
 * @param shelfMapping The product media shelf mapping
 * @returns A flow action
 */
function createExpandProductMediaAction(objectGraph, sectionMappings, shelfMapping) {
    if (!objectGraph.client.isVision || sectionMappings.length <= 1) {
        return null;
    }
    const expandedShelves = [];
    for (const sectionMapping of sectionMappings) {
        const shelf = shelfMapping[sectionMapping.shelfId];
        const expandedShelf = shallowCopyOf(shelf);
        expandedShelf.title = null;
        expandedShelf.contentsMetadata = shallowCopyOf(shelf.contentsMetadata);
        if (expandedShelf.contentsMetadata.type === "productMedia") {
            expandedShelf.contentsMetadata.expandProductMediaAction = null;
        }
        expandedShelves.push(expandedShelf);
    }
    const page = new models.GenericPage(expandedShelves);
    page.title = objectGraph.loc.string("PRODUCT_PREVIEWS_TITLE");
    const flowAction = new models.FlowAction("page");
    flowAction.pageData = page;
    flowAction.title = page.title;
    return flowAction;
}
/**
 * Creates a flow action for navigating to the product media gallery page.
 *
 * @param objectGraph Current object graph
 * @param productMedia The product media object that contains the media items to display
 * @param productId The id of the owning product
 * @returns A flow action
 */
function createViewProductMediaGalleryAction(objectGraph, productMedia, productId) {
    if (!objectGraph.client.isVision && !objectGraph.featureFlags.isEnabled("tv_product_page_2024E")) {
        return null;
    }
    const page = new models.ProductMediaGalleryPage(productMedia);
    const pageInformation = fakeMetricsPageInformation(objectGraph, "ProductMediaGallery", productId, "");
    addMetricsEventsToPageWithInformation(objectGraph, page, pageInformation);
    const flowAction = new models.FlowAction("productMediaGallery");
    flowAction.pageData = page;
    return flowAction;
}
/**
 * Determines the aspect ratio for a given ProductMediaItem
 *
 * @param objectGraph Current object graph
 * @param mediaItem The media item
 * @returns An aspect ratio determined by width / height
 */
function aspectRatioForMediaItem(objectGraph, mediaItem) {
    var _a;
    if (serverData.isNull(mediaItem)) {
        return 1.0;
    }
    if (serverData.isDefinedNonNull((_a = mediaItem.video) === null || _a === void 0 ? void 0 : _a.preview) && mediaItem.video.preview.height > 0) {
        return mediaItem.video.preview.width / mediaItem.video.preview.height;
    }
    if (serverData.isDefinedNonNull(mediaItem.screenshot) && mediaItem.screenshot.height > 0) {
        return mediaItem.screenshot.width / mediaItem.screenshot.height;
    }
    return 1.0;
}
//# sourceMappingURL=product-media-shelf.js.map