/**
 * 国际化模块,属于业务层
 */

import { Singleton, Container, Scope, Inject } from "typescript-ioc";
import { IService, logger } from "mslib"
import { TyGlobalApiClient, Token, Language } from "./TyGlobalApi";
import { Contants, redisClient, retry } from "refs/nslib";
const { I18n } = require('i18n');

/**
 * 国际化服务类
 */
@Singleton
export class GlobalService {
    @Inject
    tyGlobalApiClient: TyGlobalApiClient;

    /**
     * 获取语言包
     */
    async getLanguagePacks(args: { token: Token, language?: Language }): Promise<Map<string, { key: string, value: string }[]>> {
        logger.info(`getLanguagePacks`,args);
        console.log(`getLanguagePacks`,args);
        let languagePack = new Map<string, { key: string, value: string }[]>();

        let apiResponse = await this.tyGlobalApiClient.get({
            token: args.token,
            type: 1
        });

        for (const item of apiResponse.data?.data) {
            let pack = languagePack.get(item.language);

            if (!pack) {
                pack = [];
                languagePack.set(item.language, pack);
            }

            if (item.value.includes('${{')) {
                logger.info(item.value);
            }

            pack.push({ key: item.key, value: item.value });
        }

        return languagePack;
    }

    /**
     * 同步后端语言包到redis
     */
    async syncBackend() {
        let languagePacks = await this.getLanguagePacks({ token: !Contants.IS_PROD ? Token.keytop_nkc_pro_sg : Token.nonstandard_back_end });

        for (const languagePack of languagePacks.entries()) {
            await redisClient.hset('translation_1102011', languagePack[0], JSON.stringify(languagePack[1]));
            logger.info(`同步非标/后端语言包到redis成功,lang:${languagePack[0]}`);
            console.log(`同步非标/后端语言包到redis成功,lang:${languagePack[0]}`);

            //反序列化校验
            if (Contants.IS_LOCAL_DEBUG) {
                try {
                    let value = await redisClient.hget('translation_1102011', languagePack[0]);
                    let obj = JSON.parse(value);
                    let i = 1;
                    logger.info(`校验redis语言包成功,lang:${languagePack[0]}`);
                } catch (error) {
                    logger.error(error);
                }
            }
        }
    }
}

let config = Container.getValue('config.basic');

/**
 * 基于插件i18n开发,语种需要简写,例如：en(en-US)、zh(zh-TW)
 * 
 * 需启用国际化开关config.basic.global=true
 * 
 * i18n.__('Hello %s', 'Keytop')
 * 
 * i18n.__('Hello {0}', ['Keytop'])
 * 
 * i18n.__('Hello {name}', { name: 'Keytop' })
 * 
 * i18n.setLocale('cn') //设置语种,语种需简写
 * 
 * https://www.npmjs.com/package/i18n
 */
export let i18n = null;
if (config?.global?.toString().toUpperCase() === 'TRUE') {
    i18n = new I18n();

    setTimeout(async () => {
        try {
            await retry(async () => {
                let obj = await redisClient.hgetall('translation_1102011');
                let staticCatalog = {};
                let locales = [];

                for (const key in obj) {
                    try {
                        const [locale] = key.split('_');
                        let pack = {};

                        JSON.parse(obj[key]).forEach(s => {
                            pack[s.key] = s.value;
                        });

                        locales.push(locale);
                        staticCatalog[locale] = pack;
                    } catch (error) {
                        logger.error(`从redis加载语言包失败,lang:${key}`, error);
                    }
                }

                logger.info(`从redis加载语言包成功,lang:${locales.join(',')}`);

                i18n.configure({
                    locales: locales,
                    staticCatalog: staticCatalog,
                    mustacheConfig: {
                        tags: ['{', '}'],
                        disable: false
                    },
                    logDebugFn: function (msg) {
                        logger.debug(msg);
                    },
                    logWarnFn: function (msg) {
                        // logger.warn(msg);
                    },
                    logErrorFn: function (msg) {
                        logger.error(msg);
                    },
                    missingKeyFn: function (locale, value) {
                        return value;
                    },
                });
            }, 5, 500);
        } catch (error) {
            logger.error(`从redis加载语言包失败`, error);
        }
    });
}

function translateObj(data: object, locale: string) {
    for (const key in data) {
        if (typeof data[key] === 'object') {
            translateObj(data[key], locale);
        } else {
            if (typeof data[key] === 'string' && data[key].startsWith('${{') && data[key].endsWith('}}')) {
                data[key] = i18n.__({ phrase: data[key].substring(3, data[key].length - 2), locale: locale });
            }
        }
    }
}

/**
 * 翻译非标数据,翻译格式为${{xxx}}的字符串
 * 
 * 使用的语言包是非标/后端
 */
export function translateNsData(data: any, locale: string) {
    if (typeof data === 'object') {
        translateObj(data, locale);
        return data;
    } else {
        if (typeof data === 'string' && data.startsWith('${{') && data.endsWith('}}')) {
            return i18n.__({ phrase: data.substring(3, data.length - 2), locale: locale });
        } else {
            return data;
        }
    }
}
