"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizePhone = exports.normalize = void 0;
exports.send = send;
const hashing_utils_1 = require("../../../lib/hashing-utils");
const actions_core_1 = require("@segment/actions-core");
const constants_1 = require("./constants");
async function send(request, payload) {
    const payloads = payload.map((p, index) => ({ ...p, index }));
    const { external_audience_id } = payload[0];
    const multiStatusResponse = new actions_core_1.MultiStatusResponse();
    const batches = payloads.reduce((acc, p) => {
        const hasValue = Boolean(p.email || p.phone || p.advertising_id);
        if (!hasValue) {
            multiStatusResponse.setErrorResponseAtIndex(p.index, {
                status: 400,
                errortype: 'PAYLOAD_VALIDATION_FAILED',
                errormessage: 'One of "email" or "phone" or "Mobile Advertising ID" is required.'
            });
            return acc;
        }
        const isAdd = Boolean(p.props[p.audienceKey]);
        if (p.email) {
            (isAdd ? acc.addEmail.opPayloads : acc.removeEmail.opPayloads).push(p);
        }
        if (p.phone) {
            (isAdd ? acc.addPhone.opPayloads : acc.removePhone.opPayloads).push(p);
        }
        if (p.advertising_id) {
            (isAdd ? acc.addMAID.opPayloads : acc.removeMAID.opPayloads).push(p);
        }
        return acc;
    }, {
        addEmail: { opPayloads: [], operationType: { method: 'POST', type: constants_1.SCHEMA_TYPES.EMAIL } },
        addPhone: { opPayloads: [], operationType: { method: 'POST', type: constants_1.SCHEMA_TYPES.PHONE } },
        addMAID: { opPayloads: [], operationType: { method: 'POST', type: constants_1.SCHEMA_TYPES.MAID } },
        removeEmail: { opPayloads: [], operationType: { method: 'DELETE', type: constants_1.SCHEMA_TYPES.EMAIL } },
        removePhone: { opPayloads: [], operationType: { method: 'DELETE', type: constants_1.SCHEMA_TYPES.PHONE } },
        removeMAID: { opPayloads: [], operationType: { method: 'DELETE', type: constants_1.SCHEMA_TYPES.MAID } },
    });
    const url = `https://adsapi.snapchat.com/v1/segments/${external_audience_id}/users`;
    await Promise.all(Object.entries(batches)
        .filter(([, batch]) => batch.opPayloads.length > 0)
        .map(async ([, batch]) => {
        const { opPayloads, operationType: { type, method } } = batch;
        const json = buildJSON(opPayloads, type);
        try {
            await request(url, { method, json });
            opPayloads.forEach((p) => {
                const existingResponse = multiStatusResponse.getResponseAtIndex(p.index)?.value();
                const status = existingResponse?.status;
                if (typeof status === 'number' && (status < 200 || status >= 300)) {
                    return;
                }
                multiStatusResponse.setSuccessResponseAtIndex(p.index, {
                    status: 200,
                    sent: json.users[p.index],
                    body: JSON.stringify(p)
                });
            });
        }
        catch (error) {
            for (const p of opPayloads) {
                multiStatusResponse.setErrorResponseAtIndex(p.index, {
                    status: error?.response?.status || 400,
                    errortype: 'BAD_REQUEST',
                    errormessage: error.message || 'Unknown error',
                    sent: json.users[p.index],
                    body: JSON.stringify(p)
                });
            }
        }
    }));
    return multiStatusResponse;
}
function buildJSON(payloads, type) {
    const seen = new Set();
    const data = payloads.reduce((acc, p) => {
        let value;
        if (type === constants_1.SCHEMA_TYPES.EMAIL && p.email) {
            value = (0, hashing_utils_1.processHashing)(p.email, 'sha256', 'hex', exports.normalize);
        }
        else if (type === constants_1.SCHEMA_TYPES.PHONE && p.phone) {
            value = (0, hashing_utils_1.processHashing)(p.phone, 'sha256', 'hex', exports.normalizePhone);
        }
        else if (type === constants_1.SCHEMA_TYPES.MAID && p.advertising_id) {
            value = (0, hashing_utils_1.processHashing)(p.advertising_id, 'sha256', 'hex', exports.normalize);
        }
        if (value && !seen.has(value)) {
            seen.add(value);
            acc.push([value]);
        }
        return acc;
    }, []);
    return {
        users: [
            {
                schema: [type],
                data
            }
        ]
    };
}
const normalize = (identifier) => {
    return identifier.trim().toLowerCase();
};
exports.normalize = normalize;
const normalizePhone = (phone) => {
    let normalizedPhone = phone.replace(/[\s()+-]/g, '');
    if (normalizedPhone.startsWith('00')) {
        normalizedPhone = normalizedPhone.substring(2);
    }
    if (normalizedPhone.startsWith('0')) {
        normalizedPhone = normalizedPhone.substring(1);
    }
    return normalizedPhone;
};
exports.normalizePhone = normalizePhone;
//# sourceMappingURL=functions.js.map