(function () {
    var ACTION_LABELS = {
        'block-user': 'Block User',
        'send-frame': 'Send Frame',
        'send-car': 'Send Car',
        'send-badge': 'Send Badge',
        'send-vip': 'Send VIP',
        'update-user-level': 'Update User Level',
        'add-bd-leader': 'Add BD Leader',
        'add-admin': 'Add Admin',
        'add-superadmin': 'Add Superadmin',
        'transfer-user-country': 'Transfer User Country',
    };
    var DAY_MS = 24 * 60 * 60 * 1000;
    var PERMANENT_BLOCK_MS = 10 * 365 * DAY_MS;
    var RESOURCE_TYPES = {
        'send-frame': 'avatar_frame',
        'send-car': 'vehicle',
        'send-badge': 'badge',
    };
    var ACTION_PERMISSION_KEYS = {
        'send-frame': 'canGrantAvatarFrame',
        'send-car': 'canGrantVehicle',
        'send-badge': 'canGrantBadge',
        'send-vip': 'canGrantVip',
        'update-user-level': 'canUpdateUserLevel',
        'add-bd-leader': 'canAddBdLeader',
        'add-admin': 'canAddAdmin',
        'add-superadmin': 'canAddSuperadmin',
        'block-user': 'canBlockUser',
        'transfer-user-country': 'canTransferUserCountry',
    };
    var RESOURCE_GRANT_DURATIONS = [
        { label: '7 days', ms: 7 * DAY_MS },
        { label: '30 days', ms: 30 * DAY_MS },
        { label: '90 days', ms: 90 * DAY_MS },
    ];
    var DEFAULT_RESOURCE_GRANT_DURATION_MS = RESOURCE_GRANT_DURATIONS[0].ms;
    var VIP_GRANT_LEVELS = [1, 2, 3, 4, 5];
    var TRACK_LABELS = {
        wealth: 'Wealth',
        charm: 'Charm',
        game: 'Game',
    };

    var api = window.HyAppAPI && window.HyAppAPI.managerCenter;
    var pageState = {
        loading: true,
        denied: false,
        overview: null,
        permissions: {},
        resourcesByType: {},
        resourceRequestsByType: {},
        countries: [],
    };
    var blockState = {
        searchedUser: null,
        selectedDurationMs: 0,
        selectedDurationLabel: '',
        blockedUsers: [],
        submitting: false,
    };
    var levelState = {
        searchedUser: null,
        selectedTrack: 'wealth',
        selectedLevel: 0,
        submitting: false,
    };
    var grantState = {
        action: '',
        resourceType: '',
        title: '',
        searchedUser: null,
        selectedResourceIds: [],
        selectedResourceDurationMs: DEFAULT_RESOURCE_GRANT_DURATION_MS,
        selectedVipLevel: 0,
        submitting: false,
    };
    var bdLeaderState = {
        action: '',
        title: '',
        searchedUser: null,
        submitting: false,
    };
    var countryState = {
        searchedUser: null,
        selectedCountryCode: '',
        submitting: false,
    };

    function $(id) {
        return document.getElementById(id);
    }

    function root() {
        return document.querySelector('.manager-center');
    }

    function t(key, fallback) {
        return window.HyAppI18n && window.HyAppI18n.t
            ? window.HyAppI18n.t(key, fallback)
            : fallback || key;
    }

    function toast(message) {
        if (window.HyAppToast && window.HyAppToast.show) {
            window.HyAppToast.show(message);
            return;
        }
        window.alert(message);
    }

    function showError(error) {
        var message =
            error && error.status === 403
                ? 'Permission denied.'
                : (error && error.message) || 'Request failed.';
        toast(message);
    }

    function commandId(prefix) {
        return [
            prefix || 'manager',
            Date.now(),
            Math.random().toString(16).slice(2, 10),
        ].join('-');
    }

    function userName(user) {
        return (
            user.username ||
            user.name ||
            user.target_username ||
            user.display_user_id ||
            user.target_display_user_id ||
            'User'
        );
    }

    function userDisplayId(user) {
        return user.display_user_id || user.target_display_user_id || '';
    }

    function userId(user) {
        return user.user_id || user.target_user_id || '';
    }

    function avatarUrl(user) {
        return user.avatar || user.target_avatar || '';
    }

    function resourceImageUrl(resource) {
        return (
            resource.preview_url ||
            resource.previewUrl ||
            resource.asset_url ||
            resource.assetUrl ||
            resource.icon_url ||
            resource.iconUrl ||
            ''
        );
    }

    function resourceKindLabel() {
        if (grantState.action === 'send-frame') return 'Frame';
        if (grantState.action === 'send-car') return 'Car';
        if (grantState.action === 'send-badge') return 'Badge';
        return 'Resource';
    }

    function currentVip(user) {
        return user.current_vip || user.currentVip || user.vip || null;
    }

    function currentVipLevel(user) {
        var vip = currentVip(user);
        if (!vip || !vip.active) return 0;
        return Number(vip.level) || 0;
    }

    function currentVipStatusText(user) {
        var vip = currentVip(user);
        if (!vip || !vip.active || !vip.level) return 'Current VIP: None';
        var label = vip.name || 'VIP ' + vip.level;
        var expiresAt = Number(vip.expires_at_ms || vip.expiresAtMs || 0);
        if (expiresAt > 0) {
            return label + ' active · Expires ' + formatDateTime(expiresAt);
        }
        return label + ' active';
    }

    function initial(text) {
        return String(text || 'M')
            .trim()
            .charAt(0)
            .toUpperCase();
    }

    function createNode(tag, className, text) {
        var node = document.createElement(tag);
        if (className) node.className = className;
        if (text !== undefined) node.textContent = text;
        return node;
    }

    function setAvatar(node, user) {
        var url = avatarUrl(user);
        node.innerHTML = '';
        if (url) {
            var img = document.createElement('img');
            img.src = url;
            img.alt = '';
            node.appendChild(img);
            return;
        }
        node.textContent = initial(userName(user) || userDisplayId(user));
    }

    function textValue(value, fallback) {
        if (value === undefined || value === null || value === '') {
            return fallback;
        }
        return String(value);
    }

    function isLocalPreviewError(error) {
        var host = window.location && window.location.hostname;
        var isLocalHost =
            host === 'localhost' ||
            host === '127.0.0.1' ||
            host === '::1' ||
            host === '';
        var message = (error && error.message) || '';
        return isLocalHost && /failed to fetch|network/i.test(message);
    }

    function firstValue(source, keys) {
        source = source || {};
        for (var i = 0; i < keys.length; i += 1) {
            var key = keys[i];
            if (
                Object.prototype.hasOwnProperty.call(source, key) &&
                source[key] !== undefined &&
                source[key] !== null &&
                source[key] !== ''
            ) {
                return source[key];
            }
        }
        return undefined;
    }

    function firstNestedValue(sources, keys) {
        for (var i = 0; i < sources.length; i += 1) {
            var value = firstValue(sources[i], keys);
            if (value !== undefined) return value;
        }
        return undefined;
    }

    function formatMoney(value, fallback) {
        if (value === undefined || value === null || value === '') {
            return fallback;
        }
        if (typeof value === 'string' && value.indexOf('$') >= 0) {
            return value;
        }
        var number = Number(String(value).replace(/,/g, ''));
        if (!Number.isFinite(number)) return String(value);
        return (
            '$' +
            number.toLocaleString('en-US', {
                maximumFractionDigits: number % 1 === 0 ? 0 : 2,
                minimumFractionDigits: number % 1 === 0 ? 0 : 2,
            })
        );
    }

    function formatPercent(value, fallback) {
        if (value === undefined || value === null || value === '') {
            return fallback;
        }
        if (typeof value === 'string' && value.indexOf('%') >= 0) {
            // 服务端已带符号下发；只对正数补 +，零和负数原样透传，避免出现 "+0%"。
            var parsed = parseFloat(value);
            if (!Number.isFinite(parsed) || parsed <= 0) {
                return value;
            }
            return '+' + value.replace(/^\+/, '');
        }
        var number = Number(value);
        if (!Number.isFinite(number)) return String(value);
        if (Math.abs(number) > 0 && Math.abs(number) <= 1) {
            number *= 100;
        }
        return (number > 0 ? '+' : '') + Math.round(number) + '%';
    }

    function setText(id, value) {
        var node = $(id);
        if (node) node.textContent = value;
    }

    function updateManagerAvatar(profile) {
        var image = $('managerAvatar');
        var fallback = $('managerAvatarFallback');
        if (!image || !fallback) return;
        // 没有头像时展示首字母占位，不再使用演示头像假数据。
        var url = avatarUrl(profile);
        if (url) {
            image.src = url;
            image.hidden = false;
            fallback.hidden = true;
            return;
        }
        image.hidden = true;
        fallback.hidden = false;
        fallback.textContent = initial(
            userName(profile) || userDisplayId(profile)
        );
    }

    function dashboardSources() {
        var overview = pageState.overview || {};
        return [
            overview.dashboard,
            overview.summary,
            overview.metrics,
            overview.statistics,
            overview.wallet,
            overview,
        ];
    }

    function renderDashboard() {
        var overview = pageState.overview || {};
        var profile =
            overview.user ||
            overview.profile ||
            overview.manager ||
            overview.current_user ||
            overview.currentUser ||
            overview;
        updateManagerAvatar(profile || {});
        setText(
            'managerName',
            textValue(
                firstValue(profile || {}, [
                    'username',
                    'name',
                    'nickname',
                    'target_username',
                ]),
                '--'
            )
        );
        setText(
            'managerDisplayId',
            textValue(
                userDisplayId(profile || {}) || userId(profile || {}),
                '--'
            )
        );

        var sources = dashboardSources();
        // 页面不再内置任何设计假数据：加载中由骨架屏占位，渲染时字段缺失（聚合降级/请求失败/无 API）
        // 一律显示中性占位符，避免把演示数值误当真实团队工资。
        var fallback = {
            thisMonth: '--',
            lastMonth: '--',
            hosts: '--',
            growth: '--',
            wallet: '--',
            bankCards: '--',
        };
        setText(
            'managerThisMonthSalary',
            formatMoney(
                firstNestedValue(sources, [
                    'this_month_salary',
                    'thisMonthSalary',
                    'current_month_salary',
                    'currentMonthSalary',
                    'team_salary_this_month',
                    'teamSalaryThisMonth',
                ]),
                fallback.thisMonth
            )
        );
        setText(
            'managerLastMonthSalary',
            formatMoney(
                firstNestedValue(sources, [
                    'last_month_salary',
                    'lastMonthSalary',
                    'previous_month_salary',
                    'previousMonthSalary',
                    'team_salary_last_month',
                    'teamSalaryLastMonth',
                ]),
                fallback.lastMonth
            )
        );
        setText(
            'managerActiveHosts',
            textValue(
                firstNestedValue(sources, [
                    'active_hosts',
                    'activeHosts',
                    'total_active_hosts',
                    'totalActiveHosts',
                    'host_count',
                    'hostCount',
                ]),
                fallback.hosts
            )
        );
        setText(
            'managerGrowth',
            formatPercent(
                firstNestedValue(sources, [
                    'growth',
                    'growth_rate',
                    'growthRate',
                    'salary_growth',
                    'salaryGrowth',
                    'month_growth',
                    'monthGrowth',
                ]),
                fallback.growth
            )
        );
        setText(
            'managerWallet',
            formatMoney(
                firstNestedValue(sources, [
                    'wallet',
                    'wallet_balance',
                    'walletBalance',
                    'balance',
                ]),
                fallback.wallet
            )
        );
        setText(
            'managerBankCards',
            textValue(
                firstNestedValue(sources, [
                    'bank_cards',
                    'bankCards',
                    'bank_card_count',
                    'bankCardCount',
                ]),
                fallback.bankCards
            )
        );
    }

    function formatDateTime(ms) {
        if (!ms) return 'Never';
        var date = new Date(Number(ms));
        var year = date.getFullYear();
        var month = String(date.getMonth() + 1).padStart(2, '0');
        var day = String(date.getDate()).padStart(2, '0');
        var hour = String(date.getHours()).padStart(2, '0');
        var minute = String(date.getMinutes()).padStart(2, '0');
        return year + '-' + month + '-' + day + ' ' + hour + ':' + minute;
    }

    function setPageLoading(loading) {
        // 首屏加载态用页面级骨架屏整层覆盖（common/skeleton.js），数据就绪后整层淡出；
        // is-loading 状态类保留给页面内其他降级样式使用。
        pageState.loading = loading;
        var container = root();
        if (container) container.classList.toggle('is-loading', loading);
        if (!window.HyAppSkeleton) return;
        if (loading) {
            window.HyAppSkeleton.show();
        } else {
            window.HyAppSkeleton.hide();
        }
    }

    function setDenied(denied) {
        pageState.denied = denied;
        var container = root();
        if (!container) return;
        container.classList.toggle('is-denied', denied);
    }

    function normalizeUser(item) {
        var vip = item.current_vip || item.currentVip || item.vip || null;
        return {
            user_id: item.user_id || item.userId || item.target_user_id || '',
            display_user_id:
                item.display_user_id ||
                item.displayUserId ||
                item.target_display_user_id ||
                '',
            username: item.username || item.name || item.target_username || '',
            avatar: item.avatar || item.target_avatar || '',
            country: item.country || '',
            levels: item.levels || {},
            current_vip: vip
                ? {
                      level: Number(vip.level) || 0,
                      name: vip.name || '',
                      active: Boolean(vip.active),
                      started_at_ms: vip.started_at_ms || vip.startedAtMs || 0,
                      expires_at_ms: vip.expires_at_ms || vip.expiresAtMs || 0,
                      updated_at_ms: vip.updated_at_ms || vip.updatedAtMs || 0,
                  }
                : null,
        };
    }

    function normalizeBlock(item) {
        return {
            block_id: item.block_id || item.blockId || '',
            target_user_id: item.target_user_id || item.targetUserId || '',
            target_display_user_id:
                item.target_display_user_id || item.targetDisplayUserId || '',
            target_username: item.target_username || item.targetUsername || '',
            target_avatar: item.target_avatar || item.targetAvatar || '',
            country: item.country || '',
            blocked_until_ms:
                item.blocked_until_ms ||
                item.blockedUntilMs ||
                item.unblockAtMs ||
                0,
            status: item.status || 'active',
        };
    }

    function normalizePermissions(raw) {
        raw = raw || {};
        return {
            canGrantAvatarFrame:
                raw.canGrantAvatarFrame !== undefined
                    ? Boolean(raw.canGrantAvatarFrame)
                    : raw.can_grant_avatar_frame !== undefined
                      ? Boolean(raw.can_grant_avatar_frame)
                      : true,
            canGrantVehicle:
                raw.canGrantVehicle !== undefined
                    ? Boolean(raw.canGrantVehicle)
                    : raw.can_grant_vehicle !== undefined
                      ? Boolean(raw.can_grant_vehicle)
                      : true,
            canGrantBadge:
                raw.canGrantBadge !== undefined
                    ? Boolean(raw.canGrantBadge)
                    : raw.can_grant_badge !== undefined
                      ? Boolean(raw.can_grant_badge)
                      : true,
            canGrantVip:
                raw.canGrantVip !== undefined
                    ? Boolean(raw.canGrantVip)
                    : raw.can_grant_vip !== undefined
                      ? Boolean(raw.can_grant_vip)
                      : true,
            canUpdateUserLevel:
                raw.canUpdateUserLevel !== undefined
                    ? Boolean(raw.canUpdateUserLevel)
                    : raw.can_update_user_level !== undefined
                      ? Boolean(raw.can_update_user_level)
                      : true,
            canAddBdLeader:
                raw.canAddBdLeader !== undefined
                    ? Boolean(raw.canAddBdLeader)
                    : raw.can_add_bd_leader !== undefined
                      ? Boolean(raw.can_add_bd_leader)
                      : true,
            canAddAdmin:
                raw.canAddAdmin !== undefined
                    ? Boolean(raw.canAddAdmin)
                    : raw.can_add_admin !== undefined
                      ? Boolean(raw.can_add_admin)
                      : true,
            canAddSuperadmin:
                raw.canAddSuperadmin !== undefined
                    ? Boolean(raw.canAddSuperadmin)
                    : raw.can_add_superadmin !== undefined
                      ? Boolean(raw.can_add_superadmin)
                      : true,
            canBlockUser:
                raw.canBlockUser !== undefined
                    ? Boolean(raw.canBlockUser)
                    : raw.can_block_user !== undefined
                      ? Boolean(raw.can_block_user)
                      : true,
            canTransferUserCountry:
                raw.canTransferUserCountry !== undefined
                    ? Boolean(raw.canTransferUserCountry)
                    : raw.can_transfer_user_country !== undefined
                      ? Boolean(raw.can_transfer_user_country)
                      : true,
        };
    }

    function canUseAction(action) {
        var key = ACTION_PERMISSION_KEYS[action];
        if (!key) return true;
        return pageState.permissions[key] !== false;
    }

    function renderActionPermissions() {
        document.querySelectorAll('[data-action]').forEach(function (button) {
            var action = button.getAttribute('data-action');
            button.hidden = !canUseAction(action);
        });
    }

    function ensureActionAllowed(action) {
        if (canUseAction(action)) return true;
        toast('Permission denied.');
        return false;
    }

    function apiSearchUser(keyword, scope, action) {
        if (!api || !api.searchUsers) {
            return Promise.reject(new Error('API not available.'));
        }
        return api
            .searchUsers(keyword, 20, scope, action)
            .then(function (data) {
                var items = (data && data.items) || [];
                return items.map(normalizeUser);
            });
    }

    function loadOverview() {
        if (!api || !api.overview) {
            // 无 API 注入（本地纯静态预览等）时立即渲染一次，把骨架屏收敛成中性占位符。
            pageState.permissions = normalizePermissions({});
            renderDashboard();
            renderActionPermissions();
            setDenied(false);
            return Promise.resolve();
        }
        setPageLoading(true);
        return api
            .overview()
            .then(function (data) {
                pageState.overview = data || {};
                pageState.permissions = normalizePermissions(
                    pageState.overview.permissions || pageState.overview
                );
                renderDashboard();
                renderActionPermissions();
                setDenied(false);
                return canUseAction('block-user')
                    ? refreshBlocks()
                    : Promise.resolve();
            })
            .catch(function (error) {
                if (isLocalPreviewError(error)) {
                    pageState.permissions = normalizePermissions({});
                    renderDashboard();
                    renderActionPermissions();
                    setDenied(false);
                    return;
                }
                // 接口失败也要渲染一次：把骨架屏收敛成中性占位符，页面不残留加载态。
                setDenied(true);
                renderDashboard();
                showError(error);
            })
            .finally(function () {
                setPageLoading(false);
            });
    }

    function refreshBlocks() {
        if (!api || !api.listBlocks) return Promise.resolve();
        return api
            .listBlocks('active', 50)
            .then(function (data) {
                blockState.blockedUsers = ((data && data.items) || []).map(
                    normalizeBlock
                );
                renderBlockedList();
            })
            .catch(showError);
    }

    function goBack() {
        if (window.HyAppBridge && window.HyAppBridge.back) {
            window.HyAppBridge.back();
            return;
        }
        if (window.history.length > 1) {
            window.history.back();
        }
    }

    function renderUserRow(user, actionText, onAction) {
        var row = createNode('div', 'searched-user');
        var avatar = createNode('div', 'searched-avatar');
        setAvatar(avatar, user);
        var copy = createNode('div', 'blocked-row-main');
        copy.appendChild(createNode('div', 'searched-name', userName(user)));
        copy.appendChild(
            createNode('div', 'searched-meta', 'UID: ' + userDisplayId(user))
        );
        if (currentVip(user)) {
            copy.appendChild(
                createNode('div', 'searched-vip', currentVipStatusText(user))
            );
        }
        var button = createNode('button', 'user-block-button', actionText);
        button.type = 'button';
        button.addEventListener('click', onAction);
        row.appendChild(avatar);
        row.appendChild(copy);
        row.appendChild(button);
        return row;
    }

    function renderSearchResult() {
        var container = $('blockSearchResult');
        if (!container) return;
        container.innerHTML = '';
        if (!blockState.searchedUser) return;
        container.appendChild(
            renderUserRow(blockState.searchedUser, 'Block', function () {
                selectDuration('86400000', '1 day');
                var panel = $('blockDurationPanel');
                if (panel) panel.hidden = false;
            })
        );
    }

    function setupLevelGrid() {
        var grid = $('levelGrid');
        if (!grid || grid.children.length) return;
        for (var level = 1; level <= 11; level += 1) {
            var button = createNode('button', '', 'Lv. ' + level);
            button.type = 'button';
            button.setAttribute('data-level', String(level));
            grid.appendChild(button);
        }
    }

    function ensureTrackSelector() {
        var panel = $('levelPanel');
        if (!panel || $('levelTrackGrid')) return;
        var title = createNode(
            'div',
            'block-section-title',
            'Select level type'
        );
        var grid = createNode('div', 'track-grid');
        grid.id = 'levelTrackGrid';
        Object.keys(TRACK_LABELS).forEach(function (track) {
            var button = createNode('button', '', TRACK_LABELS[track]);
            button.type = 'button';
            button.setAttribute('data-track', track);
            button.addEventListener('click', function () {
                levelState.selectedTrack = track;
                renderLevelButtons();
                renderLevelSearchResult();
            });
            grid.appendChild(button);
        });
        panel.insertBefore(grid, panel.firstChild);
        panel.insertBefore(title, grid);
    }

    function currentTrackLevel(user) {
        var track = levelState.selectedTrack;
        var levels = (user && user.levels) || {};
        return levels[track] && levels[track].level ? levels[track].level : 0;
    }

    function renderLevelSearchResult() {
        var container = $('levelSearchResult');
        if (!container) return;
        container.innerHTML = '';
        if (!levelState.searchedUser) return;
        var user = levelState.searchedUser;
        var row = createNode('div', 'searched-user');
        var avatar = createNode('div', 'searched-avatar');
        setAvatar(avatar, user);
        var copy = createNode('div', 'blocked-row-main');
        copy.appendChild(createNode('div', 'searched-name', userName(user)));
        copy.appendChild(
            createNode(
                'div',
                'searched-meta',
                'UID: ' +
                    userDisplayId(user) +
                    ' · ' +
                    TRACK_LABELS[levelState.selectedTrack] +
                    ' Lv. ' +
                    currentTrackLevel(user)
            )
        );
        var badge = createNode(
            'div',
            'block-list-count',
            'Lv. ' + currentTrackLevel(user)
        );
        row.appendChild(avatar);
        row.appendChild(copy);
        row.appendChild(badge);
        container.appendChild(row);
    }

    function renderLevelButtons() {
        var trackButtons = document.querySelectorAll(
            '#levelTrackGrid [data-track]'
        );
        trackButtons.forEach(function (button) {
            button.classList.toggle(
                'is-selected',
                button.getAttribute('data-track') === levelState.selectedTrack
            );
        });
        var buttons = document.querySelectorAll('#levelGrid [data-level]');
        buttons.forEach(function (button) {
            var isSelected =
                Number(button.getAttribute('data-level')) ===
                levelState.selectedLevel;
            button.classList.toggle('is-selected', isSelected);
        });
        var confirmButton = $('confirmLevelButton');
        if (confirmButton) {
            confirmButton.disabled =
                !levelState.searchedUser ||
                !levelState.selectedLevel ||
                levelState.submitting;
        }
    }

    function selectLevel(level) {
        levelState.selectedLevel = Number(level) || 0;
        renderLevelButtons();
    }

    function renderDurationButtons() {
        var buttons = document.querySelectorAll(
            '#durationGrid [data-duration-ms]'
        );
        buttons.forEach(function (button) {
            var isSelected =
                Number(button.getAttribute('data-duration-ms')) ===
                blockState.selectedDurationMs;
            button.classList.toggle('is-selected', isSelected);
        });
        var confirmButton = $('confirmBlockButton');
        if (confirmButton) {
            confirmButton.disabled =
                !blockState.searchedUser || blockState.submitting;
        }
    }

    function selectDuration(durationMs, label) {
        blockState.selectedDurationMs = Number(durationMs) || 0;
        blockState.selectedDurationLabel = label || 'Permanent';
        renderDurationButtons();
    }

    function renderBlockedList() {
        var container = $('blockedList');
        var count = $('blockListCount');
        if (!container) return;
        container.innerHTML = '';
        if (count) count.textContent = String(blockState.blockedUsers.length);
        if (!blockState.blockedUsers.length) {
            container.appendChild(
                createNode('div', 'blocked-empty', 'No blocked users.')
            );
            return;
        }
        blockState.blockedUsers.forEach(function (user) {
            var row = createNode('div', 'blocked-row');
            var avatar = createNode('div', 'blocked-avatar');
            setAvatar(avatar, user);
            var copy = createNode('div', 'blocked-row-main');
            copy.appendChild(createNode('div', 'blocked-name', userName(user)));
            copy.appendChild(
                createNode('div', 'blocked-meta', 'UID: ' + userDisplayId(user))
            );
            copy.appendChild(
                createNode(
                    'div',
                    'blocked-time',
                    'Unblock time: ' + formatDateTime(user.blocked_until_ms)
                )
            );
            var unblockButton = createNode(
                'button',
                'user-unblock-button',
                'Unblock'
            );
            unblockButton.type = 'button';
            unblockButton.addEventListener('click', function () {
                unblockUser(user.block_id);
            });
            row.appendChild(avatar);
            row.appendChild(copy);
            row.appendChild(unblockButton);
            container.appendChild(row);
        });
    }

    function unblockUser(blockId) {
        if (!blockId || blockState.submitting) return;
        blockState.submitting = true;
        api.unblockUser(blockId, { reason: 'manager_center' })
            .then(function () {
                toast('User unblocked.');
                return refreshBlocks();
            })
            .catch(showError)
            .finally(function () {
                blockState.submitting = false;
            });
    }

    function resetBlockSearch() {
        var input = $('blockSearchInput');
        var panel = $('blockDurationPanel');
        blockState.searchedUser = null;
        blockState.selectedDurationMs = 0;
        blockState.selectedDurationLabel = '';
        if (input) input.value = '';
        if (panel) panel.hidden = true;
        renderSearchResult();
        renderDurationButtons();
    }

    function openBlockModal() {
        if (pageState.denied) {
            toast('Permission denied.');
            return;
        }
        if (!ensureActionAllowed('block-user')) return;
        var modal = $('blockModal');
        if (!modal) return;
        resetBlockSearch();
        refreshBlocks();
        modal.hidden = false;
        modal.setAttribute('aria-hidden', 'false');
        setTimeout(function () {
            var input = $('blockSearchInput');
            if (input) input.focus();
        }, 30);
    }

    function closeBlockModal() {
        var modal = $('blockModal');
        if (!modal) return;
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
    }

    function resetLevelSearch() {
        var input = $('levelSearchInput');
        var panel = $('levelPanel');
        levelState.searchedUser = null;
        levelState.selectedTrack = 'wealth';
        levelState.selectedLevel = 0;
        if (input) input.value = '';
        if (panel) panel.hidden = true;
        renderLevelSearchResult();
        renderLevelButtons();
    }

    function openLevelModal() {
        if (pageState.denied) {
            toast('Permission denied.');
            return;
        }
        if (!ensureActionAllowed('update-user-level')) return;
        var modal = $('levelModal');
        if (!modal) return;
        resetLevelSearch();
        modal.hidden = false;
        modal.setAttribute('aria-hidden', 'false');
        setTimeout(function () {
            var input = $('levelSearchInput');
            if (input) input.focus();
        }, 30);
    }

    function closeLevelModal() {
        var modal = $('levelModal');
        if (!modal) return;
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
    }

    function searchBlockUser() {
        var input = $('blockSearchInput');
        var value = input ? input.value.trim() : '';
        var panel = $('blockDurationPanel');
        if (!value) {
            toast('Enter user ID.');
            return;
        }
        // 封禁搜索只校验 Block User 权限；不能借用赠送弹窗状态，否则会按资源/VIP 赠送权限误判。
        apiSearchUser(value, '', 'block-user')
            .then(function (items) {
                if (!items.length) {
                    blockState.searchedUser = null;
                    toast('No user found.');
                    return;
                }
                blockState.searchedUser = items[0];
                blockState.selectedDurationMs = 0;
                blockState.selectedDurationLabel = '';
                if (panel) panel.hidden = true;
                renderSearchResult();
                renderDurationButtons();
            })
            .catch(showError);
    }

    function confirmBlockUser() {
        if (!blockState.searchedUser) {
            toast('Search a user first.');
            return;
        }
        if (blockState.submitting) return;
        var durationMs = blockState.selectedDurationMs || PERMANENT_BLOCK_MS;
        blockState.submitting = true;
        renderDurationButtons();
        api.blockUser({
            command_id: commandId('manager-block'),
            target_user_id: userId(blockState.searchedUser),
            blocked_until_ms: Date.now() + durationMs,
            reason: 'manager_center',
        })
            .then(function () {
                toast('User blocked.');
                resetBlockSearch();
                return refreshBlocks();
            })
            .catch(showError)
            .finally(function () {
                blockState.submitting = false;
                renderDurationButtons();
            });
    }

    function searchLevelUser() {
        var input = $('levelSearchInput');
        var value = input ? input.value.trim() : '';
        var panel = $('levelPanel');
        if (!value) {
            toast('Enter user ID.');
            return;
        }
        // 等级调整搜索按自己的能力开关校验，避免资源赠送关闭时误挡等级操作。
        apiSearchUser(value, '', 'update-user-level')
            .then(function (items) {
                if (!items.length) {
                    levelState.searchedUser = null;
                    toast('No user found.');
                    return;
                }
                levelState.searchedUser = items[0];
                levelState.selectedLevel = 0;
                if (panel) panel.hidden = false;
                renderLevelSearchResult();
                renderLevelButtons();
            })
            .catch(showError);
    }

    function confirmLevelUpdate() {
        if (!levelState.searchedUser) {
            toast('Search a user first.');
            return;
        }
        if (!levelState.selectedLevel) {
            toast('Select a user level.');
            return;
        }
        if (levelState.submitting) return;
        levelState.submitting = true;
        renderLevelButtons();
        api.updateLevel({
            command_id: commandId('manager-level'),
            target_user_id: userId(levelState.searchedUser),
            track: levelState.selectedTrack,
            level: levelState.selectedLevel,
            reason: 'manager_center',
        })
            .then(function () {
                toast('User level updated.');
                closeLevelModal();
            })
            .catch(showError)
            .finally(function () {
                levelState.submitting = false;
                renderLevelButtons();
            });
    }

    function ensureGrantModal() {
        if ($('grantModal')) return;
        var modal = createNode('div', 'block-modal grant-modal');
        modal.id = 'grantModal';
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
        modal.innerHTML =
            '<button class="block-backdrop" id="grantBackdrop" type="button" aria-label="Close"></button>' +
            '<section class="block-dialog" role="dialog" aria-modal="true" aria-labelledby="grantDialogTitle">' +
            '<div class="block-dialog-header"><h2 id="grantDialogTitle">Send</h2>' +
            '<button class="block-close" id="grantCloseButton" type="button" aria-label="Close"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>' +
            '<div class="block-dialog-body"><div class="block-field"><label for="grantSearchInput">User ID</label>' +
            '<div class="block-search-row"><input id="grantSearchInput" type="text" inputmode="numeric" autocomplete="off" placeholder="Enter user ID"/><button id="grantSearchButton" type="button">Search</button></div></div>' +
            '<div class="block-search-result" id="grantSearchResult" aria-live="polite"></div>' +
            '<div class="level-panel" id="grantPanel" hidden><div class="block-section-title" id="grantOptionTitle">Select item</div><div class="grant-option-grid" id="grantOptionGrid"></div><div class="block-section-title" id="grantDurationTitle" hidden>Select duration</div><div class="duration-grid grant-duration-grid" id="grantDurationGrid" hidden></div><button class="confirm-level-button" id="confirmGrantButton" type="button" disabled>Send now</button></div></div></section>';
        document.querySelector('.manager-center').appendChild(modal);
        $('grantBackdrop').addEventListener('click', closeGrantModal);
        $('grantCloseButton').addEventListener('click', closeGrantModal);
        $('grantSearchButton').addEventListener('click', searchGrantUser);
        $('grantSearchInput').addEventListener('keydown', function (event) {
            if (event.key === 'Enter') searchGrantUser();
        });
        $('confirmGrantButton').addEventListener('click', confirmGrant);
    }

    function openGrantModal(action) {
        if (pageState.denied) {
            toast('Permission denied.');
            return;
        }
        if (!ensureActionAllowed(action)) return;
        ensureGrantModal();
        grantState.action = action;
        grantState.resourceType = RESOURCE_TYPES[action] || '';
        grantState.title = ACTION_LABELS[action] || 'Send';
        grantState.searchedUser = null;
        grantState.selectedResourceIds = [];
        grantState.selectedResourceDurationMs =
            DEFAULT_RESOURCE_GRANT_DURATION_MS;
        grantState.selectedVipLevel = 0;
        $('grantDialogTitle').textContent = grantState.title;
        $('grantSearchInput').value = '';
        $('grantSearchResult').innerHTML = '';
        $('grantPanel').hidden = true;
        $('grantModal').hidden = false;
        $('grantModal').setAttribute('aria-hidden', 'false');
        renderGrantOptions();
        if (grantState.resourceType)
            loadGrantResources(grantState.resourceType);
        setTimeout(function () {
            $('grantSearchInput').focus();
        }, 30);
    }

    function closeGrantModal() {
        var modal = $('grantModal');
        if (!modal) return;
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
    }

    function loadGrantResources(resourceType) {
        if (pageState.resourcesByType[resourceType]) {
            renderGrantOptions();
            return;
        }
        if (pageState.resourceRequestsByType[resourceType]) return;

        // 同一资源类型只保留一个全量分页请求；全部页面成功后才缓存，任一页失败时允许下次打开弹窗重新获取。
        pageState.resourceRequestsByType[resourceType] = api
            .listAllResources(resourceType, 20)
            .then(function (data) {
                pageState.resourcesByType[resourceType] =
                    (data && data.items) || [];
                delete pageState.resourceRequestsByType[resourceType];
                if (grantState.resourceType === resourceType) {
                    renderGrantOptions();
                }
            })
            .catch(function (error) {
                delete pageState.resourceRequestsByType[resourceType];
                showError(error);
            });
    }

    function searchGrantUser() {
        var value = $('grantSearchInput').value.trim();
        if (!value) {
            toast('Enter user ID.');
            return;
        }
        // 搜索入口也必须携带当前赠送动作；Send VIP 只校验 VIP 赠送权限，不能落回资源赠送权限导致误拒。
        apiSearchUser(value, '', grantState.action)
            .then(function (items) {
                if (!items.length) {
                    grantState.searchedUser = null;
                    toast('No user found.');
                    return;
                }
                grantState.searchedUser = items[0];
                var container = $('grantSearchResult');
                container.innerHTML = '';
                container.appendChild(
                    renderUserRow(
                        grantState.searchedUser,
                        'Select',
                        function () {
                            $('grantPanel').hidden = false;
                            renderGrantOptions();
                        }
                    )
                );
                $('grantPanel').hidden = false;
                renderGrantOptions();
            })
            .catch(showError);
    }

    function renderGrantOptions() {
        var grid = $('grantOptionGrid');
        if (!grid) return;
        grid.innerHTML = '';
        grid.classList.toggle(
            'is-resource-grid',
            grantState.action !== 'send-vip'
        );
        var durationTitle = $('grantDurationTitle');
        var durationGrid = $('grantDurationGrid');
        if (durationTitle) {
            durationTitle.hidden = false;
            durationTitle.textContent =
                grantState.action === 'send-vip'
                    ? 'Duration: 30 days'
                    : 'Select duration';
        }
        if (durationGrid) {
            durationGrid.innerHTML = '';
            durationGrid.hidden = grantState.action === 'send-vip';
        }
        if (grantState.action === 'send-vip') {
            $('grantOptionTitle').textContent = 'Select VIP level';
            var activeVipLevel = currentVipLevel(grantState.searchedUser || {});
            if (
                grantState.selectedVipLevel &&
                activeVipLevel > grantState.selectedVipLevel
            ) {
                grantState.selectedVipLevel = 0;
            }
            // VIP grants must stay on the explicit product allow-list so the UI never sends a level the backend has not opened.
            VIP_GRANT_LEVELS.forEach(function (level) {
                var button = createNode('button', '', 'VIP ' + level);
                var blockedByCurrentVip = activeVipLevel > level;
                button.type = 'button';
                button.disabled = blockedByCurrentVip;
                if (blockedByCurrentVip) {
                    button.title = 'Current VIP is higher';
                }
                button.classList.toggle(
                    'is-selected',
                    grantState.selectedVipLevel === level
                );
                button.addEventListener('click', function () {
                    if (blockedByCurrentVip) return;
                    grantState.selectedVipLevel = level;
                    renderGrantOptions();
                });
                grid.appendChild(button);
            });
            if (activeVipLevel > 1) {
                grid.appendChild(
                    createNode(
                        'div',
                        'vip-grant-note',
                        activeVipLevel > Math.max.apply(null, VIP_GRANT_LEVELS)
                            ? 'Current VIP is higher than manager-center gift levels.'
                            : 'Lower VIP levels are disabled because the user already has a higher VIP.'
                    )
                );
            }
        } else {
            $('grantOptionTitle').textContent = 'Select ' + resourceKindLabel();
            var resources =
                pageState.resourcesByType[grantState.resourceType] || [];
            var selectedResourceSet = grantState.selectedResourceIds.reduce(
                function (result, resourceId) {
                    result[String(resourceId)] = true;
                    return result;
                },
                {}
            );
            if (!resources.length) {
                grid.appendChild(
                    createNode('div', 'blocked-empty', 'No resource available.')
                );
            }
            resources.forEach(function (resource) {
                var button = createNode('button', 'grant-resource-option');
                var imageURL = resourceImageUrl(resource);
                var resourceID = resource.resource_id;
                var resourceKey = String(resourceID);
                button.type = 'button';
                button.setAttribute(
                    'aria-label',
                    'Select ' + resourceKindLabel()
                );
                button.classList.toggle(
                    'is-selected',
                    !!selectedResourceSet[resourceKey]
                );
                if (imageURL) {
                    var media = createNode('span', 'grant-resource-media');
                    var img = document.createElement('img');
                    img.src = imageURL;
                    img.alt = '';
                    media.appendChild(img);
                    button.appendChild(media);
                } else {
                    button.appendChild(
                        createNode('span', 'grant-resource-fallback')
                    );
                }
                button.addEventListener('click', function () {
                    // 资源赠送是素材发放，不是互斥装备选择；同一弹窗允许一次选择多个素材，由后端拆成独立 grant 命令保证可重试。
                    if (selectedResourceSet[resourceKey]) {
                        grantState.selectedResourceIds =
                            grantState.selectedResourceIds.filter(
                                function (selectedID) {
                                    return String(selectedID) !== resourceKey;
                                }
                            );
                    } else {
                        grantState.selectedResourceIds =
                            grantState.selectedResourceIds.concat(resourceID);
                    }
                    renderGrantOptions();
                });
                grid.appendChild(button);
            });
            if (grantState.selectedResourceIds.length) {
                grid.appendChild(
                    createNode(
                        'div',
                        'resource-selected-note',
                        grantState.selectedResourceIds.length + ' selected'
                    )
                );
            }
            if (durationGrid) {
                RESOURCE_GRANT_DURATIONS.forEach(function (item) {
                    var durationButton = createNode('button', '', item.label);
                    durationButton.type = 'button';
                    durationButton.classList.toggle(
                        'is-selected',
                        grantState.selectedResourceDurationMs === item.ms
                    );
                    durationButton.addEventListener('click', function () {
                        grantState.selectedResourceDurationMs = item.ms;
                        renderGrantOptions();
                    });
                    durationGrid.appendChild(durationButton);
                });
            }
        }
        var confirm = $('confirmGrantButton');
        if (confirm) {
            confirm.disabled =
                !grantState.searchedUser ||
                grantState.submitting ||
                (grantState.action === 'send-vip'
                    ? !grantState.selectedVipLevel ||
                      currentVipLevel(grantState.searchedUser) >
                          grantState.selectedVipLevel
                    : !grantState.selectedResourceIds.length ||
                      !grantState.selectedResourceDurationMs);
        }
    }

    function confirmGrant() {
        if (!grantState.searchedUser || grantState.submitting) return;
        grantState.submitting = true;
        renderGrantOptions();
        var payload = {
            command_id: commandId('manager-grant'),
            target_user_id: userId(grantState.searchedUser),
            reason: 'manager_center',
        };
        var request;
        if (grantState.action === 'send-vip') {
            payload.level = grantState.selectedVipLevel;
            request = api.grantVip(payload);
        } else {
            payload.resource_ids = grantState.selectedResourceIds.slice();
            payload.duration_ms = grantState.selectedResourceDurationMs;
            request = api.grantResource(payload);
        }
        request
            .then(function () {
                toast('Sent successfully.');
                closeGrantModal();
            })
            .catch(showError)
            .finally(function () {
                grantState.submitting = false;
                renderGrantOptions();
            });
    }

    function ensureBDLeaderModal() {
        if ($('bdLeaderModal')) return;
        var modal = createNode('div', 'block-modal bd-leader-modal');
        modal.id = 'bdLeaderModal';
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
        modal.innerHTML =
            '<button class="block-backdrop" id="bdLeaderBackdrop" type="button" aria-label="Close"></button>' +
            '<section class="block-dialog" role="dialog" aria-modal="true" aria-labelledby="bdLeaderDialogTitle">' +
            '<div class="block-dialog-header"><h2 id="bdLeaderDialogTitle">Add BD Leader</h2>' +
            '<button class="block-close" id="bdLeaderCloseButton" type="button" aria-label="Close"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>' +
            '<div class="block-dialog-body"><div class="block-field"><label for="bdLeaderSearchInput">User ID</label>' +
            '<div class="block-search-row"><input id="bdLeaderSearchInput" type="text" inputmode="numeric" autocomplete="off" placeholder="Enter user ID"/><button id="bdLeaderSearchButton" type="button">Search</button></div></div>' +
            '<div class="block-search-result" id="bdLeaderSearchResult" aria-live="polite"></div>' +
            '<div class="level-panel" id="bdLeaderPanel" hidden><div class="block-section-title">Add this user as BD Leader</div>' +
            '<button class="confirm-level-button" id="confirmBDLeaderButton" type="button" disabled>Add BD Leader</button></div></div></section>';
        document.querySelector('.manager-center').appendChild(modal);
        $('bdLeaderBackdrop').addEventListener('click', closeBDLeaderModal);
        $('bdLeaderCloseButton').addEventListener('click', closeBDLeaderModal);
        $('bdLeaderSearchButton').addEventListener('click', searchBDLeaderUser);
        $('bdLeaderSearchInput').addEventListener('keydown', function (event) {
            if (event.key === 'Enter') searchBDLeaderUser();
        });
        $('confirmBDLeaderButton').addEventListener('click', confirmBDLeader);
    }

    function openBDLeaderModal(action) {
        if (pageState.denied) {
            toast('Permission denied.');
            return;
        }
        if (!ensureActionAllowed(action)) return;
        ensureBDLeaderModal();
        bdLeaderState.action = action;
        bdLeaderState.title = ACTION_LABELS[action] || 'Add BD Leader';
        bdLeaderState.searchedUser = null;
        bdLeaderState.submitting = false;
        $('bdLeaderDialogTitle').textContent = bdLeaderState.title;
        $('confirmBDLeaderButton').textContent = bdLeaderState.title;
        $('bdLeaderSearchInput').value = '';
        $('bdLeaderSearchResult').innerHTML = '';
        $('bdLeaderPanel').hidden = true;
        renderBDLeaderActions();
        $('bdLeaderModal').hidden = false;
        $('bdLeaderModal').setAttribute('aria-hidden', 'false');
        setTimeout(function () {
            $('bdLeaderSearchInput').focus();
        }, 30);
    }

    function closeBDLeaderModal() {
        var modal = $('bdLeaderModal');
        if (!modal) return;
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
    }

    function searchBDLeaderUser() {
        var value = $('bdLeaderSearchInput').value.trim();
        if (!value) {
            toast('Enter user ID.');
            return;
        }
        // BD/Admin/Superadmin 共用弹窗，搜索阶段先按当前按钮的能力开关过滤；写入口仍会二次校验真实落库能力。
        apiSearchUser(value, '', bdLeaderState.action)
            .then(function (items) {
                if (!items.length) {
                    bdLeaderState.searchedUser = null;
                    $('bdLeaderSearchResult').innerHTML = '';
                    $('bdLeaderPanel').hidden = true;
                    renderBDLeaderActions();
                    toast('No user found.');
                    return;
                }
                bdLeaderState.searchedUser = items[0];
                var container = $('bdLeaderSearchResult');
                container.innerHTML = '';
                container.appendChild(
                    renderUserRow(
                        bdLeaderState.searchedUser,
                        'Select',
                        function () {
                            $('bdLeaderPanel').hidden = false;
                            renderBDLeaderActions();
                        }
                    )
                );
                $('bdLeaderPanel').hidden = false;
                renderBDLeaderActions();
            })
            .catch(showError);
    }

    function renderBDLeaderActions() {
        var confirm = $('confirmBDLeaderButton');
        if (!confirm) return;
        confirm.disabled =
            !bdLeaderState.searchedUser || bdLeaderState.submitting;
    }

    function confirmBDLeader() {
        if (!bdLeaderState.searchedUser) {
            toast('Search a user first.');
            return;
        }
        if (!api || !api.createBDLeader) {
            toast('API not available.');
            return;
        }
        if (bdLeaderState.submitting) return;
        bdLeaderState.submitting = true;
        renderBDLeaderActions();
        api.createBDLeader({
            command_id: commandId('manager-bd-leader'),
            target_user_id: userId(bdLeaderState.searchedUser),
            reason: 'manager_center',
        })
            .then(function () {
                toast('BD Leader added.');
                closeBDLeaderModal();
            })
            .catch(showError)
            .finally(function () {
                bdLeaderState.submitting = false;
                renderBDLeaderActions();
            });
    }

    function normalizeCountry(item) {
        item = item || {};
        var code = String(
            item.country_code ||
                item.countryCode ||
                item.code ||
                item.alphaTwo ||
                item.alpha_two ||
                ''
        )
            .trim()
            .toUpperCase();
        return {
            code: code,
            name:
                item.country_display_name ||
                item.countryDisplayName ||
                item.country_name ||
                item.countryName ||
                item.name ||
                code,
        };
    }

    function countryLabel(country) {
        if (!country) return '';
        return country.name && country.name !== country.code
            ? country.name + ' · ' + country.code
            : country.code;
    }

    function selectedCountry() {
        for (var i = 0; i < pageState.countries.length; i += 1) {
            if (
                pageState.countries[i].code === countryState.selectedCountryCode
            ) {
                return pageState.countries[i];
            }
        }
        return null;
    }

    function loadCountries() {
        if (pageState.countries.length) {
            renderCountryOptions();
            return Promise.resolve(pageState.countries);
        }
        if (!api || !api.listCountries) {
            return Promise.reject(new Error('API not available.'));
        }
        return api
            .listCountries()
            .then(function (data) {
                var list = (data && (data.countries || data.items)) || [];
                pageState.countries = list
                    .map(normalizeCountry)
                    .filter(function (country) {
                        return !!country.code;
                    });
                renderCountryOptions();
                return pageState.countries;
            })
            .catch(showError);
    }

    function ensureCountryModal() {
        if ($('countryModal')) return;
        var modal = createNode('div', 'block-modal country-modal');
        modal.id = 'countryModal';
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
        modal.innerHTML =
            '<button class="block-backdrop" id="countryBackdrop" type="button" aria-label="Close"></button>' +
            '<section class="block-dialog" role="dialog" aria-modal="true" aria-labelledby="countryDialogTitle">' +
            '<div class="block-dialog-header"><h2 id="countryDialogTitle">Transfer User Country</h2>' +
            '<button class="block-close" id="countryCloseButton" type="button" aria-label="Close"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 6l12 12M18 6 6 18"/></svg></button></div>' +
            '<div class="block-dialog-body"><div class="block-field"><label for="countrySearchInput">User ID</label>' +
            '<div class="block-search-row"><input id="countrySearchInput" type="text" inputmode="numeric" autocomplete="off" placeholder="Enter user ID"/><button id="countrySearchButton" type="button">Search</button></div></div>' +
            '<div class="block-search-result" id="countrySearchResult" aria-live="polite"></div>' +
            '<div class="level-panel" id="countryPanel" hidden><div class="block-section-title">Select country</div><div class="grant-option-grid" id="countryOptionGrid"></div><button class="confirm-level-button" id="confirmCountryButton" type="button" disabled>Confirm Transfer</button></div></div></section>';
        document.querySelector('.manager-center').appendChild(modal);
        $('countryBackdrop').addEventListener('click', closeCountryModal);
        $('countryCloseButton').addEventListener('click', closeCountryModal);
        $('countrySearchButton').addEventListener('click', searchCountryUser);
        $('countrySearchInput').addEventListener('keydown', function (event) {
            if (event.key === 'Enter') searchCountryUser();
        });
        $('confirmCountryButton').addEventListener(
            'click',
            confirmCountryTransfer
        );
    }

    function openCountryModal() {
        if (pageState.denied) {
            toast('Permission denied.');
            return;
        }
        if (!ensureActionAllowed('transfer-user-country')) return;
        ensureCountryModal();
        countryState.searchedUser = null;
        countryState.selectedCountryCode = '';
        countryState.submitting = false;
        $('countrySearchInput').value = '';
        $('countrySearchResult').innerHTML = '';
        $('countryPanel').hidden = true;
        $('countryModal').hidden = false;
        $('countryModal').setAttribute('aria-hidden', 'false');
        loadCountries();
        renderCountryActions();
        setTimeout(function () {
            $('countrySearchInput').focus();
        }, 30);
    }

    function closeCountryModal() {
        var modal = $('countryModal');
        if (!modal) return;
        modal.hidden = true;
        modal.setAttribute('aria-hidden', 'true');
    }

    function searchCountryUser() {
        var value = $('countrySearchInput').value.trim();
        if (!value) {
            toast('Enter user ID.');
            return;
        }
        // 转国家是唯一允许跨国家搜索的入口，必须同时携带 scope=all 和动作，避免额外依赖资源赠送权限。
        apiSearchUser(value, 'all', 'transfer-user-country')
            .then(function (items) {
                if (!items.length) {
                    countryState.searchedUser = null;
                    $('countrySearchResult').innerHTML = '';
                    $('countryPanel').hidden = true;
                    renderCountryActions();
                    toast('No user found.');
                    return;
                }
                countryState.searchedUser = items[0];
                var container = $('countrySearchResult');
                container.innerHTML = '';
                container.appendChild(
                    renderUserRow(
                        countryState.searchedUser,
                        'Select',
                        function () {
                            $('countryPanel').hidden = false;
                            renderCountryActions();
                        }
                    )
                );
                $('countryPanel').hidden = false;
                renderCountryActions();
            })
            .catch(showError);
    }

    function renderCountryOptions() {
        var grid = $('countryOptionGrid');
        if (!grid) return;
        grid.innerHTML = '';
        if (!pageState.countries.length) {
            grid.appendChild(
                createNode('div', 'blocked-empty', 'No country available.')
            );
            renderCountryActions();
            return;
        }
        pageState.countries.forEach(function (country) {
            var button = createNode('button', 'country-option');
            button.type = 'button';
            button.classList.toggle(
                'is-selected',
                countryState.selectedCountryCode === country.code
            );
            button.appendChild(createNode('span', '', countryLabel(country)));
            button.addEventListener('click', function () {
                countryState.selectedCountryCode = country.code;
                renderCountryOptions();
                renderCountryActions();
            });
            grid.appendChild(button);
        });
        renderCountryActions();
    }

    function renderCountryActions() {
        var confirm = $('confirmCountryButton');
        if (!confirm) return;
        var currentCountry = String(
            (countryState.searchedUser && countryState.searchedUser.country) ||
                ''
        ).toUpperCase();
        confirm.disabled =
            !countryState.searchedUser ||
            !countryState.selectedCountryCode ||
            countryState.selectedCountryCode === currentCountry ||
            countryState.submitting;
        var country = selectedCountry();
        confirm.textContent = country
            ? 'Transfer to ' + countryLabel(country)
            : 'Confirm Transfer';
    }

    function confirmCountryTransfer() {
        if (!countryState.searchedUser) {
            toast('Search a user first.');
            return;
        }
        if (!countryState.selectedCountryCode) {
            toast('Select a country.');
            return;
        }
        if (countryState.submitting) return;
        countryState.submitting = true;
        renderCountryActions();
        api.transferUserCountry({
            command_id: commandId('manager-country'),
            target_user_id: userId(countryState.searchedUser),
            country: countryState.selectedCountryCode,
            reason: 'manager_center_country_transfer',
        })
            .then(function () {
                toast('User country transferred.');
                closeCountryModal();
            })
            .catch(showError)
            .finally(function () {
                countryState.submitting = false;
                renderCountryActions();
            });
    }

    function copyManagerId() {
        var value = $('managerDisplayId')
            ? $('managerDisplayId').textContent.trim()
            : '';
        if (!value) return;
        if (window.navigator && window.navigator.clipboard) {
            window.navigator.clipboard
                .writeText(value)
                .then(function () {
                    toast('Copied.');
                })
                .catch(function () {
                    toast(value);
                });
            return;
        }
        toast(value);
    }

    function bindEvents() {
        var backButton = $('backButton');
        if (backButton) backButton.addEventListener('click', goBack);
        var copyButton = document.querySelector('.manager-copy-button');
        if (copyButton) copyButton.addEventListener('click', copyManagerId);
        document.querySelectorAll('[data-action]').forEach(function (button) {
            button.addEventListener('click', function () {
                var action = button.getAttribute('data-action');
                if (!ensureActionAllowed(action)) {
                    return;
                }
                if (action === 'block-user') {
                    openBlockModal();
                    return;
                }
                if (action === 'update-user-level') {
                    openLevelModal();
                    return;
                }
                if (action === 'transfer-user-country') {
                    openCountryModal();
                    return;
                }
                if (
                    action === 'add-bd-leader' ||
                    action === 'add-admin' ||
                    action === 'add-superadmin'
                ) {
                    openBDLeaderModal(action);
                    return;
                }
                openGrantModal(action);
            });
        });
        setupLevelGrid();
        ensureTrackSelector();
        var closeButton = $('blockCloseButton');
        var backdrop = $('blockBackdrop');
        var searchButton = $('blockSearchButton');
        var searchInput = $('blockSearchInput');
        var confirmButton = $('confirmBlockButton');
        var levelCloseButton = $('levelCloseButton');
        var levelBackdrop = $('levelBackdrop');
        var levelSearchButton = $('levelSearchButton');
        var levelSearchInput = $('levelSearchInput');
        var confirmLevelButton = $('confirmLevelButton');
        if (closeButton) closeButton.addEventListener('click', closeBlockModal);
        if (backdrop) backdrop.addEventListener('click', closeBlockModal);
        if (levelCloseButton)
            levelCloseButton.addEventListener('click', closeLevelModal);
        if (levelBackdrop)
            levelBackdrop.addEventListener('click', closeLevelModal);
        if (searchButton)
            searchButton.addEventListener('click', searchBlockUser);
        if (searchInput) {
            searchInput.addEventListener('keydown', function (event) {
                if (event.key === 'Enter') searchBlockUser();
            });
        }
        if (levelSearchButton)
            levelSearchButton.addEventListener('click', searchLevelUser);
        if (levelSearchInput) {
            levelSearchInput.addEventListener('keydown', function (event) {
                if (event.key === 'Enter') searchLevelUser();
            });
        }
        if (confirmButton)
            confirmButton.addEventListener('click', confirmBlockUser);
        if (confirmLevelButton) {
            confirmLevelButton.addEventListener('click', confirmLevelUpdate);
        }
        document
            .querySelectorAll('#durationGrid [data-duration-ms]')
            .forEach(function (button) {
                button.addEventListener('click', function () {
                    selectDuration(
                        button.getAttribute('data-duration-ms'),
                        button.getAttribute('data-duration-label')
                    );
                });
            });
        document
            .querySelectorAll('#levelGrid [data-level]')
            .forEach(function (button) {
                button.addEventListener('click', function () {
                    selectLevel(button.getAttribute('data-level'));
                });
            });
    }

    function init() {
        bindEvents();
        renderBlockedList();
        // 首屏不预渲染仪表盘：骨架屏保持到 loadOverview 的任一分支调用 renderDashboard 收敛。
        loadOverview();
        if (window.HyAppBridge && window.HyAppBridge.ready) {
            window.HyAppBridge.ready({ page: 'manager-center' });
        }
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }
})();
