"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.FLAGON_NAME = exports.CANARY_API_VERSION = exports.API_VERSION = void 0;
exports.getApiVersion = getApiVersion;
exports.send = send;
exports.getJSON = getJSON;
exports.getCustomVarTypeChoices = getCustomVarTypeChoices;
exports.getEntityTypeChoices = getEntityTypeChoices;
exports.getSources = getSources;
const actions_core_1 = require("@segment/actions-core");
const types_1 = require("./types");
const hashing_utils_1 = require("../../lib/hashing-utils");
const versioning_info_1 = require("./versioning-info");
exports.API_VERSION = versioning_info_1.GOOGLE_CM360_API_VERSION;
exports.CANARY_API_VERSION = versioning_info_1.GOOGLE_CM360_CANARY_API_VERSION;
exports.FLAGON_NAME = 'cm360-canary-api-version';
function getApiVersion(features) {
    return features && features[exports.FLAGON_NAME] ? exports.CANARY_API_VERSION : exports.API_VERSION;
}
async function send(request, settings, payloads, isAdjustment, auth, features) {
    const json = getJSON(payloads, settings);
    if (json.conversions.length === 0) {
        maybeThrow(`No valid payloads found in batch of size ${payloads.length}`, true);
    }
    const version = getApiVersion(features);
    const response = await request(`https://dfareporting.googleapis.com/dfareporting/${version}/userprofiles/${settings.profileId}/conversions/batch` +
        (isAdjustment ? 'update' : 'insert'), {
        method: 'POST',
        headers: {
            Authorization: `Bearer ${auth?.accessToken}`,
            'Content-Type': 'application/json',
            Host: 'dfareporting.googleapis.com'
        },
        json
    });
    const isSuccess = response.status >= 200 && response.status < 300;
    const hasFailures = response?.data?.hasFailures === true;
    if (isSuccess && hasFailures) {
        const firstError = response?.data?.status?.[0]?.errors?.[0];
        const message = firstError?.message ?? '200 response contained unknown error';
        const code = firstError?.code ?? actions_core_1.ErrorCodes.UNKNOWN_ERROR;
        throw new actions_core_1.IntegrationError(message, code, 400);
    }
    return response;
}
function getJSON(payloads, settings) {
    const json = {
        conversions: [],
        kind: 'dfareporting#conversionsBatchInsertRequest'
    };
    const shouldThrow = payloads.length === 1;
    for (const payload of payloads) {
        const { customVariables, requiredId: { encryptedUserIdCandidates } } = payload;
        const { requiredId: { gclid, dclid, encryptedUserId, mobileDeviceId, matchId, impressionId }, encryptionInfo, adUserDataConsent, cartDataItems, merchantId, merchantFeedLabel, merchantFeedLanguage, userDetails, floodlightActivityId, floodlightConfigurationId, timestamp, value, ordinal, quantity, limitAdTracking, childDirectedTreatment, nonPersonalizedAd, treatmentForUnderage } = payload;
        if ([gclid, dclid, encryptedUserId, mobileDeviceId, matchId, impressionId, encryptedUserIdCandidates].filter(Boolean)
            .length !== 1) {
            maybeThrow('Exactly one of Google Click ID, Display Click ID, Encrypted User ID, Mobile Device ID, Match ID, Impression ID or Encrypted User ID Candidates is required', shouldThrow);
            continue;
        }
        if (!floodlightActivityId && !settings.defaultFloodlightActivityId) {
            maybeThrow('Floodlight Activity ID is required', shouldThrow);
            continue;
        }
        if (!floodlightConfigurationId && !settings.defaultFloodlightConfigurationId) {
            maybeThrow('Floodlight Configuration ID is required', shouldThrow);
            continue;
        }
        if ((encryptedUserId || encryptedUserIdCandidates) && !encryptionInfo) {
            maybeThrow('Encrypted Info field should be populated if either Encrypted User ID or Encrypted User ID Candidates fields are populated', shouldThrow);
            continue;
        }
        const conversion = {
            adUserDataConsent: adUserDataConsent,
            cartData: (() => {
                if (!Array.isArray(cartDataItems) ||
                    cartDataItems.length === 0 ||
                    merchantId ||
                    !merchantFeedLabel ||
                    !merchantFeedLanguage) {
                    return undefined;
                }
                return {
                    merchantId,
                    merchantFeedLabel,
                    merchantFeedLanguage,
                    items: cartDataItems
                };
            })(),
            childDirectedTreatment: childDirectedTreatment ?? undefined,
            dclid: dclid ?? undefined,
            encryptedUserId: encryptedUserId ?? undefined,
            floodlightActivityId: (floodlightActivityId ?? settings.defaultFloodlightActivityId),
            floodlightConfigurationId: (floodlightConfigurationId ?? settings.defaultFloodlightConfigurationId),
            gclid: gclid ?? undefined,
            impressionId: impressionId ?? undefined,
            kind: 'dfareporting#conversion',
            limitAdTracking: limitAdTracking ?? undefined,
            matchId: matchId ?? undefined,
            mobileDeviceId: mobileDeviceId ?? undefined,
            nonPersonalizedAd: nonPersonalizedAd ?? undefined,
            ordinal,
            quantity,
            timestampMicros: (() => {
                return String(BigInt(new Date(timestamp).getTime()) * 1000n);
            })(),
            treatmentForUnderage: treatmentForUnderage ?? undefined,
            userIdentifiers: (() => {
                const { email, phone, firstName, lastName, streetAddress, city, state, postalCode, countryCode } = userDetails ?? {};
                const identifiers = [];
                if (email) {
                    identifiers.push({
                        hashedEmail: (0, hashing_utils_1.processHashing)(email, 'sha256', 'hex')
                    });
                }
                if (phone) {
                    identifiers.push({
                        hashedPhoneNumber: (0, hashing_utils_1.processHashing)(phone, 'sha256', 'hex')
                    });
                }
                if (firstName || lastName || streetAddress || city || state || postalCode || countryCode) {
                    const addressInfo = {
                        hashedFirstName: firstName ? (0, hashing_utils_1.processHashing)(firstName, 'sha256', 'hex') : undefined,
                        hashedLastName: lastName ? (0, hashing_utils_1.processHashing)(lastName, 'sha256', 'hex') : undefined,
                        hashedStreetAddress: streetAddress ? (0, hashing_utils_1.processHashing)(streetAddress, 'sha256', 'hex') : undefined,
                        city: city ?? undefined,
                        state: state ?? undefined,
                        postalCode: postalCode ?? undefined,
                        countryCode: countryCode ?? undefined
                    };
                    identifiers.push({ addressInfo });
                }
                return identifiers;
            })(),
            value,
            customVariables: Array.isArray(customVariables)
                ? customVariables
                    .filter((c) => c.type.length > 0 && c.value.length > 0)
                    .map((c) => ({
                    type: c.type,
                    value: c.value,
                    kind: 'dfareporting#customFloodlightVariable'
                }))
                : [],
            encryptedUserIdCandidates: encryptedUserIdCandidates
                ?.split(',')
                .map((value) => {
                return (0, hashing_utils_1.processHashing)(value, 'sha256', 'hex');
            })
                .filter((str) => str !== undefined) ?? []
        };
        json.conversions.push(conversion);
        json.encryptionInfo =
            encryptedUserId || encryptedUserIdCandidates
                ? {
                    ...encryptionInfo,
                    kind: 'dfareporting#encryptionInfo'
                }
                : undefined;
    }
    return json;
}
function maybeThrow(message, shouldThrow) {
    if (shouldThrow) {
        throw new actions_core_1.PayloadValidationError(message);
    }
}
function getCustomVarTypeChoices() {
    return types_1.CustomVarTypeChoices.map((item) => ({
        label: item,
        value: item
    }));
}
function getEntityTypeChoices() {
    return Object.values(types_1.EntityType).map((item) => ({
        label: item,
        value: item
    }));
}
function getSources() {
    return Object.values(types_1.Source).map((item) => ({
        label: item,
        value: item
    }));
}
//# sourceMappingURL=utils.js.map