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 dateUtil from "../../foundation/util/date-util";
import { isNothing, isSome } from "@jet/environment/types/optional";
import * as offerFormatting from "../offers/offer-formatting";
import * as offers from "../offers/offers";
import * as content from "../content/content";
import * as contentArtwork from "../content/artwork/artwork";
/**
 * Creates an offer item object.
 * @param offerItemData 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 Offer Item or null
 */
export function offerItemFromData(objectGraph, offerItemData, parentAppData, offerEnvironment, offerStyle, baseMetricsOptions, includeLockupClickAction, isArcadePage) {
    var _a, _b, _c, _d, _e, _f;
    if (offerItemData.type !== "offer-items") {
        return null;
    }
    const kind = mediaAttributes.attributeAsString(offerItemData, "kind");
    if (kind !== "resubscription" && kind !== "winback") {
        // Only resubscriptions are supported
        return null;
    }
    const isArtworkDark = false;
    const mediaOverlayStyle = isArtworkDark ? "dark" : "light";
    // The Offers
    const discountedIAP = mediaRelationship.relationshipData(objectGraph, offerItemData, "salables");
    if (isNothing(discountedIAP)) {
        return null;
    }
    const discountedOffer = serverData.asDictionary(discountedIAP, "meta.discountOffer");
    const regularOffer = offers.offerDataFromData(objectGraph, discountedIAP);
    if (isNothing(discountedOffer)) {
        return null;
    }
    const resolvedParentApp = (_a = parentAppData !== null && parentAppData !== void 0 ? parentAppData : mediaRelationship.relationshipData(objectGraph, offerItemData, "app")) !== null && _a !== void 0 ? _a : mediaRelationship.relationshipData(objectGraph, discountedIAP, "app");
    const supportsStreamlinedBuy = mediaAttributes.attributeAsBooleanOrFalse(resolvedParentApp, "supportsStreamlinedBuy");
    // Offer Validity
    const endDateString = mediaAttributes.attributeAsString(offerItemData, "redemptionExpirationDate");
    if (isNothing(endDateString) || !isOfferValid(endDateString)) {
        return null;
    }
    const endDate = new Date(endDateString);
    let formattedExpiryDateShortString = formattedExpiryDate(objectGraph, endDate);
    if (isNothing(formattedExpiryDateShortString)) {
        formattedExpiryDateShortString = objectGraph.loc.string("OfferItems.Available.Now");
    }
    // IAP Artwork
    let iapArtwork = content.iconFromData(objectGraph, discountedIAP, {
        useCase: 3 /* content.ArtworkUseCase.LockupIconLarge */,
        withJoeColorPlaceholder: true,
        overrideTextColorKey: "textColor4",
    });
    /// A fallback artwork for rare cases where no artwork is found.
    /// This should not happen in production
    if (serverData.isNullOrEmpty(iapArtwork)) {
        const blackColor = {
            type: "rgb",
            red: 0.0 / 255,
            green: 0.0 / 255,
            blue: 0.0 / 255,
            alpha: 1,
        };
        iapArtwork = contentArtwork.createArtworkForResource(objectGraph, "systemimage://questionmark.circle", 200, 200, blackColor);
        iapArtwork.style = "iap";
    }
    const subscriptionRecurrence = offerFormatting.subscriptionRecurrenceForServerRecurrence(objectGraph, serverData.asString(discountedOffer, "recurringSubscriptionPeriod"), serverData.asNumber(discountedOffer, "numOfPeriods"));
    const discountDuration = isSome(subscriptionRecurrence)
        ? offerFormatting.durationCountString(objectGraph, subscriptionRecurrence.type, subscriptionRecurrence.periodDuration * subscriptionRecurrence.periodCount)
        : undefined;
    // Price Strings
    // Adding \u{2060} (Word Joiner) prevents the string from breaking on the slash character
    const regularPrice = (_b = formattedPrice(objectGraph, serverData.asString(regularOffer, "recurringSubscriptionPeriod"), serverData.asNumber(regularOffer, "numOfPeriods"), serverData.asString(regularOffer, "priceFormatted"))) === null || _b === void 0 ? void 0 : _b.replace("/", "/\u{2060}");
    const discountedPrice = (_c = formattedPrice(objectGraph, serverData.asString(discountedOffer, "recurringSubscriptionPeriod"), serverData.asNumber(discountedOffer, "numOfPeriods"), serverData.asString(discountedOffer, "priceFormatted"))) === null || _c === void 0 ? void 0 : _c.replace("/", "/\u{2060}");
    /// A string map of the templated string in an offer
    /// Fallback to the templated string if the string does not exist
    const redemptionDateFormat = objectGraph.loc.string("OfferItems.FormattedDate.RedemptionDate.DateFormat");
    const templateKeyMap = {
        "@@redemptionDate@@": objectGraph.loc.formatDate(redemptionDateFormat, endDate),
        "@@skuName@@": (_d = mediaAttributes.attributeAsString(discountedIAP, "name")) !== null && _d !== void 0 ? _d : "@@skuName@@",
        "@@discountedPrice@@": discountedPrice !== null && discountedPrice !== void 0 ? discountedPrice : "@@discountedPrice@@",
        "@@regularPricePerDuration@@": regularPrice !== null && regularPrice !== void 0 ? regularPrice : "@@regularPricePerDuration@@",
        "@@discountDuration@@": discountDuration !== null && discountDuration !== void 0 ? discountDuration : "@@discountDuration@@",
        "@@payUpfrontPrice@@": (_e = serverData.asString(discountedOffer, "priceFormatted")) !== null && _e !== void 0 ? _e : "@@payUpfrontPrice@@",
    };
    // Labels
    const badge = mediaAttributes.attributeAsString(offerItemData, "badge");
    if (isNothing(badge)) {
        return null;
    }
    const title = appPromotionCommon.replacingTemplatedKeys(mediaAttributes.attributeAsString(offerItemData, "title"), templateKeyMap);
    const formattedTitle = new models.Paragraph(title, "text/x-apple-as3-nqml", "appPromotionTitle");
    const subtitle = appPromotionCommon.replacingTemplatedKeys(mediaAttributes.attributeAsString(offerItemData, "subtitle"), templateKeyMap);
    const description = appPromotionCommon.replacingTemplatedKeys((_f = mediaAttributes.attributeAsString(offerItemData, "details")) !== null && _f !== void 0 ? _f : "", templateKeyMap);
    // Offer Lockup
    let offerLockup;
    if (serverData.isDefinedNonNull(resolvedParentApp)) {
        offerLockup = appPromotionCommon.lockupFromData(objectGraph, offerItemData, resolvedParentApp, "", offerEnvironment, offerStyle, false, baseMetricsOptions, includeLockupClickAction, null, isArcadePage, true);
    }
    if (isNothing(offerLockup)) {
        return null;
    }
    const offerItem = new models.OfferItem(null, null, mediaOverlayStyle, supportsStreamlinedBuy, formattedTitle, formattedExpiryDateShortString, subtitle, description, badge, endDate, iapArtwork, offerLockup);
    offerItem.title = title;
    // Detail page click action
    if (serverData.isDefinedNonNull(resolvedParentApp)) {
        offerItem.clickAction = appPromotionCommon.detailPageClickActionFromData(objectGraph, offerItemData, resolvedParentApp, offerItem, baseMetricsOptions, includeLockupClickAction);
    }
    return offerItem;
}
/**
 * Creates a readable subscription price
 * @param recurringSubscriptionPeriod The subscription recurrence in the server format. (eg P1M)
 * @param numberOfPeriods The number of periods the subscription recurs for.
 * @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 null;
    }
    return offerFormatting.priceDurationString(objectGraph, subscriptionRecurrence === null || subscriptionRecurrence === void 0 ? void 0 : subscriptionRecurrence.type, subscriptionRecurrence === null || subscriptionRecurrence === void 0 ? void 0 : subscriptionRecurrence.periodDuration, price);
}
/**
 * Checks the validity of a app promotion based on end date
 * @param endDateString A string representation of the end date
 * @returns bool of if the offer is valid or not
 */
