const TRANSLATE_FUNCTION_ARGS = /\(\s*'(?<key>[^']+)'(?:,\s*(?<interpolate>\{(?:(?!\}\))[\s\S])*\}))?\)/gs.source;
export const escapeHtmlTranslationValue = (translation) => translation.replace(/'/g, '&apos;').replace(/"/g, '&quot;').replace(/@/g, '&#64;');
export const escapeTsTranslationValue = (translation) => translation.replace(/'/g, "\\'").replace(/\\/g, '\\\\');
function getTranslationValue(getWebappTranslation, key, data) {
    return getWebappTranslation(key, data) || undefined;
}
export const replaceTranslationKeysWithText = (getWebappTranslation, body, regexp, { keyPattern, interpolatePattern, wrapTranslation, escapeHtml, stringify } = {}) => {
    const matches = [...body.matchAll(new RegExp(regexp, 'g'))].reverse();
    if (typeof wrapTranslation === 'string') {
        wrapTranslation = [wrapTranslation, wrapTranslation];
    }
    for (const match of matches) {
        const target = match[0];
        let key = match.groups?.key;
        if (!key && keyPattern) {
            const keyMatch = target.match(new RegExp(keyPattern));
            key = keyMatch?.groups?.key;
        }
        if (!key) {
            throw new Error(`Translation key not found for ${target}`);
        }
        let interpolate = match.groups?.interpolate;
        if (!interpolate && interpolatePattern) {
            const interpolateMatch = target.match(new RegExp(interpolatePattern));
            interpolate = interpolateMatch?.groups?.interpolate;
        }
        let data;
        if (interpolate) {
            data = {};
            try {
                data = JSON.parse(interpolate);
            }
            catch {
                throw new Error(`Translation interpolations values should be a JSON, ${interpolate}`);
            }
        }
        const translation = getTranslationValue(getWebappTranslation, key, data);
        let replacement = translation;
        if (!replacement) {
            replacement = wrapTranslation ? `${wrapTranslation[0]}${wrapTranslation[1]}` : '';
        }
        else if (wrapTranslation) {
            replacement = `${wrapTranslation[0]}${translation}${wrapTranslation[1]}`;
        }
        else if (escapeHtml) {
            replacement = escapeHtmlTranslationValue(replacement);
        }
        else if (stringify) {
            replacement = JSON.stringify(replacement);
        }
        body = `${body.slice(0, match.index)}${replacement}${body.slice(match.index + target.length)}`;
    }
    return body;
};
export const createJhiTransformTranslateReplacer = (getWebappTranslation, translateOptions) => (body) => replaceTranslationKeysWithText(getWebappTranslation, body, `__jhiTransformTranslate__${TRANSLATE_FUNCTION_ARGS}`, translateOptions);
export const createJhiTransformTranslateStringifyReplacer = getWebappTranslation => (body) => replaceTranslationKeysWithText(getWebappTranslation, body, `__jhiTransformTranslateStringify__${TRANSLATE_FUNCTION_ARGS}`, {
    stringify: true,
});
export const replaceTranslateContents = (body, filePath, regexp, converter) => {
    const matches = [...body.matchAll(new RegExp(regexp, 'g'))].reverse();
    for (const match of matches) {
        const target = match[0];
        const { key, interpolate, type, prefix = '', suffix = '' } = match.groups ?? {};
        if (!type) {
            throw new Error(`Translation type not found for ${target}`);
        }
        if (!key) {
            throw new Error(`Translation key not found for ${target}`);
        }
        let parsedInterpolate;
        if (interpolate) {
            parsedInterpolate = {};
            try {
                parsedInterpolate = JSON.parse(interpolate);
            }
            catch {
                throw new Error(`Translation interpolations values should be a JSON, ${interpolate}`);
            }
        }
        body = `${body.slice(0, match.index)}${converter({ filePath, key, interpolate, parsedInterpolate, type, prefix, suffix })}${body.slice(match.index + target.length)}`;
    }
    return body;
};
export const createJhiTranslateReplacer = (converter, { prefixPattern = '', suffixPattern = '' } = {}) => (body, filePath) => replaceTranslateContents(body, filePath, `${prefixPattern ? `(?<prefix>(${prefixPattern}))?` : ''}__jhiTranslate(?<type>(\\w+))__${TRANSLATE_FUNCTION_ARGS}${suffixPattern ? `(?<suffix>(${suffixPattern}))?` : ''}`, converter);
