"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.send = send;
const actions_core_1 = require("@segment/actions-core");
const constants_1 = require("../constants");
const functions_1 = require("../functions");
async function send(request, region, payload, isBatch) {
    const msResponse = new actions_core_1.MultiStatusResponse();
    const segmentId = payload[0]?.segmentAudienceId;
    if (!segmentId) {
        payload.forEach((p, index) => {
            handleError('PayloadValidationError', 'Missing Pendo Segment ID', isBatch, msResponse, index, p, 400);
        });
        return msResponse;
    }
    const adds = new Map();
    const removes = new Map();
    payload.forEach((p, index) => {
        const { visitorId, traitsOrProperties, segmentAudienceKey } = p;
        if (!visitorId) {
            handleError('PayloadValidationError', 'Visitor ID is required', isBatch, msResponse, index, p, 400);
            return;
        }
        const isAdding = Boolean(traitsOrProperties[segmentAudienceKey]);
        if (isAdding) {
            adds.set(index, visitorId);
        }
        else {
            removes.set(index, visitorId);
        }
    });
    if (adds.size === 0 && removes.size === 0) {
        return msResponse;
    }
    const patchBody = { patch: [] };
    if (adds.size > 0) {
        patchBody.patch.push({
            op: 'add',
            path: '/visitors',
            value: Array.from(adds.values())
        });
    }
    if (removes.size > 0) {
        patchBody.patch.push({
            op: 'remove',
            path: '/visitors',
            value: Array.from(removes.values())
        });
    }
    try {
        const response = await request(`${(0, functions_1.getDomain)(region)}/${constants_1.SEGMENT_ENDPOINT}/${segmentId}/visitor`, {
            method: 'PATCH',
            json: patchBody
        });
        const data = response?.data;
        data.multistatus.forEach((item) => {
            const isSuccess = item.status >= 200 && item.status < 300;
            const map = item.operation === 'add' ? adds : removes;
            map.forEach((visitorId, index) => {
                const p = payload[index];
                if (isSuccess) {
                    msResponse.setSuccessResponseAtIndex(index, {
                        status: item.status,
                        body: p,
                        sent: buildSent(item.operation, visitorId)
                    });
                }
                else {
                    handleError('IntegrationError', item.message, isBatch, msResponse, index, p, item.status, buildSent(item.operation, visitorId));
                }
            });
        });
    }
    catch (error) {
        const status = error?.response?.status || 500;
        const message = error?.message || 'An error occurred while syncing visitors to Pendo Segment.';
        const allIndices = [...adds.keys(), ...removes.keys()];
        allIndices.forEach((index) => {
            const visitorId = adds.get(index) ?? removes.get(index);
            const op = adds.has(index) ? 'add' : 'remove';
            handleError('IntegrationError', message, isBatch, msResponse, index, payload[index], status, buildSent(op, visitorId));
        });
    }
    if (isBatch) {
        return msResponse;
    }
    return;
}
function buildSent(op, visitorId) {
    return { patch: [{ op, path: '/visitors', value: [visitorId] }] };
}
function handleError(errType, message, isBatch, msResponse, index, payload, status = 400, sent) {
    if (!isBatch) {
        if (errType === 'PayloadValidationError') {
            throw new actions_core_1.PayloadValidationError(message);
        }
        else {
            throw new actions_core_1.IntegrationError(message, (0, actions_core_1.getErrorCodeFromHttpStatus)(status) || actions_core_1.ErrorCodes.UNKNOWN_ERROR, status);
        }
    }
    msResponse.setErrorResponseAtIndex(index, {
        status,
        body: payload,
        errormessage: message,
        ...(sent && { sent })
    });
}
//# sourceMappingURL=functions.js.map