"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.send = send;
exports.parseFieldValue = parseFieldValue;
exports.validateContentSid = validateContentSid;
exports.getSender = getSender;
exports.getSendAt = getSendAt;
const actions_core_1 = require("@segment/actions-core");
const constants_1 = require("./constants");
async function send(request, payload, settings) {
    let { toPhoneNumber, contentSid, toMessengerUserId } = payload;
    const { channel, contentVariables, validityPeriod, inlineMediaUrls, inlineBody, contentTemplateType, tags } = payload;
    const getTo = () => {
        switch (channel) {
            case constants_1.CHANNELS.SMS:
            case constants_1.CHANNELS.MMS:
            case constants_1.CHANNELS.RCS: {
                toPhoneNumber = toPhoneNumber?.trim() ?? '';
                if (!(constants_1.E164_REGEX.test(toPhoneNumber) || constants_1.TWILIO_SHORT_CODE_REGEX.test(toPhoneNumber))) {
                    throw new actions_core_1.PayloadValidationError("'To' field should be a valid phone number in E.164 format or a Twilio Short Code");
                }
                return toPhoneNumber;
            }
            case constants_1.CHANNELS.WHATSAPP: {
                toPhoneNumber = toPhoneNumber?.trim() ?? '';
                if (!constants_1.E164_REGEX.test(toPhoneNumber)) {
                    throw new actions_core_1.PayloadValidationError("'To' field should be a valid phone number in E.164 format");
                }
                return `whatsapp:${toPhoneNumber}`;
            }
            case constants_1.CHANNELS.MESSENGER: {
                toMessengerUserId = toMessengerUserId?.trim() ?? '';
                return `messenger:${toMessengerUserId}`;
            }
            default: {
                throw new actions_core_1.PayloadValidationError('Unsupported Channel');
            }
        }
    };
    const getValidityPeriod = () => (validityPeriod ? { ValidityPeriod: validityPeriod } : {});
    const getContent = () => {
        if (contentTemplateType === constants_1.ALL_CONTENT_TYPES.INLINE.friendly_name) {
            return {
                Body: inlineBody || ''
            };
        }
        contentSid = parseFieldValue(contentSid);
        if (!contentSid) {
            throw new actions_core_1.PayloadValidationError("'Content Template SID' field value is required when sending a content template message.");
        }
        if (!constants_1.CONTENT_SID_REGEX.test(contentSid)) {
            throw new actions_core_1.PayloadValidationError("'Content Template SID' field value should start with 'HX' followed by 32 hexadecimal characters.");
        }
        const contentTemplate = {
            ContentSid: contentSid
        };
        if (Object.keys(contentVariables ?? {}).length > 0) {
            contentTemplate.ContentVariables = JSON.stringify(contentVariables);
        }
        return contentTemplate;
    };
    const getInlineMediaUrls = () => {
        if (contentTemplateType !== constants_1.ALL_CONTENT_TYPES.INLINE.friendly_name) {
            return {};
        }
        if (!inlineMediaUrls || inlineMediaUrls.length === 0) {
            return {};
        }
        const urls = inlineMediaUrls.filter((item) => item.trim() !== '').map((item) => item.trim());
        if (urls.length > 10) {
            throw new actions_core_1.PayloadValidationError('Media URL cannot contain more than 10 URLs');
        }
        urls.forEach((url) => {
            try {
                new URL(url);
            }
            catch {
                throw new actions_core_1.PayloadValidationError(`Media URL ${url} is not a valid URL.`);
            }
        });
        return urls.length > 0 ? { MediaUrl: urls } : {};
    };
    const getTags = () => {
        if (!tags || typeof tags !== 'object')
            return undefined;
        const allowedPattern = /^[a-zA-Z0-9 _-]+$/;
        for (const k in tags) {
            const v = tags[k];
            if (v === null || String(v).trim() === '') {
                delete tags[k];
                continue;
            }
            if (typeof v === 'object') {
                throw new actions_core_1.PayloadValidationError(`Tag value for key "${k}" cannot be an object or array.`);
            }
            if (k.length > 128) {
                throw new actions_core_1.PayloadValidationError(`Tag key "${k}" exceeds the maximum tag key length of 128 characters.`);
            }
            const trimmedValue = String(v).trim();
            if (!allowedPattern.test(k)) {
                throw new actions_core_1.PayloadValidationError(`Tag key "${k}" contains invalid characters. Only alphanumeric, space, hyphen (-), and underscore (_) are allowed.`);
            }
            if (!allowedPattern.test(trimmedValue)) {
                throw new actions_core_1.PayloadValidationError(`Tag value "${trimmedValue}" for key "${k}" contains invalid characters. Only alphanumeric, space, hyphen (-), and underscore (_) are allowed.`);
            }
            if (trimmedValue.length > 128) {
                throw new actions_core_1.PayloadValidationError(`Tag value for key "${k}" exceeds the maximum tag value length of 128 characters.`);
            }
            tags[k] = trimmedValue;
        }
        if (Object.keys(tags).length > 10) {
            throw new actions_core_1.PayloadValidationError('Tags cannot contain more than 10 key-value pairs.');
        }
        return Object.keys(tags).length > 0 ? { Tags: JSON.stringify(tags) } : undefined;
    };
    const twilioPayload = (() => ({
        To: getTo(),
        ...getValidityPeriod(),
        ...getSender(payload),
        ...getContent(),
        ...getInlineMediaUrls(),
        ...getTags()
    }))();
    const encodedBody = encode(twilioPayload);
    return await request(constants_1.SEND_SMS_URL.replace(constants_1.ACCOUNT_SID_TOKEN, settings.accountSID), {
        method: 'post',
        body: encodedBody
    });
}
function parseFieldValue(value) {
    if (!value) {
        return undefined;
    }
    const match = constants_1.FIELD_REGEX.exec(value);
    return match ? match[1] : value;
}
function encode(twilioPayload) {
    const encodedSmsBody = new URLSearchParams();
    Object.entries(twilioPayload).forEach(([key, value]) => {
        if (key === 'MediaUrl' && Array.isArray(value)) {
            value.forEach((url) => {
                encodedSmsBody.append('MediaUrl', url);
            });
        }
        else {
            encodedSmsBody.append(key, String(value));
        }
    });
    return encodedSmsBody.toString();
}
function validateContentSid(contentSid) {
    return /^HX[0-9a-fA-F]{32}$/.test(contentSid);
}
function getSender(payload) {
    const { sendAt, senderType, channel } = payload;
    let { fromPhoneNumber, messagingServiceSid, fromFacebookPageId } = payload;
    if (senderType === constants_1.SENDER_TYPE.PHONE_NUMBER) {
        fromPhoneNumber = fromPhoneNumber?.trim();
        if (!fromPhoneNumber) {
            throw new actions_core_1.PayloadValidationError("'From Phone Number' field is required when sending from a phone number.");
        }
        if (!constants_1.E164_REGEX.test(fromPhoneNumber)) {
            throw new actions_core_1.PayloadValidationError("'From' field should be a valid phone number in E.164 format");
        }
        return channel === constants_1.CHANNELS.WHATSAPP ? { From: `whatsapp:${fromPhoneNumber}` } : { From: fromPhoneNumber };
    }
    if (senderType === constants_1.SENDER_TYPE.FACEBOOK_PAGE_ID) {
        fromFacebookPageId = fromFacebookPageId?.trim();
        if (!fromFacebookPageId) {
            throw new actions_core_1.PayloadValidationError("'From Facebook Page ID' field is required when sending from a Facebook Page.");
        }
        return { From: `messenger:${fromFacebookPageId}` };
    }
    if (senderType === constants_1.SENDER_TYPE.MESSAGING_SERVICE) {
        messagingServiceSid = parseFieldValue(messagingServiceSid);
        if (!messagingServiceSid) {
            throw new actions_core_1.PayloadValidationError("'Messaging Service SID' field is required when 'Choose Sender' field = Messaging Service SID");
        }
        if (!constants_1.MESSAGING_SERVICE_SID_REGEX.test(messagingServiceSid ?? '')) {
            throw new actions_core_1.PayloadValidationError("'Messaging Service SID' field value should start with 'MG' followed by 32 hexadecimal characters, totaling 34 characters.");
        }
        return {
            MessagingServiceSid: messagingServiceSid,
            ...getSendAt(sendAt)
        };
    }
    throw new actions_core_1.PayloadValidationError('Unsupported Sender Type');
}
function getSendAt(sendAt) {
    if (sendAt) {
        const t = new Date(sendAt).getTime() - new Date().getTime();
        if (t >= constants_1.MIN_SCHEDULE_TIME_MS && t <= constants_1.MAX_SCHEDULE_TIME_MS) {
            return { SendAt: sendAt, ScheduleType: 'fixed' };
        }
        else {
            throw new actions_core_1.PayloadValidationError(`'Send At' time of ${sendAt} is invalid. It must be at least 15 minutes and at most 35 days in the future.`);
        }
    }
    return {};
}
//# sourceMappingURL=utils.js.map