"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.processData = processData;
const actions_core_1 = require("@segment/actions-core");
const index_1 = require("../googleapis/index");
const constants_1 = require("../constants");
const a1_notation_1 = __importDefault(require("@segment/a1-notation"));
const DATA_ROW_OFFSET = 2;
const generateColumnValuesFromFields = (identifier, fields, columns) => {
    const retVal = columns.map((col) => fields[col] ?? '');
    retVal.unshift(identifier);
    return retVal;
};
function processGetSpreadsheetResponse(response, events, mappingSettings, syncMode) {
    const numColumns = mappingSettings.columns.length;
    const numRows = response.values?.length;
    if (numRows * numColumns > constants_1.CONSTANTS.MAX_CELLS) {
        throw new actions_core_1.IntegrationError(`Sheet has reached maximum limit supported by Segment: ${constants_1.CONSTANTS.MAX_CELLS} cells.`, 'INVALID_REQUEST_DATA', 400);
    }
    const updateBatch = [];
    const appendBatch = [];
    const eventMap = new Map(events.map((e) => [e.record_identifier, e]));
    if (response.values && response.values.length > 0) {
        for (let i = 0; i < response.values.length; i++) {
            const targetIdentifier = response.values[i][0];
            if (eventMap.has(targetIdentifier)) {
                const targetEvent = eventMap.get(targetIdentifier);
                if (syncMode == 'upsert' || syncMode == 'update') {
                    updateBatch.push({
                        identifier: targetIdentifier,
                        event: targetEvent.fields,
                        index: i
                    });
                }
                eventMap.delete(targetIdentifier);
            }
        }
    }
    eventMap.forEach((value, key) => {
        if (syncMode == 'upsert' || syncMode == 'add') {
            appendBatch.push({
                identifier: key,
                event: value.fields
            });
        }
    });
    return { appendBatch, updateBatch };
}
async function processUpdateBatch(mappingSettings, updateBatch, gs) {
    const getRange = (targetIndex, columnCount) => {
        const targetRange = new a1_notation_1.default(1, targetIndex);
        targetRange.addX(columnCount);
        return targetRange.toString();
    };
    const batchPayload = updateBatch.map(({ identifier, event, index }) => {
        const values = generateColumnValuesFromFields(identifier, event, mappingSettings.columns);
        return {
            range: `${mappingSettings.spreadsheetName}!${getRange(index + DATA_ROW_OFFSET, values.length)}`,
            values: [values]
        };
    });
    const headerRowRange = new a1_notation_1.default(1, 1, 1, mappingSettings.columns.length + 1);
    batchPayload.push({
        range: `${mappingSettings.spreadsheetName}!${headerRowRange.toString()}`,
        values: [['id', ...mappingSettings.columns]]
    });
    return gs.batchUpdate(mappingSettings, batchPayload);
}
async function processAppendBatch(mappingSettings, appendBatch, gs) {
    if (appendBatch.length <= 0) {
        return;
    }
    const values = appendBatch.map(({ identifier, event }) => generateColumnValuesFromFields(identifier, event, mappingSettings.columns));
    return gs.append(mappingSettings, `A${DATA_ROW_OFFSET}`, values);
}
async function processData(request, events, syncMode) {
    const mappingSettings = {
        spreadsheetId: events[0].spreadsheet_id,
        spreadsheetName: events[0].spreadsheet_name,
        dataFormat: events[0].data_format,
        columns: Object.getOwnPropertyNames(events[0].fields)
    };
    const gs = new index_1.GoogleSheets(request);
    const response = await gs.get(mappingSettings, `A${DATA_ROW_OFFSET}:A`);
    const { appendBatch, updateBatch } = processGetSpreadsheetResponse(response.data, events, mappingSettings, syncMode);
    const promises = [
        processUpdateBatch(mappingSettings, updateBatch, gs),
        processAppendBatch(mappingSettings, appendBatch, gs)
    ];
    return await Promise.all(promises);
}
//# sourceMappingURL=operations2.js.map