"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
Object.defineProperty(exports, "TranslatedString", {
    enumerable: true,
    get: function() {
        return TranslatedString;
    }
});
const _constants = require("@tamanu/constants");
const _sequelize = require("sequelize");
const _Model = require("./Model");
const _lodash = require("lodash");
const _translationFactory = require("@tamanu/shared/utils/translation/translationFactory");
const _enumRegistry = require("@tamanu/shared/utils/enumRegistry");
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
let TranslatedString = class TranslatedString extends _Model.Model {
    static initModel(options) {
        super.init({
            id: {
                // translated_string records use a generated primary key that enforces one per string and language,
                type: `TEXT GENERATED ALWAYS AS ("string_id" || ';' || "language") STORED`,
                set () {
                // any sets of the convenience generated "id" field can be ignored
                }
            },
            stringId: {
                type: _sequelize.DataTypes.TEXT,
                allowNull: false,
                primaryKey: true,
                validate: {
                    doesNotContainIdDelimiter: (value)=>{
                        if (value.includes(';')) {
                            throw new Error('Translation ID cannot contain ";"');
                        }
                    }
                }
            },
            language: {
                type: _sequelize.DataTypes.TEXT,
                allowNull: false,
                primaryKey: true,
                validate: {
                    doesNotContainIdDelimiter: (value)=>{
                        if (value.includes(';')) {
                            throw new Error('Language cannot contain ";"');
                        }
                    }
                }
            },
            text: {
                type: _sequelize.DataTypes.TEXT,
                allowNull: false
            }
        }, {
            ...options,
            syncDirection: _constants.SYNC_DIRECTIONS.BIDIRECTIONAL,
            indexes: [
                {
                    name: 'string_language_unique',
                    fields: [
                        'string_id',
                        'language'
                    ],
                    unique: true
                },
                {
                    name: 'string_id_index',
                    fields: [
                        'string_id'
                    ]
                },
                {
                    name: 'language_index',
                    fields: [
                        'language'
                    ]
                },
                {
                    name: 'updated_at_sync_tick_index',
                    fields: [
                        'language',
                        'updated_at_sync_tick'
                    ]
                }
            ]
        });
    }
    static buildSyncFilter() {
        return null; // syncs everywhere
    }
    static async buildSyncLookupQueryDetails() {
        return null; // syncs everywhere
    }
};
_define_property(TranslatedString, "getPossibleLanguages", async ()=>{
    const languagesInDb = await TranslatedString.findAll({
        attributes: [
            'language'
        ],
        group: 'language'
    });
    const languageNames = await TranslatedString.findAll({
        where: {
            stringId: _constants.LANGUAGE_NAME_STRING_ID
        }
    });
    const countryCodes = await TranslatedString.findAll({
        where: {
            stringId: _constants.COUNTRY_CODE_STRING_ID
        }
    });
    return {
        languagesInDb,
        languageNames,
        countryCodes
    };
});
_define_property(TranslatedString, "getTranslations", async (language, prefixIds)=>{
    const translatedStringRecords = await TranslatedString.findAll({
        where: {
            language,
            // filter Boolean to avoid query all records
            [_sequelize.Op.or]: prefixIds.filter(Boolean).map((prefixId)=>({
                    id: {
                        [_sequelize.Op.startsWith]: prefixId
                    }
                }))
        },
        attributes: [
            'stringId',
            'text'
        ]
    });
    const translations = (0, _lodash.mapValues)((0, _lodash.keyBy)(translatedStringRecords, 'stringId'), 'text');
    return translations;
});
_define_property(TranslatedString, "getTranslationFunction", async (language, prefixIds = [])=>{
    const translations = await TranslatedString.getTranslations(language, prefixIds);
    return (stringId, fallback, translationOptions = {})=>{
        const translationFunc = (0, _translationFactory.translationFactory)(translations);
        const { value } = translationFunc(stringId, fallback, translationOptions);
        return value;
    };
});
_define_property(TranslatedString, "getEnumTranslationFunction", async (language, prefixIds = [])=>{
    const translationFunc = await TranslatedString.getTranslationFunction(language, prefixIds);
    return (enumValues, currentValue)=>{
        const fallback = enumValues[currentValue];
        const stringId = `${(0, _enumRegistry.getEnumPrefix)(enumValues)}.${currentValue}`;
        const value = translationFunc(stringId, fallback || '');
        return value;
    };
});

//# sourceMappingURL=TranslatedString.js.map