"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const subscription_properties_1 = require("./subscription-properties");
const errors_1 = require("../errors");
const segment_properties_1 = require("../segment-properties");
const subscriptionStatusConfig = [
    { status: 'SUBSCRIBED', matchingStatuses: ['true', 'subscribed'] },
    { status: 'UNSUBSCRIBED', matchingStatuses: ['false', 'unsubscribed'] },
    { status: 'DID_NOT_SUBSCRIBE', matchingStatuses: ['did-not-subscribe', 'did_not_subscribe'] }
];
const supportedChannels = [
    {
        field: 'email',
        externalId: 'email',
        subscriptionFields: ['email_subscription_status'],
        channels: ['EMAIL'],
        groups: true
    },
    {
        field: 'phone',
        externalId: 'phone',
        subscriptionFields: ['sms_subscription_status', 'whatsapp_subscription_status'],
        channels: ['SMS', 'WHATSAPP'],
        groups: false
    },
    {
        field: 'android_push_token',
        externalId: 'android.push_token',
        subscriptionFields: ['android_push_subscription_status'],
        channels: ['ANDROID_PUSH'],
        groups: false
    },
    {
        field: 'ios_push_token',
        externalId: 'ios.push_token',
        subscriptionFields: ['ios_push_subscription_status'],
        channels: ['IOS_PUSH'],
        groups: false
    }
];
const INVALID_SUBSCRIPTION_STATUS = 'INVALID';
const getStatus = (subscriptionStatus) => {
    const tempSubscriptionStatus = subscriptionStatus?.trim().toLowerCase();
    if (!tempSubscriptionStatus) {
        return undefined;
    }
    const status = subscriptionStatusConfig.find(({ matchingStatuses }) => matchingStatuses.indexOf(tempSubscriptionStatus) > -1);
    if (status) {
        return status.status;
    }
    return INVALID_SUBSCRIPTION_STATUS;
};
const enrichExternalIds = (payload, externalIds) => {
    for (const channel of supportedChannels) {
        const field = payload[channel.field];
        if (field != undefined) {
            externalIds.push({
                id: field,
                type: channel.externalId,
                collection: 'users',
                encoding: 'none'
            });
        }
    }
    return externalIds;
};
const enrichMessagingSubscriptions = (payload, messagingSubscriptions) => {
    for (const channel of supportedChannels) {
        const field = payload[channel.field];
        for (const [index, subscriptionField] of channel.subscriptionFields.entries()) {
            const subscriptionValue = payload[subscriptionField];
            const subscription = formatToMessagingSubscription(field, channel.channels[index], subscriptionValue);
            if (subscription && channel.groups) {
                if (payload.subscription_groups &&
                    typeof payload.subscription_groups === 'object' &&
                    Object.keys(payload.subscription_groups).length > 0) {
                    const formattedGroups = Object.entries(payload.subscription_groups)
                        .filter(([name, status]) => name !== undefined && status !== undefined)
                        .map(([name, status]) => ({
                        name: String(name),
                        status: getStatus(String(status))
                    }));
                    subscription.groups = formattedGroups;
                }
            }
            if (subscription)
                messagingSubscriptions.push(subscription);
        }
    }
    return messagingSubscriptions;
};
const validateSubscriptions = (payload, statsClient, tags) => {
    if (!(payload.email || payload.phone || payload.android_push_token || payload.ios_push_token)) {
        tags?.push(`type:missing_external_ids`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingExternalIdsError;
    }
    if (!(payload.email_subscription_status ||
        payload.whatsapp_subscription_status ||
        payload.sms_subscription_status ||
        payload.android_push_subscription_status ||
        payload.ios_push_subscription_status)) {
        tags?.push(`type:missing_subscription_status`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingSubscriptionStatusesError;
    }
    if (!payload.email && payload.email_subscription_status) {
        tags?.push(`type:missing_email_but_subscription_exists`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingEmailIfEmailSubscriptionIsPresentError;
    }
    if (payload.subscription_groups &&
        !payload.email_subscription_status &&
        Object.keys(payload.subscription_groups).length > 0) {
        tags?.push(`type:missing_email_but_subscription_groups_exists`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingEmailSubscriptionIfSubscriptionGroupsIsPresentError;
    }
    if (!payload.phone && (payload.sms_subscription_status || payload.whatsapp_subscription_status)) {
        tags?.push(`type:missing_phone_but_subscription_exists`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingPhoneIfSmsOrWhatsappSubscriptionIsPresentError;
    }
    if (!payload.android_push_token && payload.android_push_subscription_status) {
        tags?.push(`type:missing_android_push_but_subscription_exists`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingAndroidPushTokenIfAndroidPushSubscriptionIsPresentError;
    }
    if (!payload.ios_push_token && payload.ios_push_subscription_status) {
        tags?.push(`type:missing_ios_push_but_subscription_exists`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.MissingIosPushTokenIfIosPushSubscriptionIsPresentError;
    }
    if (payload.email_subscription_status &&
        getStatus(payload.email_subscription_status) == INVALID_SUBSCRIPTION_STATUS &&
        payload.sms_subscription_status &&
        getStatus(payload.sms_subscription_status) == INVALID_SUBSCRIPTION_STATUS &&
        payload.whatsapp_subscription_status &&
        getStatus(payload.whatsapp_subscription_status) == INVALID_SUBSCRIPTION_STATUS &&
        payload.ios_push_subscription_status &&
        getStatus(payload.ios_push_subscription_status) == INVALID_SUBSCRIPTION_STATUS &&
        payload.android_push_subscription_status &&
        getStatus(payload.android_push_subscription_status) == INVALID_SUBSCRIPTION_STATUS) {
        tags?.push(`type:invalid_subscription_value`);
        statsClient?.incr('validation_error', 1, tags);
        throw errors_1.InvalidSubscriptionStatusError;
    }
};
const formatToMessagingSubscription = (key, type, status) => {
    const tempStatus = getStatus(status);
    if (tempStatus) {
        return {
            key,
            type,
            status: tempStatus
        };
    }
    return undefined;
};
const action = {
    title: 'Send Subscriptions',
    description: 'Send an identify call to Segment’s tracking API. This is used to get user channel subscription data into Engage.',
    defaultSubscription: 'type = "identify"',
    fields: {
        engage_space: subscription_properties_1.engage_space,
        user_id: subscription_properties_1.user_id,
        anonymous_id: subscription_properties_1.anonymous_id,
        email: subscription_properties_1.email,
        email_subscription_status: subscription_properties_1.email_subscription_status,
        subscription_groups: subscription_properties_1.subscription_groups,
        phone: subscription_properties_1.phone,
        sms_subscription_status: subscription_properties_1.sms_subscription_status,
        whatsapp_subscription_status: subscription_properties_1.whatsapp_subscription_status,
        android_push_token: subscription_properties_1.android_push_token,
        android_push_subscription_status: subscription_properties_1.android_push_subscription_status,
        ios_push_token: subscription_properties_1.ios_push_token,
        ios_push_subscription_status: subscription_properties_1.ios_push_subscription_status,
        traits: subscription_properties_1.traits,
        timestamp: segment_properties_1.timestamp,
        message_id: subscription_properties_1.message_id,
        consent: subscription_properties_1.consent
    },
    perform: (_request, { payload, statsContext }) => {
        const statsClient = statsContext?.statsClient;
        const tags = statsContext?.tags;
        tags?.push(`action:sendSubscription`);
        validateSubscriptions(payload, statsClient, tags);
        const isValidConsentObject = (0, segment_properties_1.validateConsentObject)(payload?.consent);
        const externalIds = enrichExternalIds(payload, []);
        const messagingSubscriptions = enrichMessagingSubscriptions(payload, []);
        const subscriptionPayload = {
            userId: payload?.user_id,
            anonymousId: payload?.anonymous_id,
            traits: {
                ...payload?.traits
            },
            context: {
                messaging_subscriptions: messagingSubscriptions,
                externalIds,
                messaging_subscriptions_retl: true,
                consent: isValidConsentObject ? { ...payload?.consent } : {}
            },
            timestamp: payload?.timestamp,
            integrations: {
                All: false
            },
            messageId: payload?.message_id,
            type: 'identify'
        };
        statsClient?.incr('success', 1, tags);
        statsClient?.incr('tapi_internal', 1, tags);
        return { batch: [subscriptionPayload] };
    }
};
exports.default = action;
//# sourceMappingURL=index.js.map