// SaaSShop Admin JS
// 说明：用于增强总台管理的运营交互体验（尽量保持小而可治理）。
// 原则：不引入复杂构建链；以渐进增强为主，页面无 JS 也应可用。

(function () {
    if (window.__SAASSHOP_ADMIN_JS__) {
        return;
    }
    window.__SAASSHOP_ADMIN_JS__ = true;

    function qs(sel, root) {
        return (root || document).querySelector(sel);
    }

    function formatMoney(v) {
        var n = Number(v || 0);
        if (!isFinite(n)) {
            n = 0;
        }
        // 统一口径：两位小数 + 千分位
        try {
            return n.toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
        } catch (e) {
            return n.toFixed(2);
        }
    }

    function formatPct(ratio, digits) {
        var d = (digits == null) ? 1 : Number(digits);
        if (!isFinite(d) || d < 0) {
            d = 1;
        }
        var r = Number(ratio || 0);
        if (!isFinite(r)) {
            r = 0;
        }
        return (r * 100).toFixed(d);
    }

    // 续费缺订阅治理：绑定成功后自动滚动到顶部提示区（让运营立刻看到 success/warning/error）
    // 说明：由后端 redirect url 追加 attached_subscription=1 触发。
    if (window.location && window.location.search && window.location.search.indexOf('attached_subscription=1') >= 0) {
        try {
            window.scrollTo({ top: 0, behavior: 'smooth' });
        } catch (e) {
            window.scrollTo(0, 0);
        }
    }

    // 平台订单详情页：当从仪表盘/列表跳转到某个治理锚点（例如 #add-payment-receipt）时，自动展开对应 <details>。
    // 说明：避免“跳过去但面板是折叠的”，造成运营以为没跳到。
    (function () {
        if (!window.location || !window.location.hash) {
            return;
        }

        var h = String(window.location.hash || '');
        var map = {
            '#add-payment-receipt': 'details#add-payment-receipt',
            '#add-refund-receipt': 'details#add-refund-receipt',
        };

        if (map[h]) {
            var d = qs(map[h]);
            if (d) {
                d.open = true;
            }
        }
    })();

    // 平台订单列表页：当从批次页等入口带 #filters 跳转过来时，自动展开筛选面板并定位。
    // 说明：筛选面板会记忆折叠状态（localStorage）；若运营之前手动收起，再跳转回来可能看不到筛选条件。
    (function () {
        if (!window.location || String(window.location.hash || '') !== '#filters') {
            return;
        }

        var d = qs('#filters');
        if (!d) {
            return;
        }

        // 若是 <details>，确保展开
        if (String(d.tagName || '').toLowerCase() === 'details') {
            d.open = true;
        }

        // 轻量定位（不强依赖 smooth）
        try {
            d.scrollIntoView({ behavior: 'smooth', block: 'start' });
        } catch (e) {
            try {
                d.scrollIntoView();
            } catch (e2) {}
        }
    })();

    // 通用：表单提交后禁用按钮，避免运营重复点击造成重复请求
    // 用法：form 标记 data-action="disable-on-submit"。
    (function () {
        var forms = document.querySelectorAll('form[data-action="disable-on-submit"]');
        if (!forms || forms.length === 0) {
            return;
        }

        forms.forEach(function (form) {
            form.addEventListener('submit', function () {
                try {
                    var btns = form.querySelectorAll('button, input[type="submit"]');
                    btns.forEach(function (b) {
                        b.disabled = true;
                        // 尽量不改文案（避免影响断言/文案口径）；只做禁用
                    });
                } catch (e) {}
            });
        });
    })();

    // 通用：折叠面板（collapsible）记忆展开状态（localStorage）
    // 用法：<details data-role="collapsible" data-storage-key="xxx">
    (function () {
        // 兼容历史：旧实现要求 data-role="collapsible"；现在只要存在 data-storage-key 就启用记忆。
        var nodes = document.querySelectorAll('details[data-storage-key], details[data-role="collapsible"][data-storage-key]');
        if (!nodes || nodes.length === 0) {
            return;
        }

        nodes.forEach(function (d) {
            var key = d.getAttribute('data-storage-key');
            if (!key) {
                return;
            }

            try {
                var saved = window.localStorage.getItem(key);
                if (saved === 'open') {
                    d.open = true;
                } else if (saved === 'closed') {
                    d.open = false;
                }
            } catch (e) {}

            d.addEventListener('toggle', function () {
                try {
                    window.localStorage.setItem(key, d.open ? 'open' : 'closed');
                } catch (e) {}
            });
        });
    })();

    // 仪表盘：列宽一致（趋势/收费工作台 与 最近平台订单同列宽度一致）
    // 说明：用户明确需求是“宽度一致”，不是高度一致。
    // 方案：基于 CSS Grid 的列宽天然一致；这里不再做任何 JS 对齐（避免误解/副作用）。
    // 保留 data-role 供测试与未来渐进增强定位用。

    // 仪表盘：迷你图表（趋势图渐进增强）
    // 说明：不引入图表库，避免构建链；用 div bar 方式渲染。
    (function () {
        var el = qs('[data-role="platform-order-trend-7d-chart"][data-points]');
        if (!el) {
            return;
        }

        var raw = el.getAttribute('data-points') || '[]';
        var points = [];
        try {
            points = JSON.parse(raw) || [];
        } catch (e) {
            points = [];
        }

        if (!points || points.length === 0) {
            el.classList.add('is-empty');
            el.textContent = '暂无趋势数据';
            return;
        }

        var max = 0;
        points.forEach(function (p) {
            var v = Number(p && p.paid_sum ? p.paid_sum : 0);
            if (v > max) {
                max = v;
            }
        });
        if (!max || max <= 0) {
            max = 1;
        }

        // 渐进增强：从下方表格复用“日期→订单集合”链接口径（避免硬编码 URL 规则）。
        var dateToHref = {};
        try {
            var links = document.querySelectorAll('[data-role="platform-order-trend-7d"] a.link');
            links.forEach(function (a) {
                var d = String((a.textContent || '')).trim();
                if (!d) {
                    return;
                }
                dateToHref[d] = String(a.getAttribute('href') || '');
            });
        } catch (e) {
            dateToHref = {};
        }

        // 清空（避免 SSR/重复执行污染）
        el.innerHTML = '';

        points.forEach(function (p) {
            var paid = Number(p && p.paid_sum ? p.paid_sum : 0);
            var h = Math.round(Math.max(6, (paid / max) * 72));

            var date = (p && p.date) ? String(p.date) : '';
            var href = (date && dateToHref[date]) ? String(dateToHref[date]) : '';

            var bar = document.createElement(href ? 'a' : 'div');
            bar.className = 'adm-mini-chart-bar' + (href ? ' adm-mini-chart-bar-link' : '');
            bar.style.height = h + 'px';
            if (href) {
                bar.setAttribute('href', href);
                bar.setAttribute('role', 'link');
                bar.setAttribute('aria-label', '进入当日订单集合：' + date);
            }

            var countNum = Number(p && p.count != null ? p.count : 0);
            if (!isFinite(countNum) || countNum < 0) {
                countNum = 0;
            }
            var avg = countNum > 0 ? (paid / countNum) : 0;
            bar.title = date + '｜订单 ' + String(countNum) + ' 单｜已付 ¥' + formatMoney(paid) + '｜单均 ¥' + formatMoney(avg);

            el.appendChild(bar);
        });
    })();

    // 仪表盘：迷你排行（近7天站点收入 Top5）
    (function () {
        var el = qs('[data-role="merchant-revenue-rank-7d-chart"][data-points]');
        if (!el) {
            return;
        }

        var raw = el.getAttribute('data-points') || '[]';
        var points = [];
        try {
            points = JSON.parse(raw) || [];
        } catch (e) {
            points = [];
        }

        if (!points || points.length === 0) {
            el.classList.add('is-empty');
            el.textContent = '暂无排行数据';
            return;
        }

        var max = 0;
        points.forEach(function (p) {
            var v = Number(p && p.paid_sum ? p.paid_sum : 0);
            if (v > max) {
                max = v;
            }
        });
        if (!max || max <= 0) {
            max = 1;
        }

        // 渐进增强：从下方表格复用“站点→订单集合”链接口径（避免硬编码/避免 merchant_id=1 命中 10 的误匹配）。
        var merchantIdToHref = {};
        try {
            var merchantLinks = document.querySelectorAll('[data-role="merchant-revenue-rank-7d"] a.link[href*="merchant_id="]');
            merchantLinks.forEach(function (a) {
                var href = String(a.getAttribute('href') || '');
                var m = href.match(/[?&]merchant_id=(\d+)/);
                if (!m) {
                    return;
                }
                merchantIdToHref[String(m[1])] = href;
            });
        } catch (e) {
            merchantIdToHref = {};
        }

        el.innerHTML = '';

        points.forEach(function (p, idx) {
            var paid = Number(p && p.paid_sum ? p.paid_sum : 0);
            var ratio = Math.max(0, Math.min(1, paid / max));

            var mid = Number(p && p.merchant_id != null ? p.merchant_id : 0);
            if (!isFinite(mid) || mid < 0) {
                mid = 0;
            }
            var href = merchantIdToHref[String(mid)] ? String(merchantIdToHref[String(mid)]) : '';

            var row = document.createElement(href ? 'a' : 'div');
            row.className = 'adm-mini-rank-row' + (href ? ' adm-mini-rank-row-link' : '');
            if (href) {
                row.setAttribute('href', href);
            }

            var name = document.createElement('div');
            name.className = 'adm-mini-rank-name';
            var mname = (p && p.name) ? String(p.name) : ('#' + (idx + 1));
            name.textContent = mname;
            // tooltip：显示完整名称（避免 ellipsis 后看不到）
            name.title = mname;

            var wrap = document.createElement('div');
            wrap.className = 'adm-mini-rank-bar-wrap';

            var bar = document.createElement('div');
            bar.className = 'adm-mini-rank-bar';
            bar.style.width = Math.round(ratio * 100) + '%';

            wrap.appendChild(bar);

            var val = document.createElement('div');
            val.className = 'adm-mini-rank-value';
            val.textContent = '¥' + formatMoney(paid);

            var cntText = String(p && p.count != null ? p.count : 0);
            row.title = 'Top' + (idx + 1) + '：' + mname + '｜已付 ¥' + formatMoney(paid) + '｜订单数 ' + cntText;

            row.appendChild(name);
            row.appendChild(wrap);
            row.appendChild(val);

            // a 标签：避免默认下划线影响视觉（由 CSS 控制）；并提升可访问性。
            if (href) {
                row.setAttribute('role', 'link');
                row.setAttribute('aria-label', '进入站点订单集合：' + mname);
            }

            el.appendChild(row);
        });
    })();



    // 仪表盘：最近平台订单（概览 mini bars）
    // 说明：让“最近订单列表”也纳入数据图形化体系，但保留明细扫描行。
    // 渐进增强：由 Blade 输出 data-points（label/count/href/tone），JS 渲染为可点击条目。
    (function(){
        var el = qs('[data-role="recent-platform-orders-mini-bars"][data-points]');
        if (!el) {
            return;
        }

        var raw = el.getAttribute('data-points') || '[]';
        var points = [];
        try {
            points = JSON.parse(raw) || [];
        } catch (e) {
            points = [];
        }

        var total = Number(el.getAttribute('data-total') || 0);
        if (!isFinite(total) || total < 0) {
            total = 0;
        }

        if (!points || points.length === 0) {
            el.classList.add('is-empty');
            el.textContent = '暂无最近订单概览';
            return;
        }

        // 视觉口径：按当前 points 内最大值归一（更易读）；tooltip 同时提供 count/占比。
        var max = 0;
        points.forEach(function(p){
            var c = Number(p && p.count != null ? p.count : 0);
            if (isFinite(c) && c > max) {
                max = c;
            }
        });
        if (!max || max <= 0) {
            max = 1;
        }

        function toneToGradient(tone){
            if (tone === 'danger') {
                return 'linear-gradient(90deg, rgba(239, 68, 68, .45), rgba(239, 68, 68, .14))';
            }
            if (tone === 'warn') {
                return 'linear-gradient(90deg, rgba(245, 158, 11, .45), rgba(245, 158, 11, .16))';
            }
            if (tone === 'success') {
                return 'linear-gradient(90deg, rgba(34, 197, 94, .40), rgba(34, 197, 94, .12))';
            }
            return 'linear-gradient(90deg, rgba(22, 119, 255, .35), rgba(22, 119, 255, .12))';
        }

        el.innerHTML = '';

        points.forEach(function(p, idx){
            var label = (p && p.label) ? String(p.label) : ('#' + String(idx + 1));
            var cnt = Number(p && p.count != null ? p.count : 0);
            if (!isFinite(cnt) || cnt < 0) {
                cnt = 0;
            }

            var href = (p && p.href) ? String(p.href) : '';
            var tone = (p && p.tone) ? String(p.tone) : '';

            var row = document.createElement(href ? 'a' : 'div');
            row.className = 'adm-mini-share-row' + (href ? ' adm-mini-share-row-link' : '');
            if (href) {
                row.setAttribute('href', href);
                row.setAttribute('role', 'link');
                row.setAttribute('aria-label', '进入最近订单集合：' + label);
            }

            var name = document.createElement('div');
            name.className = 'adm-mini-share-name';
            name.textContent = label;
            name.title = label;

            var wrap = document.createElement('div');
            wrap.className = 'adm-mini-share-bar-wrap';

            var bar = document.createElement('div');
            bar.className = 'adm-mini-share-bar';
            bar.style.width = Math.round(Math.max(0, Math.min(1, cnt / max)) * 100) + '%';
            bar.style.background = toneToGradient(tone);
            wrap.appendChild(bar);

            var val = document.createElement('div');
            val.className = 'adm-mini-share-value';
            val.textContent = String(cnt);

            var pct = (total > 0) ? (cnt / total) : 0;
            row.title = label + '｜' + String(cnt) + ' 单｜占比 ' + formatPct(pct, 1) + '%';

            row.appendChild(name);
            row.appendChild(wrap);
            row.appendChild(val);

            el.appendChild(row);
        });
    })();
    // 仪表盘：迷你占比（套餐订单占比 Top5）
    (function () {
        var el = qs('[data-role="plan-order-share-top5-chart"][data-points]');
        if (!el) {
            return;
        }

        var raw = el.getAttribute('data-points') || '[]';
        var points = [];
        try {
            points = JSON.parse(raw) || [];
        } catch (e) {
            points = [];
        }

        var total = Number(el.getAttribute('data-total') || 0);
        if (!total || total <= 0) {
            total = 0;
        }

        if (!points || points.length === 0 || total === 0) {
            el.classList.add('is-empty');
            el.textContent = '暂无占比数据';
            return;
        }

        // 渐进增强：从下方表格复用“套餐→订单集合”链接口径（避免硬编码 URL 规则）。
        var planIdToHref = {};
        try {
            var planLinks = document.querySelectorAll('[data-role="plan-order-share-top5"] a.link[href*="plan_id="]');
            planLinks.forEach(function (a) {
                var href = String(a.getAttribute('href') || '');
                var m = href.match(/[?&]plan_id=(\d+)/);
                if (!m) {
                    return;
                }
                planIdToHref[String(m[1])] = href;
            });
        } catch (e) {
            planIdToHref = {};
        }

        // 视觉口径：bar 宽度按 Top5 内最大值归一（更易读）；百分比仍按 total 分母计算。
        var maxCnt = 0;
        points.forEach(function (p) {
            var v = Number(p && p.count ? p.count : 0);
            if (v > maxCnt) {
                maxCnt = v;
            }
        });
        if (!maxCnt || maxCnt <= 0) {
            maxCnt = 1;
        }

        el.innerHTML = '';

        points.forEach(function (p, idx) {
            var cnt = Number(p && p.count ? p.count : 0);
            var ratio = total > 0 ? Math.max(0, Math.min(1, cnt / total)) : 0;
            var barRatio = maxCnt > 0 ? Math.max(0, Math.min(1, cnt / maxCnt)) : 0;

            var pid = Number(p && p.plan_id != null ? p.plan_id : 0);
            if (!isFinite(pid) || pid < 0) {
                pid = 0;
            }
            var href = planIdToHref[String(pid)] ? String(planIdToHref[String(pid)]) : '';

            var row = document.createElement(href ? 'a' : 'div');
            row.className = 'adm-mini-share-row' + (href ? ' adm-mini-share-row-link' : '');
            if (href) {
                row.setAttribute('href', href);
            }

            var name = document.createElement('div');
            name.className = 'adm-mini-share-name';
            var pname = (p && p.name) ? String(p.name) : ('#' + (idx + 1));
            name.textContent = pname;
            // tooltip：显示完整名称（避免 ellipsis 后看不到）
            name.title = pname;

            var wrap = document.createElement('div');
            wrap.className = 'adm-mini-share-bar-wrap';

            var bar = document.createElement('div');
            bar.className = 'adm-mini-share-bar';
            bar.style.width = Math.round(barRatio * 100) + '%';

            wrap.appendChild(bar);

            var val = document.createElement('div');
            val.className = 'adm-mini-share-value';
            val.textContent = formatPct(ratio, 1) + '%';

            row.title = 'Top' + (idx + 1) + '：' + pname + '｜' + cnt + ' 单｜占比 ' + formatPct(ratio, 1) + '%';

            row.appendChild(name);
            row.appendChild(wrap);
            row.appendChild(val);

            // a 标签：避免默认下划线影响视觉（由 CSS 控制）；并提升可访问性。
            if (href) {
                row.setAttribute('role', 'link');
                row.setAttribute('aria-label', '进入套餐订单集合：' + pname);
            }

            el.appendChild(row);
        });
    })();

    // 通用：将后端 flash 信息同步到 toast（更像 Ant Design Pro 的反馈方式）
    // 说明：渐进增强。页面仍保留原本的提示块，不依赖 JS。
    (function () {
        var container = qs('[data-role="toast-container"]');
        if (!container) {
            return;
        }

        var flashNodes = document.querySelectorAll('[data-flash]');
        if (!flashNodes || flashNodes.length === 0) {
            return;
        }

        function createToast(type, text) {
            var div = document.createElement('div');
            div.className = 'toast toast-' + type;
            div.setAttribute('role', 'status');

            var content = document.createElement('div');
            content.className = 'toast-content';
            content.textContent = text;

            var close = document.createElement('button');
            close.type = 'button';
            close.className = 'toast-close';
            close.textContent = '×';
            close.addEventListener('click', function () {
                try {
                    container.removeChild(div);
                } catch (e) {}
            });

            div.appendChild(content);
            div.appendChild(close);
            return div;
        }

        flashNodes.forEach(function (node) {
            var type = node.getAttribute('data-flash') || 'info';
            var text = (node.textContent || '').trim();
            if (!text) {
                return;
            }

            container.appendChild(createToast(type, text));
        });

        // 自动消失（success/warning），error 保留更久
        setTimeout(function () {
            try {
                var toasts = container.querySelectorAll('.toast');
                toasts.forEach(function (t) {
                    var cls = t.className || '';
                    var isError = cls.indexOf('toast-error') >= 0;
                    if (!isError) {
                        container.removeChild(t);
                    }
                });
            } catch (e) {}
        }, 4500);

        setTimeout(function () {
            try {
                var toasts = container.querySelectorAll('.toast');
                toasts.forEach(function (t) {
                    try {
                        container.removeChild(t);
                    } catch (e) {}
                });
            } catch (e) {}
        }, 9000);
    })();

    // 通用：复制到剪贴板（有权限限制/兼容降级）
    function copyToClipboard(text) {
        var t = String(text || '');
        if (!t) {
            return Promise.reject(new Error('empty'));
        }

        if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
            return navigator.clipboard.writeText(t);
        }

        return new Promise(function (resolve, reject) {
            try {
                var ta = document.createElement('textarea');
                ta.value = t;
                ta.setAttribute('readonly', 'readonly');
                ta.style.position = 'fixed';
                ta.style.top = '-1000px';
                ta.style.left = '-1000px';
                document.body.appendChild(ta);
                ta.select();
                var ok = document.execCommand('copy');
                document.body.removeChild(ta);
                ok ? resolve() : reject(new Error('copy_failed'));
            } catch (e) {
                reject(e);
            }
        });
    }

    function toast(type, text, ttlMs) {
        try {
            var container = qs('[data-role="toast-container"]');
            if (!container) {
                return false;
            }

            var t = document.createElement('div');
            t.className = 'toast toast-' + String(type || 'info');
            t.setAttribute('role', 'status');

            var c = document.createElement('div');
            c.className = 'toast-content';
            c.textContent = String(text || '');

            t.appendChild(c);
            container.appendChild(t);

            var ttl = Number(ttlMs || 2500);
            if (!isFinite(ttl) || ttl <= 0) {
                ttl = 2500;
            }

            setTimeout(function () {
                try {
                    container.removeChild(t);
                } catch (e) {}
            }, ttl);

            return true;
        } catch (e) {
            return false;
        }
    }

    function toastSuccess(text) {
        return toast('success', text, 2500);
    }

    function toastWarning(text) {
        return toast('warning', text, 4500);
    }

    function toastError(text) {
        // error 需要更久，避免运营错过
        return toast('error', text, 9000);
    }

    // 复制反馈文案统一口径（更像后台系统的短反馈，不塞超长 URL）
    function toastCopied(label, detail) {
        var l = String(label || '').trim();
        var d = String(detail || '').trim();
        var msg = '已复制';
        if (l) {
            msg += l;
        }
        if (d) {
            msg += '：' + d;
        }
        return toastSuccess(msg);
    }

    function toastCopyFailed(label, detail) {
        var l = String(label || '').trim();
        var d = String(detail || '').trim();
        var msg = '复制失败';
        if (l) {
            msg += '（' + l + '）';
        }
        if (d) {
            msg += '：' + d;
        }
        return toastError(msg);
    }

    // 通用：按钮短暂反馈（已复制/复制失败）并自动恢复
    // 说明：用于复制 run_id / 复制治理链接，避免两套口径漂移。
    function tempButtonFeedback(btn, ok, origAttr) {
        try {
            var key = String(origAttr || 'data-orig-text');

            var orig = btn.getAttribute(key);
            if (!orig) {
                orig = String(btn.textContent || '');
                btn.setAttribute(key, orig);
            }

            var nextText = ok ? '已复制' : '复制失败';
            btn.textContent = nextText;
            btn.disabled = true;

            setTimeout(function(){
                try {
                    btn.textContent = orig;
                    btn.disabled = false;
                } catch (e) {}
            }, 1200);
        } catch (e) {}
    }

    function markCopied(btn, ok) {
        // 兼容：保留函数名，供测试护栏与未来复用
        tempButtonFeedback(btn, ok, 'data-orig-text');
    }

    // 批次页：一键复制 run_id（渐进增强）
    (function(){
        var btn = qs('[data-action="copy-run-id"][data-run-id]');
        if(!btn){return;}

        function markCopiedRunId(ok){
            tempButtonFeedback(btn, ok, 'data-orig-text-run-id');
        }

        btn.addEventListener('click', function(){
            var runId = btn.getAttribute('data-run-id') || '';
            copyToClipboard(runId).then(function(){
                markCopiedRunId(true);
                // 成功反馈优先 toast；若 toast 不可用也无需 alert（按钮已提供“已复制”短反馈）。
                toastCopied('run_id', runId);
            }).catch(function(){
                markCopiedRunId(false);
                if (toastCopyFailed('run_id', '请手动复制：' + runId)) {
                    return;
                }
                try { window.alert('复制失败，请手动复制 run_id：' + runId); } catch (e) {}
            });
        });
    })();

    function absoluteUrl(href) {
        var h = String(href || '');
        if (!h) {
            return '';
        }
        // 已是绝对链接
        if (h.indexOf('http://') === 0 || h.indexOf('https://') === 0) {
            return h;
        }
        // 仅将站内相对路径补齐为绝对链接
        if (h.indexOf('/') === 0 && window.location && window.location.origin) {
            return String(window.location.origin) + h;
        }
        return h;
    }

    // 批次页：一键复制治理集合链接（例如：本批次失败 / 按Top原因）
    (function(){
        var btns = document.querySelectorAll('[data-action="copy-link"][data-href]');
        if(!btns || btns.length === 0){return;}

        btns.forEach(function(btn){
            btn.addEventListener('click', function(){
                var href = btn.getAttribute('data-href') || '';
                var label = btn.getAttribute('data-label') || '链接';

                var abs = absoluteUrl(href);
                copyToClipboard(abs).then(function(){
                    markCopied(btn, true);
                    // 成功反馈优先 toast；若 toast 不可用也无需 alert（按钮已提供“已复制”短反馈）。
                    toastCopied(label + '链接', '');
                }).catch(function(){
                    markCopied(btn, false);
                    if (toastCopyFailed(label + '链接', '请手动复制')) {
                        return;
                    }
                    try { window.alert('复制失败，请手动复制' + label + '链接'); } catch (e) {}
                });
            });
        });
    })();

    // 通用：复制任意文本（用于 flash 提示中的“复制run_id”等）
    (function(){
        var btns = document.querySelectorAll('[data-action="copy-text"][data-copy-text]');
        if(!btns || btns.length === 0){return;}

        btns.forEach(function(btn){
            btn.addEventListener('click', function(){
                var text = btn.getAttribute('data-copy-text') || '';
                var label = btn.getAttribute('data-copy-label') || '文本';

                copyToClipboard(text).then(function(){
                    markCopied(btn, true);
                    toastCopied(label, text);
                }).catch(function(){
                    markCopied(btn, false);
                    if (toastCopyFailed(label, '请手动复制：' + text)) {
                        return;
                    }
                    try { window.alert('复制失败，请手动复制：' + text); } catch (e) {}
                });
            });
        });
    })();

    // 续费缺订阅治理：订单详情页“绑定订阅ID”输入框，小交互增强：
    // - 输入后按 Enter 直接提交
    // - 自动聚焦，减少点击
    var attachInput = qs('#attach_site_subscription_id');
    if (attachInput) {
        try {
            attachInput.focus();
        } catch (e) {}

        attachInput.addEventListener('keydown', function (e) {
            if (e && (e.key === 'Enter' || e.keyCode === 13)) {
                var form = attachInput.form;
                if (form) {
                    e.preventDefault();
                    form.submit();
                }
            }
        });
    }
})();
