import * as models from "../../api/models";
import * as serverData from "../../foundation/json-parsing/server-data";
import * as mediaAttributes from "../../foundation/media/attributes";
import * as mediaRelationship from "../../foundation/media/relationships";
import * as appPromotionCommon from "./app-promotions-common";
import * as offerFormatting from "../offers/offer-formatting";
import * as offers from "../offers/offers";
import * as color from "../../foundation/util/color-util";
import { isNothing, isSome } from "@jet/environment/types/optional";
import { contentAttributeAsDictionary } from "../content/attributes";
import * as content from "../content/content";
/**
 * Creates a contingent offer object.
 * @param data The data blob
 * @param parentAppData The related parent app of this app event. If not provided will be derived from `data`.
 * @param offerEnvironment The preferred environment for the offer
 * @param offerStyle The preferred style of the offer
 * @param baseMetricsOptions The base metrics options
 * @param allowEndedEvents Whether events in the past are allowed
 * @param includeLockupClickAction Whether to include the click action for the lockup
 * @param isArcadePage Whether or not this is presented on the Arcade page
 * @returns an ContingentOffer or null
 */
export function contingentOfferFromData(objectGraph, data, parentAppData, offerEnvironment, offerStyle, baseMetricsOptions, includeLockupClickAction, isArcadePage) {
    var _a, _b, _c;
    if (data.type !== "contingent-items") {
        return null;
    }
    // Artwork
    const moduleArtwork = appPromotionCommon.artworkFromPlatformData(objectGraph, data, "lockupArtwork");
    if (serverData.isNull(moduleArtwork)) {
        return null;
    }
    const isArtworkDark = color.isDarkColor(moduleArtwork.backgroundColor);
    const mediaOverlayStyle = isArtworkDark ? "dark" : "light";
    // Labels
    const badge = mediaAttributes.attributeAsString(data, "badge");
    const subtitle = mediaAttributes.attributeAsString(data, "subtitle");
    const label = mediaAttributes.attributeAsString(data, "label");
    const additionalInfoLabel = objectGraph.loc.string("ContingentOffer.AdditionalInfoButton.Title");
    if (isNothing(badge) || isNothing(label)) {
        return null;
    }
    // The discounted offer
    const branch = mediaRelationship.relationshipData(objectGraph, data, "branch");
    if (isNothing(branch) || serverData.isNullOrEmpty(serverData.asDictionary(branch, "meta.contingentItemOffer"))) {
        return null;
    }
    const formattedText = formattedTextFromData(objectGraph, data);
    if (isNothing(formattedText) || isNothing(formattedText === null || formattedText === void 0 ? void 0 : formattedText.title)) {
        return null;
    }
    // The Apps
    const resolvedBranchAppData = mediaRelationship.relationshipData(objectGraph, data, "branch-app");
    const supportsStreamlinedBuy = mediaAttributes.attributeAsBooleanOrFalse(resolvedBranchAppData, "supportsStreamlinedBuy");
    const offerLockup = appPromotionCommon.lockupFromData(objectGraph, data, resolvedBranchAppData, "", offerEnvironment, offerStyle, false, baseMetricsOptions, includeLockupClickAction, null, isArcadePage, true);
    if (isNothing(offerLockup)) {
        return null;
    }
    // Trunk Lockup. The app you need to be subscribed to in order to get the discounted offer
    const resolvedTrunkAppData = mediaRelationship.relationshipData(objectGraph, data, "trunk-app");
    let trunkAppIcon;
    if (isSome(resolvedTrunkAppData) && isSome(subtitle) && (subtitle === null || subtitle === void 0 ? void 0 : subtitle.length) > 0) {
        trunkAppIcon =
            (_a = appPromotionCommon.artworkFromPlatformData(objectGraph, resolvedTrunkAppData, "artwork")) !== null && _a !== void 0 ? _a : appPromotionCommon.artworkFromData(objectGraph, resolvedTrunkAppData, "artwork");
    }
    // When displaying a first party offer the trunk artwork is in a different location
    if (isSome(subtitle) && (subtitle === null || subtitle === void 0 ? void 0 : subtitle.length) > 0) {
        trunkAppIcon = (_b = firstPartyTrunkLockupFromData(objectGraph, data)) !== null && _b !== void 0 ? _b : trunkAppIcon;
    }
    // Offer Strings
    const additionalInfo = formattedAdditionalInfoFromData(objectGraph, data, branch);
    const contingentOffer = new models.ContingentOffer(moduleArtwork, mediaOverlayStyle, supportsStreamlinedBuy, additionalInfoLabel, formattedText.title, subtitle !== null && subtitle !== void 0 ? subtitle : undefined, (_c = formattedText.description) !== null && _c !== void 0 ? _c : undefined, label, badge, additionalInfo, trunkAppIcon !== null && trunkAppIcon !== void 0 ? trunkAppIcon : undefined, offerLockup);
    /// The raw title is used for metrics purposes
    contingentOffer.title = formattedText.rawTitle;
    // Detail page click action
    if (serverData.isDefinedNonNull(resolvedBranchAppData)) {
        contingentOffer.clickAction = appPromotionCommon.detailPageClickActionFromData(objectGraph, data, resolvedBranchAppData, contingentOffer, baseMetricsOptions, includeLockupClickAction);
    }
    return contingentOffer;
}
/**
 * Creates the Title and description of the contingent offer out of a templated string
 * @param data A data blob for the contingent-item
 * @returns Creates a formatted string of the tile including the subscription price and period
 */
