(function () {
    'use strict';

    var CONTEXT_QUERY_KEYS = [
        'token',
        'access_token',
        'accessToken',
        'env',
        'language',
        'lang',
        'locale',
        'app_lang',
        'appLanguage',
        'mock',
    ];
    var product = null;

    function normalizeSlug(value, field) {
        var slug = String(value || '')
            .trim()
            .toLowerCase();
        if (!/^[a-z][a-z0-9_-]*$/.test(slug)) {
            throw new Error('Invalid guild product ' + field + ': ' + slug);
        }
        return slug;
    }

    function freezeArray(value) {
        return Object.freeze(Array.isArray(value) ? value.slice() : []);
    }

    function defineProduct(config) {
        var next = config || {};
        var normalized = Object.freeze({
            key: normalizeSlug(next.key, 'key'),
            appCode: normalizeSlug(next.appCode, 'appCode'),
            languages: freezeArray(next.languages),
            features: Object.freeze(
                Object.assign(
                    {
                        hostCenter: true,
                        agencyCenter: true,
                        bdCenter: true,
                        wallet: true,
                    },
                    next.features || {}
                )
            ),
        });

        // 同一页面只能属于一个产品；静默覆盖会让后加载的品牌包改变请求租户，属于高风险串数据。
        if (product && product.key !== normalized.key) {
            throw new Error('Guild product already defined as ' + product.key);
        }
        product = normalized;
        window.HyAppDefaultAppCode = normalized.appCode;
        window.HyAppI18nSupported = normalized.languages;
        document.documentElement.setAttribute(
            'data-hy-product',
            normalized.key
        );
        return product;
    }

    function getProduct() {
        if (!product) throw new Error('Guild product is not defined');
        return product;
    }

    function currentParams() {
        var params = new URLSearchParams(window.location.search || '');
        var hash = window.location.hash || '';
        if (hash.indexOf('?') >= 0) {
            new URLSearchParams(hash.split('?').slice(1).join('?')).forEach(
                function (value, key) {
                    if (!params.has(key)) params.set(key, value);
                }
            );
        }
        return params;
    }

    function buildURL(path, extra) {
        var target = new URL(path, window.location.href);
        var source = currentParams();

        // 页面跳转只继承认证、环境和语言上下文，不复制筛选、分页等页面状态，避免不同中心解释同名参数。
        CONTEXT_QUERY_KEYS.forEach(function (key) {
            if (source.has(key) && !target.searchParams.has(key)) {
                target.searchParams.set(key, source.get(key));
            }
        });
        target.searchParams.set('app_code', getProduct().appCode);
        Object.keys(extra || {}).forEach(function (key) {
            var value = extra[key];
            if (value === undefined || value === null || value === '') {
                target.searchParams.delete(key);
                return;
            }
            target.searchParams.set(key, String(value));
        });
        return target.toString();
    }

    window.HyGuild = window.HyGuild || {};
    window.HyGuild.product = {
        define: defineProduct,
        get: getProduct,
        buildURL: buildURL,
    };
})();
