"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PushSender = exports.MobilePushExtIdTypes = void 0;
const utils_1 = require("../utils");
const actions_shared_1 = require("@segment/actions-shared");
const actions_core_1 = require("@segment/actions-core");
var MobilePushExtIdTypes;
(function (MobilePushExtIdTypes) {
    MobilePushExtIdTypes["IOS"] = "ios.push_token";
    MobilePushExtIdTypes["ANDROID"] = "android.push_token";
})(MobilePushExtIdTypes || (exports.MobilePushExtIdTypes = MobilePushExtIdTypes = {}));
class PushSender extends utils_1.TwilioMessageSender {
    constructor() {
        super(...arguments);
        this.supportedTemplateTypes = ['twilio/text', 'twilio/media'];
        this.DEFAULT_HOSTNAME = 'push.ashburn.us1.twilio.com';
    }
    getChannelType() {
        return 'mobilepush';
    }
    isSupportedExternalId(externalId) {
        return PushSender.externalIdTypes.includes(externalId.type);
    }
    get twilioHostname() {
        return this.settings.twilioHostname?.length ? this.settings.twilioHostname : this.DEFAULT_HOSTNAME;
    }
    get twilioToken() {
        return Buffer.from(`${this.settings.twilioApiKeySID}:${this.settings.twilioApiKeySecret}`).toString('base64');
    }
    async beforeSend(recepients) {
        if (this.payload.send && recepients.length > 0) {
            this.bodyCustomDataBundle = await this.getBody();
        }
    }
    async sendToRecepient(recipientDevice) {
        const { requestBody, customData } = this.bodyCustomDataBundle;
        const webhookUrl = this.getWebhookUrlWithParams(recipientDevice.type, recipientDevice.id);
        const body = new URLSearchParams(requestBody);
        if (recipientDevice?.type?.toLowerCase() === MobilePushExtIdTypes.IOS) {
            body.append('Recipients', JSON.stringify({
                apn: [{ addr: recipientDevice.id }]
            }));
        }
        else {
            body.append('Recipients', JSON.stringify({
                fcm: [{ addr: recipientDevice.id }]
            }));
        }
        body.append('CustomData', JSON.stringify({
            ...customData,
            __segment_internal_external_id_key__: recipientDevice.type,
            __segment_internal_external_id_value__: recipientDevice.id
        }));
        if (webhookUrl) {
            body.append('DeliveryCallbackUrl', webhookUrl);
        }
        this.statsSet('message_body_size', body?.toString().length);
        body.sort();
        const res = await this.request(`https://${this.twilioHostname}/v1/Services/${this.payload.from}/Notifications`, {
            method: 'POST',
            headers: {
                authorization: `Basic ${this.twilioToken}`
            },
            body
        });
        return res;
    }
    async getBody() {
        let templateTypes;
        if (this.payload.contentSid) {
            templateTypes = await this.getContentTemplateTypes();
        }
        const profile = { traits: this.payload.traits };
        const parsedTemplateContent = await this.parseContent({
            title: this.payload.customizations?.title,
            body: this.payload.customizations?.body || templateTypes?.body,
            media: this.payload.customizations?.media || templateTypes?.media,
            link: this.payload.customizations?.link
        }, profile);
        const tapActionButtons = this.payload.customizations?.tapActionButtons ?? [];
        const parsedTapActionButtons = await Promise.all(tapActionButtons.map(async (button) => {
            return {
                ...button,
                onTap: this.getTapActionPreset(button.onTap, button.link),
                ...(await this.parseContent({ link: button.link, text: button.text }, profile))
            };
        }));
        const badgeAmount = this.payload.customizations?.badgeAmount ?? 1;
        const badgeStrategy = this.payload.customizations?.badgeStrategy ?? 'inc';
        try {
            const customData = this.removeEmpties({
                ...this.payload.customArgs,
                space_id: this.settings.spaceId,
                badgeAmount,
                badgeStrategy,
                media: parsedTemplateContent.media?.length ? parsedTemplateContent.media : undefined,
                link: parsedTemplateContent.link?.length ? parsedTemplateContent.link : undefined,
                tapActionButtons: parsedTapActionButtons
            });
            const body = this.removeEmpties({
                Body: parsedTemplateContent.body,
                Action: this.getTapActionPreset(this.payload.customizations?.tapAction, this.payload.customizations?.link),
                Title: parsedTemplateContent.title,
                Sound: this.payload.customizations?.sound,
                Priority: this.payload.customizations?.priority,
                TimeToLive: this.payload.customizations?.ttl,
                ApnPayload: {
                    aps: {
                        'mutable-content': 1,
                        badge: badgeAmount
                    }
                }
            });
            const requestBody = new URLSearchParams({
                ...body,
                FcmPayload: '{}',
                ApnPayload: JSON.stringify(body.ApnPayload)
            });
            return { requestBody, customData };
        }
        catch (error) {
            this.rethrowIntegrationError(error, () => new actions_core_1.PayloadValidationError('Unable to construct Push API request body'));
        }
    }
    getTapActionPreset(tapAction, link) {
        if (link?.length && tapAction === 'open_app') {
            return 'deep_link';
        }
        return tapAction;
    }
    removeEmpties(obj) {
        return JSON.parse(JSON.stringify(obj, (_, value) => {
            if (value == null || value?.length === 0 || (typeof value === 'object' && Object.keys(value).length === 0)) {
                return undefined;
            }
            return value;
        }));
    }
}
exports.PushSender = PushSender;
PushSender.externalIdTypes = Object.values(MobilePushExtIdTypes);
__decorate([
    (0, actions_shared_1.track)()
], PushSender.prototype, "getBody", null);
//# sourceMappingURL=PushSender.js.map