//
//  sharing.ts
//  AppStoreKit
//
//  Created by Sam Vafaee on 6/16/17.
//  Copyright (c) 2016 Apple Inc. All rights reserved.
//
import { isNothing, isSome } from "@jet/environment";
import * as validation from "@jet/environment/json/validation";
import * as models from "../api/models";
import * as serverData from "../foundation/json-parsing/server-data";
import * as mediaAttributes from "../foundation/media/attributes";
import { Parameters, ShareURLParameters } from "../foundation/network/url-constants";
import * as urls from "../foundation/network/urls";
import * as dateUtil from "../foundation/util/date-util";
import * as client from "../foundation/wrappers/client";
import * as contentArtwork from "./content/artwork/artwork";
import * as contentAttributes from "./content/attributes";
import * as content from "./content/content";
import * as metricsHelpersClicks from "./metrics/helpers/clicks";
import * as offers from "./offers/offers";
import { productVariantDataForData, productVariantIDForVariantData } from "./product-page/product-page-variants";
import { cardDisplayStyleFromData, editorialArtKeyPathForCardDisplayStyle, todayCardArtworkFromArtworkData, todayCardHeroArtForData, } from "./today/today-card-util";
import { HeroMediaDisplayContext } from "./today/today-types";
import { dataHasDeviceFamily, dataOnlyHasDeviceFamily } from "./content/device-family";
// region Data helpers
export function adamIdForShareSheetGiftActivityFromProductData(objectGraph, data) {
    if (!objectGraph.bag.isContentGiftingEnabled) {
        return null;
    }
    if (serverData.isNull(data)) {
        return null;
    }
    const offer = offers.offerDataFromData(objectGraph, data);
    if (serverData.isNull(offer)) {
        return null;
    }
    // Disable gifting for pre-orders
    const isPreorder = mediaAttributes.attributeAsBoolean(data, "isPreorder");
    if (isPreorder) {
        return null;
    }
    const price = serverData.asNumber(offer, "price");
    if (price > 0) {
        return data.id;
    }
    return null;
}
/**
 * Return the url for sharing for given product
 * @param objectGraph Dependency soup
 * @param data Apps Resource data for product
 */
