"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAssociationPayloads = createAssociationPayloads;
exports.sendAssociatedRecords = sendAssociatedRecords;
exports.readAssociatedRecords = readAssociatedRecords;
exports.sendAssociations = sendAssociations;
const constants_1 = require("../constants");
const types_1 = require("../types");
function createAssociationPayloads(payloads, key) {
    const associationPayloads = payloads.flatMap((payload) => Array.isArray(payload[key])
        ? payload[key]
            .filter((association) => association.id_field_value !== undefined &&
            association.id_field_value !== null &&
            association.id_field_value !== '')
            .map((association) => ({
            object_details: {
                object_type: association.object_type,
                id_field_name: association.id_field_name,
                id_field_value: association.id_field_value,
                from_record_id: association.from_record_id
            },
            association_details: {
                association_label: association.association_label
            }
        }))
        : []);
    return groupPayloads(associationPayloads, ['object_type', 'id_field_name']);
}
function groupPayloads(associations, groupBy) {
    const groupedPayloads = [];
    const groups = associations.reduce((acc, payload) => {
        const key = groupBy.map((prop) => payload.object_details[prop]).join('_');
        if (!acc[key]) {
            acc[key] = [];
        }
        acc[key].push(payload);
        return acc;
    }, {});
    for (const key in groups) {
        const items = groups[key];
        for (let i = 0; i < items.length; i += constants_1.MAX_HUBSPOT_BATCH_SIZE) {
            groupedPayloads.push(items.slice(i, i + constants_1.MAX_HUBSPOT_BATCH_SIZE));
        }
    }
    return groupedPayloads;
}
async function sendAssociatedRecords(client, payloads, associationSyncMode) {
    switch (associationSyncMode) {
        case types_1.AssociationSyncMode.Upsert: {
            return await upsertAssociatedRecords(client, payloads);
        }
        case types_1.AssociationSyncMode.Read: {
            return await readAssociatedRecords(client, payloads);
        }
    }
}
async function readAssociatedRecords(client, groupedPayloads) {
    const requests = groupedPayloads.map(async (payloads) => {
        const { object_type: objectType } = payloads[0].object_details;
        return await client.batchObjectRequest(types_1.AssociationSyncMode.Read, objectType, {
            idProperty: payloads[0].object_details.id_field_name,
            properties: [payloads[0].object_details.id_field_name],
            inputs: payloads.map((payload) => {
                return {
                    id: payload.object_details.id_field_value
                };
            })
        });
    });
    const responses = await Promise.all(requests);
    return returnAssociatedRecordsWithIds(groupedPayloads, responses);
}
async function upsertAssociatedRecords(client, groupedPayloads) {
    const requests = groupedPayloads.map(async (payloads) => {
        const { object_type: objectType } = payloads[0].object_details;
        return await client.batchObjectRequest(types_1.AssociationSyncMode.Upsert, objectType, {
            inputs: payloads.map((payload) => {
                return {
                    idProperty: payload.object_details.id_field_name,
                    id: payload.object_details.id_field_value,
                    properties: {
                        [payload.object_details.id_field_name]: payload.object_details.id_field_value
                    }
                };
            })
        });
    });
    const responses = await Promise.all(requests);
    return returnAssociatedRecordsWithIds(groupedPayloads, responses);
}
function returnAssociatedRecordsWithIds(groupedPayloads, responses) {
    responses.forEach((response, index) => {
        const payloads = groupedPayloads[index];
        response?.data?.results.forEach((result) => {
            payloads
                .filter((payload) => payload.object_details.id_field_value == result.properties[payload.object_details.id_field_name])
                .forEach((payload) => (payload.object_details.record_id = result.id));
        });
    });
    return groupedPayloads
        .flat()
        .filter((payload) => payload.object_details.record_id);
}
async function sendAssociations(client, payloads, action) {
    const groupedPayloads = groupPayloads(payloads, [
        'object_type'
    ]);
    const requests = groupedPayloads.map(async (payloads) => {
        const toObjectType = payloads[0].object_details.object_type;
        const inputs = payloads.map((payload) => {
            const { associationCategory, associationTypeId } = getAssociationType(payload.association_details.association_label);
            const input = {
                types: [
                    {
                        associationCategory,
                        associationTypeId
                    }
                ],
                from: {
                    id: payload.object_details.from_record_id
                },
                to: {
                    id: payload.object_details.record_id
                }
            };
            return input;
        });
        if (action === 'archive') {
            return client.batchDissociationsRequest({ inputs }, toObjectType);
        }
        if (action === 'create') {
            return client.batchAssociationsRequest({ inputs }, toObjectType);
        }
    });
    await Promise.all(requests);
}
function getAssociationType(associationLabel) {
    const [associationCategory, associationTypeId] = associationLabel.split(':');
    return { associationCategory, associationTypeId };
}
//# sourceMappingURL=hubspot-association-functions.js.map