/**
 * Copyright schukai GmbH and contributors 2022. All Rights Reserved.
 * Node module: @schukai/monster
 * This file is licensed under the AGPLv3 License.
 * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
 */

import {internalSymbol} from "../../constants.mjs";
import {extend} from "../../data/extend.mjs";
import { getGlobalObject} from "../../types/global.mjs";
import {isString} from "../../types/is.mjs";
import {validateObject, validateString} from "../../types/validate.mjs";
import {parseLocale} from "../locale.mjs";
import {Provider} from "../provider.mjs";
import {Translations} from "../translations.mjs";

export {Embed}

/**
 * The Embed provider retrieves a JSON file from the given Script Tag.
 *
 * @externalExample ../../../example/i18n/providers/embed.mjs
 * @license AGPLv3
 * @since 1.13.0
 * @copyright schukai GmbH
 * @memberOf Monster.I18n.Providers
 * @see {@link https://datatracker.ietf.org/doc/html/rfc3066}
 * @tutorial i18n-locale-and-formatter
 */
class Embed extends Provider {

    /**
     * ```html
     * <script id="translations" type="application/json">
     * {
     *     "hello": "Hallo"
     * }
     * </script>
     * ```
     * 
     * 
     * ```javascript
     * new Embed('translations')
     * ```
     *
     * @param {string} id
     * @param {Object} options
     */
    constructor(id, options) {
        super(options);

        if (options === undefined) {
            options = {};
        }

        validateString(id);

        /**
         * @property {string}
         */
        this.textId = id;

        /**
         * @private
         * @property {Object} options
         */
        this[internalSymbol] = extend({}, super.defaults, this.defaults, validateObject(options));

    }

    /**
     * Defaults
     *
     * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API}
     */
    get defaults() {
        return extend({}, super.defaults);
    }

    /**
     *
     * @param {Locale|string} locale
     * @return {Promise}
     */
    getTranslations(locale) {

        if (isString(locale)) {
            locale = parseLocale(locale);
        }

        return new Promise((resolve, reject) => {

            let text = getGlobalObject('document').getElementById(this.textId);

            if (text === null) {
                reject(new Error('Text not found'));
                return;
            }

            let translations = null;
            try {
                translations = JSON.parse(text.innerHTML);
            } catch (e) {
                reject(e);
                return;
            }


            if (translations === null) {
                reject(new Error('Translations not found or invalid'));
                return;
            }
            
            const t = new Translations(locale);
            t.assignTranslations(translations)

            resolve(t);

        });

    }


}