function shareUrlForProductData(objectGraph, data, urlKey) {
    const rawUrl = mediaAttributes.attributeAsString(data, urlKey);
    if (serverData.isNullOrEmpty(rawUrl)) {
        return null;
    }
    const url = new urls.URL(rawUrl);
    // Add client specifier to url so apps are shown in the same client they were shared from
    let clientSpecifier = null;
    const clientIdentifier = objectGraph.host.clientIdentifier;
    switch (clientIdentifier) {
        case client.messagesIdentifier:
            clientSpecifier = "messages";
            break;
        case client.watchIdentifier:
            clientSpecifier = "watch";
            break;
        default:
            break;
    }
    if (clientSpecifier) {
        url.param(ShareURLParameters.clientSpecifier, clientSpecifier);
    }
    // Custom product page variant id must be added to `url` for MAPI resource caching constraints.
    const productVariantData = productVariantDataForData(objectGraph, data);
    const productVariantID = productVariantIDForVariantData(productVariantData);
    if (serverData.isDefinedNonNull(productVariantID)) {
        url.param(Parameters.productVariantID, productVariantID);
    }
    return url.toString();
}
function notesMetadataFromProductData(objectGraph, data) {
    return validation.context("notesMetadataFromProductData", () => {
        var _a;
        if (serverData.isNull(data)) {
            return null;
        }
        const itemName = mediaAttributes.attributeAsString(data, "name");
        // Require name
        if (isNothing(itemName) || itemName.length === 0) {
            return null;
        }
        const url = shareUrlForProductData(objectGraph, data, "url");
        const developer = mediaAttributes.attributeAsString(data, "artistName");
        const category = mediaAttributes.attributeAsString(data, "genreNames.0");
        const fileSize = (_a = content.combinedFileSizeFromData(objectGraph, data)) === null || _a === void 0 ? void 0 : _a.fileSizeByDevice;
        let mediaType;
        switch (data.type) {
            case "apps": {
                mediaType = "app";
                break;
            }
            case "app-bundles": {
                mediaType = "bundle";
                break;
            }
            case "in-apps": {
                mediaType = "iap";
                break;
            }
            default: {
                mediaType = null;
            }
        }
        return new models.ShareSheetNotesMetadata(itemName, url, developer, category, fileSize, mediaType);
    });
}
function copyLinkShareSheetActivityForURL(objectGraph, url, title) {
    if (serverData.isNullOrEmpty(url)) {
        return null;
    }
    const copyTextAction = new models.CopyTextAction(url);
    copyTextAction.title = title !== null && title !== void 0 ? title : objectGraph.loc.string("ShareSheet.CopyLink.Title");
    copyTextAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://link");
    const copyLinkActionActivity = new models.ShareSheetActivity("com.apple.AppStore.copyLinkActivity", copyTextAction);
    return copyLinkActionActivity;
}
function openInGameCenterShareSheetActivityForURL(url, title) {
    if (serverData.isNullOrEmpty(url)) {
        return undefined;
    }
    const openURLAction = new models.ExternalUrlAction(url);
    openURLAction.title = title;
    const activity = new models.ShareSheetActivity("com.apple.AppStore.openInGameCenterActivity", openURLAction);
    return activity;
}
// endregion
// region Article
export function shareSheetDataForArticle(objectGraph, text, url, shortUrl, articleArtwork, data) {
    // Sharing is currently not supported on watchOS.
    if (serverData.isNull(data) || objectGraph.client.isWatch) {
        return null;
    }
    return validation.context("shareSheetDataForArticle", () => {
        let artwork = articleArtwork;
        if (isNothing(artwork) && isSome(data)) {
            artwork = shareSheetArtForData(objectGraph, data);
        }
        const subtitle = objectGraph.loc.string("ShareSheet.Story.Subtitle");
        const articleMetadata = new models.ShareSheetArticleMetadata(data.id, text, subtitle, artwork);
        return new models.ShareSheetData(articleMetadata, url, shortUrl);
    });
}
/**
 * Determines the artwork to use in share sheets.
 * @param {Data} data The data from which to retrieve the artwork.
 * @returns {Artwork} The artwork suitable for display in the share sheet.
 */
