/*!
 * 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;

/*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;