export function formattedTextFromData(objectGraph, data) {
    var _a, _b, _c;
    const branch = mediaRelationship.relationshipData(objectGraph, data, "branch");
    if (isNothing(branch)) {
        return undefined;
    }
    const regularOffer = offers.offerDataFromData(objectGraph, branch);
    const discountedOffer = serverData.asDictionary(branch, "meta.contingentItemOffer");
    if (serverData.isNullOrEmpty(regularOffer) || serverData.isNullOrEmpty(discountedOffer)) {
        return undefined;
    }
    // Price Strings
    // Adding \u{2060} (Word Joiner) prevents the string from breaking on the slash character
    const regularPrice = (_a = formattedPrice(objectGraph, serverData.asString(regularOffer, "recurringSubscriptionPeriod"), serverData.asNumber(regularOffer, "numOfPeriods"), serverData.asString(regularOffer, "priceFormatted"))) === null || _a === void 0 ? void 0 : _a.replace("/", "/\u{2060}");
    const discountedPrice = (_b = formattedPrice(objectGraph, serverData.asString(discountedOffer, "recurringSubscriptionPeriod"), serverData.asNumber(discountedOffer, "numOfPeriods"), serverData.asString(discountedOffer, "priceFormatted"))) === null || _b === void 0 ? void 0 : _b.replace("/", "/\u{2060}");
    if (serverData.isNullOrEmpty(regularPrice) || serverData.isNullOrEmpty(discountedPrice)) {
        return null;
    }
    const title = mediaAttributes.attributeAsString(data, "name");
    const titleKeys = {
        "@@discountedPrice@@/@@recurringSubscriptionPeriod@@": discountedPrice,
        "@@regularPrice@@/@@recurringSubscriptionPeriod@@": regularPrice,
        "@@discountedPricePerRecurringSubscriptionPeriod@@": discountedPrice,
        "@@regularPricePerRecurringSubscriptionPeriod@@": regularPrice,
    };
    let titleTemplate = title !== null && title !== void 0 ? title : "";
    Object.keys(titleKeys).forEach((element) => {
        titleTemplate = titleTemplate.replace(element, titleKeys[element]);
    });
    const htmlRegex = /<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+>/g;
    const rawTitle = titleTemplate.replace(htmlRegex, "");
    const formattedTitle = new models.Paragraph(titleTemplate, "text/x-apple-as3-nqml", "appPromotionTitle");
    const developerDetailText = (_c = mediaAttributes.attributeAsString(data, "description.standard")) !== null && _c !== void 0 ? _c : "";
    const detailTemplate = objectGraph.loc.string("ContingentOffer.Description.Format");
    const descriptionKeys = {
        "@@BranchName@@": mediaAttributes.attributeAsString(branch, "name"),
        "@@RegularPrice@@": regularPrice,
        "@@DiscountedPrice@@": discountedPrice,
    };
    let description = detailTemplate;
    Object.keys(descriptionKeys).forEach((element) => {
        description = description.replace(element, descriptionKeys[element]);
    });
    const formattedDescription = [description, developerDetailText].join(" ");
    return {
        title: formattedTitle,
        rawTitle,
        description: formattedDescription,
    };
}
/**
 * Creates a readable subscription price
 * @param recurringSubscriptionPeriod The subscription recurrence in the server format. (eg P1M)
 * @param price A price string in a readable format like $3.99.
 * @returns A formatted string eg $3.99/month
 */
