"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mapPayload = mapPayload;
exports.formatAttributes = formatAttributes;
exports.formatIdentifiers = formatIdentifiers;
exports.handleMultiStatusResponse = handleMultiStatusResponse;
const constants_1 = require("../constants");
const actions_core_1 = require("@segment/actions-core");
function mapPayload(payload) {
    const { profileAttributes: { language, email_address, phone_number, email_marketing, sms_marketing, region, timezone, ...customAttributes } = {}, identifiers, eventName, eventAttributes } = payload;
    const nativeProfileAttributes = {
        $email_address: email_address,
        $phone_number: phone_number,
        $email_marketing: email_marketing === 'reset' ? null : email_marketing,
        $sms_marketing: sms_marketing === 'reset' ? null : sms_marketing,
        $language: extractLanguage(language),
        $region: extractRegion(region),
        $timezone: timezone
    };
    Object.keys(nativeProfileAttributes).forEach((key) => {
        delete customAttributes[key];
    });
    const customProfileAttributes = formatAttributes(customAttributes, false);
    const attributes = Object.fromEntries(Object.entries({ ...nativeProfileAttributes, ...customProfileAttributes }).slice(0, constants_1.MAX_ATTRIBUTES_SIZE));
    const eventNameCleaned = formatEventName(eventName);
    const events = eventNameCleaned
        ? [
            {
                name: eventNameCleaned,
                attributes: formatAttributes(eventAttributes ?? {}, true)
            }
        ]
        : undefined;
    const json = {
        identifiers: formatIdentifiers(identifiers),
        attributes: Object.keys(attributes).length === 0 ? undefined : attributes,
        events
    };
    return json;
}
function formatAttributes(attributes, allowObjects) {
    const result = {};
    for (const [key, value] of Object.entries(attributes)) {
        const newKey = correctKey(key, value);
        if (typeof value === 'string') {
            result[newKey] = value;
        }
        else if (typeof value === 'number' || typeof value === 'boolean' || value === null) {
            result[newKey] = value;
        }
        else if (allowObjects) {
            if (Array.isArray(value)) {
                if (value.every((item) => typeof item === 'string')) {
                    result[newKey] = value;
                }
                else if (value.every(isFlatObject)) {
                    result[newKey] = value.map((obj) => formatFlatObject(obj));
                }
            }
            else if (isFlatObject(value)) {
                result[newKey] = formatFlatObject(value);
            }
        }
    }
    return result;
}
function formatIdentifiers(identifiers) {
    const cleanedIdentifiers = {
        custom_id: identifiers.custom_id,
        ...Object.fromEntries(Object.entries(identifiers)
            .filter(([key]) => key !== 'custom_id')
            .map(([key, value]) => [key, String(value)]))
    };
    return cleanedIdentifiers;
}
function handleMultiStatusResponse(response, payloads, json) {
    const msResponse = new actions_core_1.MultiStatusResponse();
    if (response.code === 'SUCCESS_WITH_PARTIAL_ERRORS') {
        payloads.forEach((payload, index) => {
            const matchingError = response.errors.find((error) => error.bulk_index === index);
            if (matchingError) {
                msResponse.setErrorResponseAtIndex(index, {
                    status: 400,
                    errormessage: matchingError.reason,
                    sent: payload,
                    body: JSON.stringify(json[index])
                });
            }
            else {
                msResponse.setSuccessResponseAtIndex(index, {
                    status: 202,
                    sent: payload,
                    body: JSON.stringify(json[index])
                });
            }
        });
        return msResponse;
    }
    else {
        payloads.forEach((payload, index) => {
            msResponse.setSuccessResponseAtIndex(index, {
                status: 202,
                sent: payload,
                body: JSON.stringify(json[index])
            });
        });
        return msResponse;
    }
}
function formatEventName(eventName) {
    if (!eventName)
        return undefined;
    const e = eventName.toLowerCase().replace(/[^a-z0-9_]/g, '_');
    return e.length > 0 ? e : undefined;
}
function extractLanguage(language) {
    if (language === null)
        return null;
    const lang = language?.trim().split('-')[0];
    return lang && lang.length === 2 ? lang : undefined;
}
function extractRegion(region) {
    if (region === null)
        return null;
    if (!region)
        return undefined;
    if (region.length === 2)
        return region;
    const regionFromLocale = region.trim().split('-')[1];
    return regionFromLocale?.length === 2 ? regionFromLocale : undefined;
}
function fixAttributeName(name) {
    return name.toLowerCase().replace(/[^a-z0-9_]/g, '');
}
function correctKey(key, value) {
    if (typeof value === 'string') {
        if (isISO8601Date(value))
            return `date(${fixAttributeName(key)})`;
        if (isValidUrl(value))
            return `url(${fixAttributeName(key)})`;
        return fixAttributeName(key);
    }
    return key;
}
function isFlatObject(obj) {
    if (typeof obj !== 'object' || obj === null)
        return false;
    return Object.values(obj).every((value) => ['string', 'number', 'boolean'].includes(typeof value) || value === null || value === undefined);
}
function formatFlatObject(obj) {
    const result = {};
    for (const [key, value] of Object.entries(obj)) {
        result[correctKey(key, value)] = value;
    }
    return result;
}
function isISO8601Date(value) {
    const iso8601Regex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3,6})?Z$/;
    return iso8601Regex.test(value);
}
function isValidUrl(value) {
    const urlRegex = /^(https?|ftp):\/\/[^\s/$.?#].[^\s]*$/i;
    return urlRegex.test(value);
}
//# sourceMappingURL=utils.js.map