// Google Translate wrappers used when a bot is configured to fan a message
// out into multiple languages. Splitting out into its own module keeps the
// google-translate API key (env-only) and the per-language plural-request
// dance in one place — index.js doesn't need to know about either.
//
// createTranslator({ languages, apiKey, fetchWithRateLimit, logger })
// returns { buildTranslations(message) }. Callers hand in the same
// fetchWithRateLimit that lib/webex.js uses so the whole app has a single
// 429 retry policy.

export function createTranslator(deps) {
    var languages = Array.isArray(deps.languages) ? deps.languages : [];
    var apiKey = deps.apiKey || '';
    var fetchWithRateLimit = deps.fetchWithRateLimit;
    var logger = deps.logger || function () {};

    // POST to Google's translate v2 REST endpoint for one (message, target
    // language, format) triple. Resolves to a normalized record so the
    // fan-out caller can index by language name.
    function translateMessage(message, language, format, messageType) {
        return new Promise(function (resolve, reject) {
            var params = {
                q: message,
                target: language.key,
                format: format,
                source: 'en',
                model: 'nmt',
                key: apiKey
            };
            var translateUrl = 'https://translation.googleapis.com/language/translate/v2?' + new URLSearchParams(params);
            fetchWithRateLimit(translateUrl, { method: 'POST' })
                .then(response => response.json())
                .then(result => {
                    resolve({
                        name: language.name,
                        key: language.key,
                        format: format,
                        messageType: messageType,
                        translatedText: result.data.translations[0].translatedText
                    });
                })
                .catch(reject);
        });
    }

    // Fans `message` out across every configured language in text +
    // markdown + html variants. Returns an object shaped like:
    //   { english: {text, markdown, html}, "<languageName>": {...}, ... }
    // Failed translations are silently dropped (partial success is better
    // than the whole send blowing up when one language server is down).
    function buildTranslations(message) {
        return new Promise(function (resolve) {
            logger('buildTranslations', 'Started');
            var translationPromises = [];
            var translations = {
                english: {
                    text: message.text,
                    markdown: message.markdown,
                    html: message.html
                }
            };

            for (var language of languages) {
                translationPromises.push(translateMessage(message.text, language, 'text', 'text'));
                translationPromises.push(translateMessage(message.markdown, language, 'text', 'markdown'));
                translationPromises.push(translateMessage(message.html, language, 'html', 'html'));
            }

            Promise.allSettled(translationPromises).then(function (results) {
                for (var translation of results) {
                    if (translation.status === 'fulfilled') {
                        var name = translation.value.name;
                        if (!translations[name]) translations[name] = {};
                        translations[name][translation.value.messageType] = translation.value.translatedText;
                    }
                }
                logger('buildTranslations', 'Completed');
                resolve(translations);
            });
        });
    }

    return { buildTranslations, translateMessage };
}
