"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.send = send;
exports.currencies = currencies;
const actions_core_1 = require("@segment/actions-core");
const constants_1 = require("./constants");
const dayjs_1 = __importDefault(require("dayjs"));
async function send(request, payloads, settings, isBatch, syncMode) {
    const msResponse = new actions_core_1.MultiStatusResponse();
    if (!['update', 'add'].includes(syncMode ?? '')) {
        const message = `Invalid syncMode: ${syncMode}. Supported sync modes are 'add' and 'update'.`;
        if (isBatch) {
            payloads.forEach((payload, index) => {
                msResponse.setErrorResponseAtIndex(index, {
                    status: 400,
                    errormessage: message,
                    sent: payload
                });
            });
            return msResponse;
        }
        else {
            throw new actions_core_1.PayloadValidationError(message);
        }
    }
    const { endpoint } = settings;
    const { json, payloadsWithIndexes } = getJSON(payloads, settings, isBatch, syncMode, msResponse);
    const url = `${endpoint}/users/track`;
    const response = await request(url, {
        method: 'POST',
        ...(isBatch ? { headers: { 'X-Braze-Batch': 'true' } } : undefined),
        json
    });
    const errors = Array.isArray(response.data.errors) ? response.data.errors : [];
    payloadsWithIndexes.forEach((payload, index) => {
        const error = errors.find(e => e.index === index);
        if (error) {
            msResponse.setErrorResponseAtIndex(index, {
                status: 400,
                errortype: 'BAD_REQUEST',
                errormessage: error.type,
                sent: payload,
                body: JSON.stringify(json.events[index])
            });
        }
    });
    return isBatch ? msResponse : response;
}
function getJSON(payloads, settings, isBatch, syncMode, msResponse) {
    const payloadsWithIndexes = [...payloads];
    const events = [];
    payloadsWithIndexes.forEach((payload, index) => {
        const message = validate(payload, isBatch);
        if (message) {
            payload.index = undefined;
            msResponse.setErrorResponseAtIndex(index, {
                status: 400,
                errormessage: message,
                sent: payload
            });
        }
        else {
            const event = getJSONItem(payload, settings, syncMode);
            payload.index = events.length;
            events.push(event);
            msResponse.setSuccessResponseAtIndex(index, {
                status: 200,
                sent: payload,
                body: JSON.stringify(event)
            });
        }
    });
    return { json: { events }, payloadsWithIndexes };
}
function getJSONItem(payload, settings, syncMode) {
    const { app_id } = settings;
    const { external_id, braze_id, email, phone, user_alias, name, time: payloadTime, currency, source, metadata } = payload;
    const time = (0, dayjs_1.default)(payloadTime).toISOString();
    const updateExistingOnly = (() => {
        if (user_alias?.alias_label && user_alias?.alias_name) {
            return true;
        }
        if (syncMode === 'update') {
            return true;
        }
        return undefined;
    })();
    const baseEvent = {
        ...(external_id ? { external_id } : {}),
        ...(braze_id ? { braze_id } : {}),
        ...(email ? { email } : {}),
        ...(phone ? { phone } : {}),
        ...(user_alias ? { user_alias } : {}),
        ...(app_id ? { app_id } : {}),
        name: name,
        time,
        properties: {
            currency,
            source,
            ...(metadata ? { metadata } : {})
        },
        ...(typeof updateExistingOnly === 'boolean' ? { _update_existing_only: updateExistingOnly } : {})
    };
    switch (name) {
        case constants_1.EVENT_NAMES.PRODUCT_VIEWED: {
            const { product } = payload;
            const event = {
                ...baseEvent,
                name: constants_1.EVENT_NAMES.PRODUCT_VIEWED,
                properties: {
                    ...baseEvent.properties,
                    ...product
                }
            };
            return event;
        }
        case constants_1.EVENT_NAMES.CHECKOUT_STARTED:
        case constants_1.EVENT_NAMES.ORDER_PLACED:
        case constants_1.EVENT_NAMES.ORDER_CANCELLED:
        case constants_1.EVENT_NAMES.ORDER_REFUNDED: {
            const { total_value } = payload;
            const multiProductEvent = {
                ...baseEvent,
                name: name,
                properties: {
                    ...baseEvent.properties,
                    products: getProductAndMetadataJSON(payload),
                    total_value: total_value
                }
            };
            switch (name) {
                case constants_1.EVENT_NAMES.CHECKOUT_STARTED: {
                    const { checkout_id, cart_id } = payload;
                    const event = {
                        ...multiProductEvent,
                        name: constants_1.EVENT_NAMES.CHECKOUT_STARTED,
                        properties: {
                            ...multiProductEvent.properties,
                            checkout_id: checkout_id,
                            ...(cart_id ? { cart_id } : {})
                        }
                    };
                    return event;
                }
                case constants_1.EVENT_NAMES.ORDER_PLACED: {
                    const { order_id, cart_id, total_discounts, discounts } = payload;
                    const event = {
                        ...multiProductEvent,
                        name: constants_1.EVENT_NAMES.ORDER_PLACED,
                        properties: {
                            ...multiProductEvent.properties,
                            order_id: order_id,
                            ...(typeof total_discounts === 'number' ? { total_discounts } : {}),
                            ...(discounts ? { discounts } : {}),
                            ...(cart_id ? { cart_id } : {})
                        }
                    };
                    return event;
                }
                case constants_1.EVENT_NAMES.ORDER_REFUNDED: {
                    const { order_id, total_discounts, discounts } = payload;
                    const event = {
                        ...multiProductEvent,
                        name: constants_1.EVENT_NAMES.ORDER_REFUNDED,
                        properties: {
                            ...multiProductEvent.properties,
                            order_id: order_id,
                            ...(typeof total_discounts === 'number' ? { total_discounts } : {}),
                            ...(discounts ? { discounts } : {})
                        }
                    };
                    return event;
                }
                case constants_1.EVENT_NAMES.ORDER_CANCELLED: {
                    const { order_id, cancel_reason, total_discounts, discounts } = payload;
                    const event = {
                        ...multiProductEvent,
                        name: constants_1.EVENT_NAMES.ORDER_CANCELLED,
                        properties: {
                            ...multiProductEvent.properties,
                            order_id: order_id,
                            cancel_reason: cancel_reason,
                            ...(typeof total_discounts === 'number' ? { total_discounts } : {}),
                            ...(discounts ? { discounts } : {})
                        }
                    };
                    return event;
                }
                default: {
                    throw new actions_core_1.PayloadValidationError(`Unsupported event name: ${name}`);
                }
            }
        }
        default: {
            throw new actions_core_1.PayloadValidationError(`Unsupported event name: ${name}`);
        }
    }
}
function getProductAndMetadataJSON(payload) {
    return payload.products.map(product => {
        const { quantity, product_id, product_name, variant_id, price, image_url, product_url, ...metadata } = product;
        return {
            quantity,
            product_id,
            product_name,
            variant_id,
            price,
            image_url,
            product_url,
            ...(typeof metadata === 'object' && Object.entries(metadata).length > 0 ? { metadata } : {})
        };
    });
}
function validate(payload, isBatch) {
    const { braze_id, user_alias, external_id, email, phone } = payload;
    if (!braze_id && !user_alias && !external_id && !email && !phone) {
        const message = 'One of "external_id" or "user_alias" or "braze_id" or "email" or "phone" is required.';
        if (!isBatch) {
            throw new actions_core_1.PayloadValidationError(message);
        }
        else {
            return message;
        }
    }
}
function currencies() {
    const codes = [
        "AFN", "EUR", "ALL", "DZD", "USD", "EUR", "AOA", "XCD", "XCD", "XAD", "ARS", "AMD",
        "AWG", "AUD", "EUR", "AZN", "BSD", "BHD", "BDT", "BBD", "BYN", "EUR", "BZD", "XOF",
        "BMD", "INR", "BTN", "BOB", "BOV", "USD", "BAM", "BWP", "NOK", "BRL", "USD", "BND",
        "BGN", "XOF", "BIF", "CVE", "KHR", "XAF", "CAD", "KYD", "XAF", "XAF", "CLP", "CLF",
        "CNY", "AUD", "AUD", "COP", "COU", "KMF", "CDF", "XAF", "NZD", "CRC", "XOF", "EUR",
        "CUP", "XCG", "EUR", "CZK", "DKK", "DJF", "XCD", "DOP", "USD", "EGP", "SVC", "USD",
        "XAF", "ERN", "EUR", "SZL", "ETB", "EUR", "FKP", "DKK", "FJD", "EUR", "EUR", "EUR",
        "XPF", "EUR", "XAF", "GMD", "GEL", "EUR", "GHS", "GIP", "EUR", "DKK", "XCD", "EUR",
        "USD", "GTQ", "GBP", "GNF", "XOF", "GYD", "HTG", "USD", "AUD", "EUR", "HNL", "HKD",
        "HUF", "ISK", "INR", "IDR", "XDR", "IRR", "IQD", "EUR", "GBP", "ILS", "EUR", "JMD",
        "JPY", "GBP", "JOD", "KZT", "KES", "AUD", "KPW", "KRW", "KWD", "KGS", "LAK", "EUR",
        "LBP", "LSL", "ZAR", "LRD", "LYD", "CHF", "EUR", "EUR", "MOP", "MGA", "MWK", "MYR",
        "MVR", "XOF", "EUR", "USD", "EUR", "MRU", "MUR", "EUR", "XUA", "MXN", "MXV", "USD",
        "MDL", "EUR", "MNT", "EUR", "XCD", "MAD", "MZN", "MMK", "NAD", "ZAR", "AUD", "NPR",
        "EUR", "XPF", "NZD", "NIO", "XOF", "NGN", "NZD", "AUD", "MKD", "USD", "NOK", "OMR",
        "PKR", "USD", "PAB", "USD", "PGK", "PYG", "PEN", "PHP", "NZD", "PLN", "EUR", "USD",
        "QAR", "EUR", "RON", "RUB", "RWF", "EUR", "SHP", "XCD", "XCD", "EUR", "EUR", "XCD",
        "WST", "EUR", "STN", "SAR", "XOF", "RSD", "SCR", "SLE", "SGD", "XCG", "XSU", "EUR",
        "EUR", "SBD", "SOS", "ZAR", "SSP", "EUR", "LKR", "SDG", "SRD", "NOK", "SEK", "CHF",
        "CHE", "CHW", "SYP", "TWD", "TJS", "TZS", "THB", "USD", "XOF", "NZD", "TOP", "TTD",
        "TND", "TRY", "TMT", "USD", "AUD", "UGX", "UAH", "AED", "GBP", "USD", "USD", "USN",
        "UYU", "UYI", "UYW", "UZS", "VUV", "VES", "VED", "VND", "USD", "USD", "XPF", "MAD",
        "YER", "ZMW", "ZWG"
    ];
    const unique = Array.from(new Set(codes));
    return unique.map(code => ({
        label: code,
        value: code
    }));
}
//# sourceMappingURL=functions.js.map