/*!
 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
import IntlObj from 'intl';
import IntlMessageFormatObj from 'intl-messageformat';
import IntlRelativeFormatObj from 'intl-relativeformat';
import createFormatCacheObj from 'intl-format-cache';
import i18nJson from 'i18nJson';
/*
 Intl libs are using out dated transpailer from ecmascript6.
 *  TODO: As soon as they fix it, remove this assignments!!!
 * */
var Intl               = window.Intl || IntlObj.default,
	IntlMessageFormat  = IntlMessageFormatObj.default,
	IntlRelativeFormat = IntlRelativeFormatObj.default,
	createFormatCache  = createFormatCacheObj.default;

/*extract locale*/
var _locale = window.localStorage && localStorage.getItem('user_locale');
if(!_locale) {
	if(window.navigator) {
		_locale = navigator.language || navigator.userLanguage;

		//For now removing the dashes from the language.
		let indexOfDash = _locale.indexOf('-');
		if(-1 !== indexOfDash) {
			_locale = _locale.substr(0, indexOfDash);
		}
	}
	if(!_locale) {
		_locale = 'en';
	}
}

var _localeUpper = _locale.toUpperCase();
var i18n = {

	_locale: _locale,
	_localeUpper: _localeUpper,
	_i18nData: i18nJson || {},

	number(num) {
		return createFormatCache(Intl.NumberFormat)(this._locale).format(num);
	},

	date(date, options, relativeDates) {
		if (undefined === relativeDates || relativeDates) {
			return this.dateRelative(date, options);
		} else {
			return this.dateNormal(date, options);
		}
	},

	dateNormal(date, options) {
		return createFormatCache(Intl.DateTimeFormat)(this._locale, options).format(date);
	},

	dateRelative(date, options) {
		return createFormatCache(IntlRelativeFormat)(this._locale, options).format(date);
	},
	message(messageId, options) {
		let messageTxt = null;
		if (i18nJson && i18nJson[messageId]) {
			messageTxt = i18nJson[messageId];
		} else {
			messageTxt = String(messageId);
		}
		return createFormatCache(IntlMessageFormat)(messageTxt, this._locale).format(options);

	},
	getLocale() {
		return this._locale;
	},
	getLocaleUpper() {
		return this._localeUpper;
	},
	setLocale(locale) {
		localStorage.setItem('user_locale', locale);
		window.location.reload();
	}

};
function i18nWrapper() {
	return i18nWrapper.message.apply(i18nWrapper, arguments);
}

/*replace with some kind of extend method*/
var prop, propKey;
for (propKey in i18n) {
	prop = i18n[propKey];
	if (typeof prop === 'function') {
		prop = prop.bind(i18nWrapper);
	}
	i18nWrapper[propKey] = prop;
}

export default i18nWrapper;
