(function () {
    var TOKEN_KEYS = ['token', 'access_token', 'accessToken'];
    var APP_CODE_KEYS = ['app', 'app_code', 'appCode'];
    var USER_READY_EVENT = 'hyapp:user-ready';
    var USER_ERROR_EVENT = 'hyapp:user-error';

    function query() {
        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 first(params, keys) {
        for (var i = 0; i < keys.length; i += 1) {
            var value = params.get(keys[i]);
            if (value) return value;
        }
        return '';
    }

    function normalizeToken(value) {
        var token = String(value || '').trim();
        if (!token) return '';
        if (/^Bearer\s+/i.test(token)) token = token.replace(/^Bearer\s+/i, '');
        var match = token.match(
            /[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/
        );
        token = match ? match[0] : token;
        return isExpiredToken(token) ? '' : token;
    }

    function decodeBase64URLJSON(value) {
        try {
            var normalized = String(value || '').replace(/-/g, '+').replace(/_/g, '/');
            while (normalized.length % 4) normalized += '=';
            return JSON.parse(window.atob(normalized));
        } catch (_) {
            return null;
        }
    }

    function isExpiredToken(token) {
        var parts = String(token || '').split('.');
        if (parts.length < 2) return false;
        var payload = decodeBase64URLJSON(parts[1]);
        if (!payload || !payload.exp) return false;
        // params 是页面入口模式的判定来源；过期 JWT 必须当作无 token，否则充值页会隐藏用户 ID 输入并触发 INVALID_ARGUMENT。
        return Number(payload.exp) * 1000 <= Date.now() + 5000;
    }

    function parse() {
        var params = query();
        var token = normalizeToken(first(params, TOKEN_KEYS));
        var appCode =
            first(params, APP_CODE_KEYS) ||
            window.localStorage.getItem('hyapp_app_code') ||
            'lalu';

        if (window.HyAppAPI) {
            if (token) window.HyAppAPI.setAccessToken(token);
            if (appCode) window.HyAppAPI.setAppCode(appCode);
        }

        return {
            token:
                token ||
                (window.HyAppAPI && window.HyAppAPI.getAccessToken
                    ? window.HyAppAPI.getAccessToken()
                    : ''),
            app_code: appCode,
            raw: params,
        };
    }

    function emit(name, detail) {
        window.dispatchEvent(new CustomEvent(name, { detail: detail }));
    }

    function loadUser() {
        var current = parse();
        if (!current.token || !window.HyAppAPI) {
            return Promise.resolve(null);
        }
        return window.HyAppAPI.get('/api/v1/users/me/overview')
            .then(function (userInfo) {
                current.user = userInfo;
                window.HyAppParams.current = current;
                emit(USER_READY_EVENT, current);
                return current;
            })
            .catch(function (error) {
                current.error = error;
                window.HyAppParams.current = current;
                emit(USER_ERROR_EVENT, current);
                throw error;
            });
    }

    window.HyAppParams = {
        parse: parse,
        loadUser: loadUser,
        current: parse(),
        USER_READY_EVENT: USER_READY_EVENT,
        USER_ERROR_EVENT: USER_ERROR_EVENT,
    };
})();