function isOfferValid(endDateString) {
    if (isNothing(endDateString) || serverData.isNullOrEmpty(endDateString)) {
        return false;
    }
    const endDate = new Date(endDateString);
    if (serverData.isNull(endDate)) {
        return false;
    }
    const todayDate = new Date();
    const hasEventEnded = endDate.getTime() <= todayDate.getTime();
    if (hasEventEnded) {
        return false;
    }
    return true;
}
/**
 * Creates the availability label for a app promotion
 * @param startDate The start date
 * @param endDate The end date
 * @returns string of the format the date should be shown
 */
function formattedExpiryDate(objectGraph, endDate) {
    if (isNothing(endDate)) {
        return null;
    }
    const endMidnight = dateUtil.convertLocalDateToLocalMidnight(endDate);
    const currentDate = new Date();
    const daysLeft = dateUtil.numberOfDaysBetween(currentDate, endMidnight);
    if (isNothing(daysLeft)) {
        return null;
    }
    const isSameDate = dateUtil.areLocalDatesSameDay(currentDate, endDate);
    if (daysLeft > 90) {
        return objectGraph.loc.string("OfferItems.Available.Now");
    }
    // Event ends 5+ days from now
    // Example: EXPIRES DEC 31
    if (daysLeft > 5) {
        const expiryDateFormat = currentDate.getFullYear() !== endDate.getFullYear()
            ? objectGraph.loc.string("OfferItems.FormattedDate.NextYear.DateFormat")
            : objectGraph.loc.string("OfferItems.FormattedDate.FiveDaysOrMore.DateFormat");
        const expiryDateString = objectGraph.loc.uppercased(objectGraph.loc.formatDate(expiryDateFormat, endDate));
        if (isNothing(expiryDateString)) {
            return null;
        }
        return objectGraph.loc
            .string("OfferItems.FormattedDate.FiveDaysOrMore.Title")
            .replace("@@date@@", expiryDateString);
    }
    // Event ends 2-5 days from now
    // Example: EXPIRES IN 3 Days
    if (daysLeft > 1) {
        const fiveDaysPriorDateFormat = objectGraph.loc
            .string("OfferItems.FormattedDate.FiveDaysOrLess.Title")
            .replace("@@count@@", objectGraph.loc.formattedCount(daysLeft));
        return fiveDaysPriorDateFormat;
    }
    // Event ends 1 day from now
    // Example: EXPIRES TOMORROW
    if (daysLeft === 1 && !isSameDate) {
        return objectGraph.loc.string("OfferItems.FormattedDate.Tomorrow.Title");
    }
    // Event ends 1 day from now
    // Example: EXPIRES TONIGHT
    return objectGraph.loc.string("OfferItems.FormattedDate.Today.Title");
}
//# sourceMappingURL=offer-item.js.map