"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getUserData = exports.clean = exports.hash = exports.cleanAndHash = exports.hashArray = exports.isHashedInformation = exports.getApiVersion = exports.generateAppData = exports.validateContents = exports.validate = void 0;
exports.send = send;
exports.getBaseEventData = getBaseEventData;
exports.getAddToCartEventData = getAddToCartEventData;
exports.getCustomEventData = getCustomEventData;
exports.getInitiateCheckoutEventData = getInitiateCheckoutEventData;
exports.getPageViewEventData = getPageViewEventData;
exports.getPurchaseEventData = getPurchaseEventData;
exports.getSearchEventData = getSearchEventData;
exports.getViewContentEventData = getViewContentEventData;
const actions_core_1 = require("@segment/actions-core");
const constants_1 = require("./constants");
const hashing_utils_1 = require("../../../lib/hashing-utils");
function send(request, payload, settings, getDataFunction, eventType, features, statsContext) {
    const { test_event_code } = payload;
    const { testEventCode, pixelId } = settings;
    (0, exports.validate)(payload, eventType);
    const data = getDataFunction(payload);
    const json = {
        data: [data],
        ...(test_event_code || testEventCode ? { test_event_code: test_event_code || testEventCode } : {})
    };
    return request(`https://graph.facebook.com/v${(0, exports.getApiVersion)(features, statsContext)}/${pixelId}/events`, {
        method: 'POST',
        json
    });
}
const validate = (payload, eventType) => {
    const { action_source, user_data } = payload;
    if (eventType !== constants_1.EventType.Custom && eventType !== constants_1.EventType.PageView) {
        const { currency, contents } = payload;
        if (eventType === constants_1.EventType.Purchase && !currency) {
            throw new actions_core_1.PayloadValidationError('Must include a currency for Purchase events');
        }
        if (currency && typeof currency === 'string' && !constants_1.CURRENCY_ISO_CODES.has(currency)) {
            throw new actions_core_1.IntegrationError(`${currency} is not a valid currency code.`, actions_core_1.ErrorCodes.INVALID_CURRENCY_CODE, 400);
        }
        if (contents) {
            (0, exports.validateContents)(contents);
        }
    }
    if (!user_data) {
        throw new actions_core_1.PayloadValidationError('Must include at least one user data property');
    }
    if (eventType !== constants_1.EventType.Custom) {
        if (action_source === 'website' && user_data.client_user_agent === undefined) {
            throw new actions_core_1.PayloadValidationError('If action source is "Website" then client_user_agent must be defined');
        }
    }
};
exports.validate = validate;
const validateContents = (contents) => {
    const valid_delivery_categories = ['in_store', 'curbside', 'home_delivery'];
    for (let i = 0; i < contents.length; i++) {
        const item = contents[i];
        if (!item.id) {
            throw new actions_core_1.PayloadValidationError(`contents[${i}] must include an 'id' parameter.`);
        }
        if (item.delivery_category && !valid_delivery_categories.includes(item.delivery_category)) {
            throw new actions_core_1.PayloadValidationError(`contents[${i}].delivery_category must be one of {in_store, home_delivery, curbside}.`);
        }
    }
};
exports.validateContents = validateContents;
function getBaseEventData(payload) {
    const { event_time, action_source, event_source_url, event_id, user_data, app_data_field, data_processing_options, data_processing_options_country, data_processing_options_state } = payload;
    const baseEventData = {
        event_time,
        ...(event_source_url && { event_source_url }),
        ...(event_id && { event_id }),
        action_source,
        user_data: (0, exports.getUserData)(user_data),
        ...(() => {
            const app_data = (0, exports.generateAppData)(app_data_field);
            return app_data ? { app_data } : {};
        })(),
        ...(data_processing_options ? { data_processing_options: ['LDU'] } : {}),
        ...(data_processing_options ? { data_processing_options_country: data_processing_options_country || 0 } : {}),
        ...(data_processing_options ? { data_processing_options_state: data_processing_options_state || 0 } : {})
    };
    return baseEventData;
}
function getAddToCartEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const { custom_data, content_name, currency, value, content_ids, content_type, contents } = payload;
    const data = {
        event_name: 'AddToCart',
        ...baseEventData,
        custom_data: {
            ...custom_data,
            currency: currency,
            ...(typeof value === 'number' ? { value } : {}),
            ...(Array.isArray(content_ids) && content_ids.length > 0 && { content_ids }),
            ...(content_name && { content_name }),
            ...(content_type && { content_type }),
            ...(contents && { contents })
        }
    };
    return data;
}
function getCustomEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const { custom_data, event_name } = payload;
    const data = {
        event_name,
        ...baseEventData,
        custom_data: { ...custom_data }
    };
    return data;
}
function getInitiateCheckoutEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const { custom_data, currency, value, content_ids, content_category, num_items, contents } = payload;
    const data = {
        event_name: 'InitiateCheckout',
        ...baseEventData,
        custom_data: {
            ...custom_data,
            currency: currency,
            ...(typeof value === 'number' ? { value } : {}),
            ...(Array.isArray(content_ids) && content_ids.length > 0 && { content_ids }),
            ...(contents && { contents }),
            ...(typeof num_items === 'number' && { num_items }),
            ...(content_category && { content_category })
        }
    };
    return data;
}
function getPageViewEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const data = {
        event_name: 'PageView',
        ...baseEventData
    };
    return data;
}
function getPurchaseEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const { custom_data, currency, value, content_ids, net_revenue, content_name, content_type, num_items, contents } = payload;
    const data = {
        event_name: 'Purchase',
        ...baseEventData,
        custom_data: {
            ...custom_data,
            currency,
            value,
            ...(typeof net_revenue === 'number' && { net_revenue }),
            ...(Array.isArray(content_ids) && content_ids.length > 0 && { content_ids }),
            ...(content_name && { content_name }),
            ...(content_type && { content_type }),
            ...(contents && { contents }),
            ...(typeof num_items === 'number' && { num_items })
        }
    };
    return data;
}
function getSearchEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const { custom_data, currency, value, content_ids, search_string, content_category, contents } = payload;
    const data = {
        event_name: 'Search',
        ...baseEventData,
        custom_data: {
            ...custom_data,
            currency: currency,
            value,
            ...(Array.isArray(content_ids) && content_ids.length > 0 && { content_ids }),
            ...(contents && { contents }),
            ...(content_category && { content_category }),
            ...(search_string && { search_string })
        }
    };
    return data;
}
function getViewContentEventData(payload) {
    const baseEventData = getBaseEventData(payload);
    const { custom_data, currency, value, content_ids, content_category, content_name, content_type, contents } = payload;
    const data = {
        event_name: 'ViewContent',
        ...baseEventData,
        custom_data: {
            ...custom_data,
            currency: currency,
            value,
            ...(Array.isArray(content_ids) && content_ids.length > 0 && { content_ids }),
            ...(content_name && { content_name }),
            ...(content_type && { content_type }),
            ...(contents && { contents }),
            ...(content_category && { content_category })
        }
    };
    return data;
}
const generateAppData = (app_data) => {
    const { use_app_data, advertiser_tracking_enabled, application_tracking_enabled, madId, version, packageName, shortVersion, longVersion, osVersion, deviceName, locale, timezone, carrier, width, height, density, cpuCores, storageSize, freeStorage, deviceTimezone } = app_data || {};
    if (!app_data || !use_app_data) {
        return undefined;
    }
    return {
        advertiser_tracking_enabled: advertiser_tracking_enabled ? 1 : 0,
        application_tracking_enabled: application_tracking_enabled ? 1 : 0,
        madid: madId,
        extinfo: [
            version ?? '',
            packageName ?? '',
            shortVersion ?? '',
            longVersion ?? '',
            osVersion ?? '',
            deviceName ?? '',
            locale ?? '',
            timezone ?? '',
            carrier ?? '',
            width ?? '',
            height ?? '',
            density ?? '',
            cpuCores ?? '',
            storageSize ?? '',
            freeStorage ?? '',
            deviceTimezone ?? ''
        ]
    };
};
exports.generateAppData = generateAppData;
const getApiVersion = (features, statsContext) => {
    const statsClient = statsContext?.statsClient;
    const tags = statsContext?.tags;
    if (features && features[constants_1.FLAGON_NAME]) {
        tags?.push(`version:${constants_1.CANARY_API_VERSION}`);
        statsClient?.incr(`fb_api_version`, 1, tags);
        return constants_1.CANARY_API_VERSION;
    }
    tags?.push(`version:${constants_1.API_VERSION}`);
    statsClient?.incr(`fb_api_version`, 1, tags);
    return constants_1.API_VERSION;
};
exports.getApiVersion = getApiVersion;
const isHashedInformation = (information) => new RegExp(/[0-9abcdef]{64}/gi).test(information);
exports.isHashedInformation = isHashedInformation;
const hashArray = (values) => {
    if (!values?.length) {
        return undefined;
    }
    const cleaned = (Array.isArray(values) ? values : [values]).map((item) => (0, exports.clean)(item)).filter(Boolean);
    const hashed = cleaned.map((item) => (0, exports.hash)(item)).filter(Boolean);
    return hashed.length ? hashed : undefined;
};
exports.hashArray = hashArray;
const cleanAndHash = (value) => {
    return (0, exports.hash)((0, exports.clean)(value));
};
exports.cleanAndHash = cleanAndHash;
const hash = (value) => {
    if (value === undefined || !value.length) {
        return undefined;
    }
    return (0, hashing_utils_1.processHashing)(value, 'sha256', 'hex');
};
exports.hash = hash;
const clean = (value) => {
    if (value === undefined || !value.length) {
        return undefined;
    }
    return value.replace(/\s/g, '').toLowerCase() || undefined;
};
exports.clean = clean;
const getUserData = (payloadUserData) => {
    const { email, phone, gender, dateOfBirth, lastName, firstName, city, state, zip, country, externalId, client_ip_address, client_user_agent, fbc, fbp, subscriptionID, leadID, anonId, madId, fbLoginID, partner_id, partner_name } = payloadUserData ?? {};
    const em = (0, exports.cleanAndHash)(email);
    const ph = (() => {
        if (!phone) {
            return undefined;
        }
        if (!(0, exports.isHashedInformation)(phone)) {
            const digits = phone.replace(/\D/g, '');
            return (0, exports.hash)(digits);
        }
        return phone;
    })();
    const ge = (() => {
        if (!gender) {
            return undefined;
        }
        if ((0, exports.isHashedInformation)(gender)) {
            return gender;
        }
        switch (gender.replace(/\s/g, '').toLowerCase()) {
            case 'male':
            case 'm':
                return (0, exports.cleanAndHash)('m');
            case 'female':
            case 'f':
                return (0, exports.cleanAndHash)('f');
            default:
                return undefined;
        }
    })();
    const db = (0, exports.cleanAndHash)(dateOfBirth);
    const ln = (0, exports.cleanAndHash)(lastName);
    const fn = (0, exports.cleanAndHash)(firstName);
    const ct = (0, exports.cleanAndHash)(city);
    const st = (() => {
        const stateCleaned = (0, exports.clean)(state);
        return (0, exports.hash)(constants_1.US_STATE_CODES.get(stateCleaned ?? '') ?? (stateCleaned || undefined));
    })();
    const zp = (0, exports.cleanAndHash)(zip);
    const countryValue = (() => {
        const cleaned = (0, exports.clean)(country);
        return (0, exports.hash)(constants_1.COUNTRY_CODES.get(cleaned ?? '') ?? cleaned);
    })();
    const external_id = (0, exports.hashArray)(externalId);
    const userData = {
        ...(em ? { em } : {}),
        ...(ph ? { ph } : {}),
        ...(ge ? { ge } : {}),
        ...(db ? { db } : {}),
        ...(ln ? { ln } : {}),
        ...(fn ? { fn } : {}),
        ...(ct ? { ct } : {}),
        ...(st ? { st } : {}),
        ...(zp ? { zp } : {}),
        ...(countryValue ? { country: countryValue } : {}),
        ...(external_id ? { external_id } : {}),
        ...(client_ip_address ? { client_ip_address } : {}),
        ...(client_user_agent ? { client_user_agent } : {}),
        ...(fbc ? { fbc } : {}),
        ...(fbp ? { fbp } : {}),
        ...(subscriptionID ? { subscription_id: subscriptionID } : {}),
        ...(typeof leadID === 'number' ? { lead_id: leadID } : {}),
        ...(anonId ? { anon_id: anonId } : {}),
        ...(madId ? { madid: madId } : {}),
        ...(typeof fbLoginID === 'number' ? { fb_login_id: fbLoginID } : {}),
        ...(partner_id ? { partner_id } : {}),
        ...(partner_name ? { partner_name } : {})
    };
    return userData;
};
exports.getUserData = getUserData;
//# sourceMappingURL=functions.js.map