export function shareSheetArtForData(objectGraph, data) {
    const cardDisplayStyle = cardDisplayStyleFromData(data);
    if (!objectGraph.client.isVision && !preprocessor.GAMES_TARGET) {
        const heroArt = todayCardHeroArtForData(objectGraph, data, HeroMediaDisplayContext.Article, cardDisplayStyle);
        if (serverData.isDefinedNonNull(heroArt)) {
            return heroArt;
        }
    }
    let cropCode;
    if (objectGraph.client.isVision) {
        cropCode = "SCS.ApDPCS01";
    }
    const artKeyPath = editorialArtKeyPathForCardDisplayStyle(objectGraph, cardDisplayStyle);
    return todayCardArtworkFromArtworkData(objectGraph, mediaAttributes.attributeAsDictionary(data, artKeyPath), cropCode);
}
export function shareSheetActivitiesForArticle(objectGraph, shareUrl, todayCardPreviewUrl, storyID) {
    const shareSheetActivities = [];
    if ((shareUrl === null || shareUrl === void 0 ? void 0 : shareUrl.length) > 0) {
        const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareUrl);
        if (serverData.isDefinedNonNull(copyLinkActivity)) {
            shareSheetActivities.push(copyLinkActivity);
        }
    }
    if ((todayCardPreviewUrl === null || todayCardPreviewUrl === void 0 ? void 0 : todayCardPreviewUrl.length) > 0) {
        const copyCardPreviewLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, todayCardPreviewUrl, "Copy Card Preview Link");
        if (serverData.isDefinedNonNull(copyCardPreviewLinkActivity)) {
            shareSheetActivities.push(copyCardPreviewLinkActivity);
        }
    }
    if (isSome(storyID)) {
        let activity;
        if (objectGraph.featureFlags.isGSEUIEnabled("de7bbd8e") &&
            objectGraph.featureFlags.isEnabled("open_in_story_share_sheet")) {
            activity = openInGameCenterShareSheetActivityForURL(`games:///story/id${storyID}`, objectGraph.loc.string("ShareSheet.OpenInGameCenter.Title"));
        }
        if (serverData.isDefinedNonNull(activity)) {
            shareSheetActivities.push(activity);
        }
    }
    return shareSheetActivities;
}
// endregion
// region App Events
export function shareSheetDataForAppEvent(objectGraph, text, subtitle, url, shortUrl, appEventArtwork) {
    return validation.context("shareSheetDataForAppEvent", () => {
        const artwork = appEventArtwork;
        const appEventMetadata = new models.ShareSheetAppEventMetadata(text, subtitle, artwork);
        return new models.ShareSheetData(appEventMetadata, url, shortUrl);
    });
}
export function shareSheetActivitiesForAppEvent(objectGraph, appEvent, shareUrl) {
    var _a;
    const shareSheetActivities = [];
    // Copy link action
    if ((shareUrl === null || shareUrl === void 0 ? void 0 : shareUrl.length) > 0) {
        const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareUrl);
        if (serverData.isDefinedNonNull) {
            shareSheetActivities.push(copyLinkActivity);
        }
    }
    // If the event has already started, remove the option to create a calendar event
    if (appEvent.startDate.getTime() <= Date.now()) {
        return shareSheetActivities;
    }
    // Creating events is not supported in the product page extension
    if (objectGraph.host.clientIdentifier === client.productPageExtensionIdentifier) {
        return shareSheetActivities;
    }
    // Not authorized action
    const notAuthorizedAction = new models.AlertAction("default");
    notAuthorizedAction.title = objectGraph.loc.string("APP_EVENTS_CALENDAR_NOT_AUTHORIZED_TITLE");
    notAuthorizedAction.message = objectGraph.loc.string("APP_EVENTS_CALENDAR_NOT_AUTHORIZED_DETAIL");
    notAuthorizedAction.isCancelable = true;
    notAuthorizedAction.buttonTitles = [objectGraph.loc.string("ACTION_SETTINGS")];
    // NOTE: This URL only works on iOS. If this feature is expanded beyond iOS, this code will need to be split per-platform.
    notAuthorizedAction.buttonActions = [new models.ExternalUrlAction("prefs:root=Privacy&path=CALENDARS", true)];
    let isAllDay = false;
    if (serverData.isDefinedNonNull(appEvent.endDate)) {
        // If the start and end date are > 6 hours apart, and spans over multiple days, then mark as all-day
        const startMidnight = dateUtil.convertLocalDateToLocalMidnight(appEvent.startDate);
        const endMidnight = dateUtil.convertLocalDateToLocalMidnight(appEvent.endDate);
        const difference = appEvent.endDate.getTime() - appEvent.startDate.getTime();
        const sixHoursDifference = 1000 * 60 * 60 * 6;
        if (endMidnight.getTime() > startMidnight.getTime() && difference > sixHoursDifference) {
            isAllDay = true;
        }
        // If the start and end date are on the same day, and the event runs for 23 hours & 59 mins
        // then mark as all-day. This effectively ignores the seconds portion as calendar ignores
        // this anyway.
        const fullDayDifference = 1000 * 60 * 60 * 23 + 1000 * 60 * 59;
        if (startMidnight.getTime() === endMidnight.getTime() && difference >= fullDayDifference) {
            isAllDay = true;
        }
    }
    // Create calendar event activity
    const createCalendarEventAction = new models.CreateCalendarEventAction(appEvent.startDate, appEvent.endDate, isAllDay, appEvent.title, (_a = appEvent.lockup) === null || _a === void 0 ? void 0 : _a.title, appEvent.detail, shareUrl, notAuthorizedAction, "free");
    createCalendarEventAction.title = objectGraph.loc.string("SHARE_SHEET_ADD_TO_CALENDAR");
    createCalendarEventAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://calendar.circle");
    const createCalendarEventActivity = new models.ShareSheetActivity("com.apple.AppStore.createCalendarEventActivity", createCalendarEventAction);
    // Create Calendar Event should be at the beginning.
    shareSheetActivities.unshift(createCalendarEventActivity);
    return shareSheetActivities;
}
// endregion
// region Products
export function shareSheetDataForProductFromProductData(objectGraph, data, clientIdentifierOverride) {
    return validation.context("shareSheetDataForProductFromProductData", () => {
        // Sharing is currently not supported on watchOS or the web client.
        if (serverData.isNull(data) || objectGraph.client.isWatch || objectGraph.client.isWeb) {
            return null;
        }
        // required attributes
        const url = shareUrlForProductData(objectGraph, data, "url");
        const title = mediaAttributes.attributeAsString(data, "name");
        const developerName = mediaAttributes.attributeAsString(data, "artistName");
        const adamId = data.id;
        const storeFrontIdentifier = objectGraph.client.storefrontIdentifier;
        // Sanity check
        if (!url || !title || !developerName || !adamId) {
            return null;
        }
        // optional attributes
        const shortUrl = shareUrlForProductData(objectGraph, data, "shortUrl");
        let artwork = null;
        let notesMetadata = null;
        const screenshots = content.screenshotsFromData(objectGraph, data, 4 /* content.ArtworkUseCase.LockupScreenshots */);
        const videos = content.videoPreviewsFromData(objectGraph, data);
        const subtitle = contentAttributes.contentAttributeAsString(objectGraph, data, "subtitle") || developerName;
        const genreName = null;
        const isMessagesOnlyApp = false;
        const messagesAppIcon = null;
        // Platform
        let platform;
        const isMacOnlyApp = dataOnlyHasDeviceFamily(objectGraph, data, "mac");
        const isMacApp = dataHasDeviceFamily(objectGraph, data, "mac");
        if (isMacOnlyApp || (objectGraph.client.isMac && isMacApp)) {
            platform = "Mac";
        }
        else {
            platform = "iOS";
        }
        // Add product info
        if (serverData.isDefinedNonNull(data) && mediaAttributes.attributeAsString(data, "url")) {
            artwork = content.iconFromData(objectGraph, data, {
                useCase: 1 /* content.ArtworkUseCase.LockupIconSmall */,
            }, clientIdentifierOverride);
            notesMetadata = notesMetadataFromProductData(objectGraph, data);
        }
        const productMetadata = new models.ShareSheetProductMetadata(adamId, storeFrontIdentifier, title, platform, artwork, screenshots, videos, isMessagesOnlyApp, subtitle, genreName, messagesAppIcon, notesMetadata);
        return new models.ShareSheetData(productMetadata, url, shortUrl);
    });
}
export function shareProductActionFromData(objectGraph, data, metricsPageInformation, metricsLocationTracker, clientIdentifierOverride) {
    return validation.context(`shareActionFromData: ${data.type}`, () => {
        var _a;
        const id = data.id;
        switch (objectGraph.client.deviceType) {
            case "mac": {
                const shareSheetData = shareSheetDataForProductFromProductData(objectGraph, data);
                // Share action
                if (shareSheetData) {
                    const shareAction = new models.ShareSheetAction(shareSheetData, []);
                    metricsHelpersClicks.addClickEventToAction(objectGraph, shareAction, {
                        targetType: "button",
                        id: id,
                        actionType: "share",
                        pageInformation: metricsPageInformation,
                        locationTracker: metricsLocationTracker,
                    });
                    return shareAction;
                }
                break;
            }
            case "phone":
            case "pad":
            case "vision": {
                const shareSheetData = shareSheetDataForProductFromProductData(objectGraph, data, clientIdentifierOverride);
                const shareSheetActivities = [];
                // Copy link action
                if (((_a = shareSheetData === null || shareSheetData === void 0 ? void 0 : shareSheetData.url) === null || _a === void 0 ? void 0 : _a.length) > 0) {
                    const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareSheetData.url);
                    if (serverData.isDefinedNonNull) {
                        shareSheetActivities.push(copyLinkActivity);
                    }
                }
                // Gift action
                const giftAdamId = adamIdForShareSheetGiftActivityFromProductData(objectGraph, data);
                if (giftAdamId) {
                    const giftAction = new models.FlowAction("finance");
                    giftAction.presentationContext = "presentModal";
                    giftAction.title = objectGraph.loc.string("SHARE_GIFT_APP");
                    giftAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://app.gift");
                    giftAction.pageUrl = `gift/${giftAdamId}`;
                    metricsHelpersClicks.addClickEventToAction(objectGraph, giftAction, {
                        targetType: "button",
                        id: id,
                        actionType: "gift",
                        actionContext: "shareSheet",
                        pageInformation: metricsPageInformation,
                        locationTracker: metricsLocationTracker,
                    });
                    const giftActionActivity = new models.ShareSheetActivity("com.apple.AppStore.giftActivity", giftAction);
                    shareSheetActivities.push(giftActionActivity);
                }
                if (shareSheetData) {
                    // Share action
                    const shareSheetStyle = "expanded";
                    const shareAction = new models.ShareSheetAction(shareSheetData, shareSheetActivities, shareSheetStyle);
                    shareAction.title = objectGraph.loc.string("SHARE_APP");
                    shareAction.artwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://square.and.arrow.up");
                    metricsHelpersClicks.addClickEventToAction(objectGraph, shareAction, {
                        targetType: "button",
                        id: id,
                        actionType: "share",
                        actionContext: "shareSheet",
                        pageInformation: metricsPageInformation,
                        locationTracker: metricsLocationTracker,
                    });
                    return shareAction;
                }
                else if (shareSheetActivities.length > 0) {
                    // Map ActionActivity[] to Action[] as we're not dealing with a share sheet
                    const sheetActions = shareSheetActivities.map((activity) => activity.action);
                    // Create action sheet instead of share sheet
                    const sheetAction = new models.SheetAction(sheetActions);
                    sheetAction.isCancelable = true;
                    sheetAction.isCustom = true;
                    metricsHelpersClicks.addClickEventToAction(objectGraph, sheetAction, {
                        targetType: "button",
                        id: id,
                        actionType: "actionSheet",
                        pageInformation: metricsPageInformation,
                        locationTracker: metricsLocationTracker,
                    });
                    return sheetAction;
                }
                break;
            }
            default: {
                // These device types do not support sharing, so we don't create any share actions.
                break;
            }
        }
        return null;
    });
}
// region Generic Pages
export function shareSheetDataForGenericPage(objectGraph, text, url, subtitle, shortUrl, artwork) {
    return validation.context("shareSheetDataForGenericPage", () => {
        if (serverData.isNullOrEmpty(url)) {
            return null;
        }
        const metadata = new models.ShareSheetGenericMetadata(text, subtitle, artwork !== null && artwork !== void 0 ? artwork : undefined);
        return new models.ShareSheetData(metadata, url, shortUrl);
    });
}
export function shareSheetActivitiesForGenericPage(objectGraph, shareUrl) {
    const shareSheetActivities = [];
    if ((shareUrl === null || shareUrl === void 0 ? void 0 : shareUrl.length) > 0) {
        const copyLinkActivity = copyLinkShareSheetActivityForURL(objectGraph, shareUrl);
        if (serverData.isDefinedNonNull) {
            shareSheetActivities.push(copyLinkActivity);
        }
    }
    return shareSheetActivities;
}
// endregion
//# sourceMappingURL=sharing.js.map