function formattedPrice(objectGraph, recurringSubscriptionPeriod, numberOfPeriods, price) {
    const subscriptionRecurrence = offerFormatting.subscriptionRecurrenceForServerRecurrence(objectGraph, recurringSubscriptionPeriod, numberOfPeriods);
    if (isNothing(subscriptionRecurrence) || isNothing(price)) {
        return undefined;
    }
    return offerFormatting.priceDurationString(objectGraph, subscriptionRecurrence.type, subscriptionRecurrence.periodDuration, price);
}
/**
 * Creates the additional info text of the contingent offer out of a templated string
 * @param data A data blob
 * @param branch A data blob containing the offer also known as the branch
 * @param trunk A data blob containing the required subscription app also known as the trunk
 * @returns Creates a formatted paragraph containing the contents of the additional info page.
 */
function formattedAdditionalInfoFromData(objectGraph, data, branch) {
    const skuNameTitle = "<b>" + mediaAttributes.attributeAsString(branch, "name") + "</b>";
    const skuDescription = mediaAttributes.attributeAsString(branch, "description.standard") + "<br>";
    const termsTitle = "<b>" + objectGraph.loc.string("ContingentOffer.Terms.Title") + "</b>";
    const terms = mediaAttributes.attributeAsString(data, "additionalTerms");
    return new models.Paragraph([skuNameTitle, skuDescription, termsTitle, terms].join("<br>"), "text/x-apple-as3-nqml");
}
/**
 * If the contingent offer has a an associated trunk use that instead of the trunk-app
 * @param data The data blob
 * @returns Creates a lockup to use as the TrunkLockup
 */
function firstPartyTrunkLockupFromData(objectGraph, data) {
    var _a, _b;
    const firstPartyTrunkData = serverData.asInterface(data, "meta.associations.trunks");
    if (isNothing(firstPartyTrunkData)) {
        return null;
    }
    const firstPartyApp = firstPartyTrunkData.data[0];
    const shouldUseTrunkArtwork = (_b = (_a = firstPartyApp === null || firstPartyApp === void 0 ? void 0 : firstPartyApp.meta) === null || _a === void 0 ? void 0 : _a["useTrunkArtwork"]) !== null && _b !== void 0 ? _b : false;
    if (shouldUseTrunkArtwork) {
        const editorialArtwork = contentAttributeAsDictionary(objectGraph, firstPartyApp, "editorialArtwork.brandLogo");
        if (isNothing(editorialArtwork)) {
            return null;
        }
        return content.artworkFromApiArtwork(objectGraph, editorialArtwork, {
            useCase: 1 /* content.ArtworkUseCase.LockupIconSmall */,
            style: "roundedRect",
        });
    }
    return null;
}
//# sourceMappingURL=contingent-offer.js.map