const _ = require('lodash');
const template = require('./template');
const locales = require('../i18n');
const log = require('./log');

let cache = {};

const LocalePath = {
    HBS_HELPER_OPTIONS: [ 'data', 'root', 'Layout', 'locale' ],
    DEFAULT_USER: [ 'session', 'default_user', 'dbfields', 'userinfo.lang.uid' ]
};

// source: options из handlebars-хелпера | req.context
function getLocale(source) {
    let locale = source;
    if (typeof locale === 'object') {
        locale = (
            _.get(source, LocalePath.HBS_HELPER_OPTIONS) ||
            _.get(source, LocalePath.DEFAULT_USER)
        );
    }
    if (!locale) {
        log('@warning Failed to detect locale');
        locale = 'en';
    }
    return typeof locale === 'string' ? locale : undefined;
}

function getDictionary(locale) {
    locale = getLocale(locale);

    if (cache[locale])
        return cache[locale];

    var dictionary = {
        storage: Object.assign(
            load(locale),
            { country: load('countries.' + locale) },
            { language: load('languages.' + locale) },
            { date: load('date.' + locale) }
        )
    };
    // Object.assign(dictionary.storage, load(`${locale}.compatibility`));

    dictionary.pick = (key, data) => {
        var value = _.get(dictionary.storage, key);
        return typeof value === 'string' ? template.build(value, data) : value;
    };

    // переносим в словарь методы специфичного для локали форматирования
    if (locales[locale]) {
        Object.keys(locales[locale]).forEach(method => {
            if (typeof locales[locale][method] === 'function') {
                dictionary[method] = (...args) => locales[locale][method].apply(null, args);
            }
        });
    }

    return (cache[locale] = dictionary);
}

function load(name) {
    var data = {};

    try {
        data = require(`../../locales/${name}.json`);
    }
    catch(e) {
        log(`@error Failed to load 'locales/${name}.json'`);
    }

    return data;
}

module.exports = {
    getLocale, getDictionary
};
