const yaml = require('js-yaml');

const locales = {};
let fallbackLang = 'en';
let lang = null;

/**
 * Class to manage the internationalization.
 */
module.exports =
{
	init() {
		if (lang) return;
		this.loads = {};
		this.locales = locales;
		this.fallbackLang = fallbackLang;

		const languages = navigator.languages;

		if (languages && languages.length > 0)
			lang = languages[0];
		else if (navigator.language)
			lang = navigator.language;

		lang = lang ? lang.substr(0, 2) : fallbackLang;
		this.language = lang;
	},

	async load(path) {
		this.init();
		await Promise.all([
			this.loadLang(path, fallbackLang),
			this.loadLang(path, lang)
		]);
	},

	/**
	 * @returns {Promise}
	 */
	async loadLang(path, lang) {
		let langLoad = this.loads[lang];
		if (!langLoad)
			langLoad = this.loads[lang] = {};

		if (langLoad[path])
			return Promise.resolve();
		langLoad[path] = true;

		const langFile = `${path}/locale/${lang}.yml${Vn.getVersion()}`;
		const request = new XMLHttpRequest();
		request.open('get', langFile, true);

		const promise = new Promise((resolve, reject) => {
			request.onreadystatechange =
				() => this.onRequestReady(request, resolve, reject);
		});

		request.send();

		try {
			const translations = await promise;
			this.add(translations, lang);
		} catch(err) {
			langLoad[path] = false;
			//console.warn(err);
		}
	},

	onRequestReady(request, resolve, reject) {
		if (request.readyState != 4)
			return;
		if (request.status < 200 || request.status >= 400)
			return reject(new Error(`HTTP ${request.status}: ${request.statusText}`));

		resolve(yaml.safeLoad(request.responseText));
	},
	
	add(translations, myLang) {
		if (!translations) return;
		myLang = myLang || lang;
		let langLocales = locales[myLang];
		if (!langLocales)
			langLocales = locales[myLang] = {};
		for (const str in translations)
			langLocales[str] = translations[str];
	}
}

function getString(stringId, lang) {
	return locales[lang] ? locales[lang][stringId] : null;
}

window._ = function(stringId) {
	let string = getString(stringId, lang);
	if (!string)
		string = getString(stringId, fallbackLang);
	return string || stringId;
}