"use client";
'use strict';

var tslib_es6 = require('../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.3/node_modules/tslib/tslib.es6.js');
var jsxRuntime = require('react/jsx-runtime');
var server = require('@windrun-huaiin/base-ui/components/server');
var lib = require('@windrun-huaiin/base-ui/lib');
var utils = require('@windrun-huaiin/lib/utils');
var React = require('react');
var useFingerprint = require('./use-fingerprint.js');
var ui = require('@windrun-huaiin/base-ui/ui');
var fingerprintClient = require('./fingerprint-client.js');
var fingerprintDebug = require('./fingerprint-debug.js');
var fingerprintShared = require('./fingerprint-shared.js');

const FingerprintContext = React.createContext(undefined);
/**
 * Fingerprint Provider Component
 * 为应用提供fingerprint和匿名用户管理功能
 */
function FingerprintProvider({ children, config }) {
    const fingerprintData = useFingerprint.useFingerprint(config);
    return (jsxRuntime.jsx(FingerprintContext.Provider, { value: fingerprintData, children: children }));
}
/**
 * Hook to use fingerprint context
 */
function useFingerprintContext() {
    const context = React.useContext(FingerprintContext);
    if (context === undefined) {
        throw new Error('useFingerprintContext must be used within a FingerprintProvider');
    }
    return context;
}
/**
 * Safe hook to use fingerprint context - returns null if no provider
 * 安全版本的fingerprint context hook - 如果没有Provider则返回null
 */
function useFingerprintContextSafe() {
    const context = React.useContext(FingerprintContext);
    return context || null;
}
/**
 * HOC for components that need fingerprint functionality
 * Note: This HOC now requires config to be passed externally
 */
function withFingerprint(Component, config) {
    return function FingerprintWrappedComponent(props) {
        return (jsxRuntime.jsx(FingerprintProvider, { config: config, children: jsxRuntime.jsx(Component, Object.assign({}, props)) }));
    };
}
/**
 * 组件：显示用户状态和积分信息（用于调试）
 */
function FingerprintStatus() {
    const { fingerprintId, xUser, xCredit, xSubscription, error, clearError, } = useFingerprintContext();
    const [isOpen, setIsOpen] = React.useState(false);
    const [panelMode, setPanelMode] = React.useState('info');
    const [testResult, setTestResult] = React.useState('');
    const [isRunningTest, setIsRunningTest] = React.useState(false);
    const modalRef = React.useRef(null);
    const isInitializingDebugAnonymousUserRef = React.useRef(false);
    const [activeDebugFingerprintId, setActiveDebugFingerprintId] = React.useState(null);
    const handleToggle = () => setIsOpen(prev => !prev);
    const handleBackdropClick = (e) => {
        if (e.target === e.currentTarget)
            setIsOpen(false);
    };
    React.useEffect(() => {
        const handleEscKey = (e) => {
            if (e.key === 'Escape' && isOpen)
                setIsOpen(false);
        };
        if (isOpen)
            document.addEventListener('keydown', handleEscKey);
        return () => document.removeEventListener('keydown', handleEscKey);
    }, [isOpen]);
    React.useEffect(() => {
        if (xUser && !xUser.fingerprintId) {
            console.warn('xUser.fingerprintId is missing:', xUser);
        }
    }, [xUser]);
    React.useEffect(() => {
        const debugFingerprintOverride = fingerprintDebug.getDebugFingerprintOverride();
        if (debugFingerprintOverride) {
            setActiveDebugFingerprintId(debugFingerprintOverride);
            return;
        }
        const nextFingerprintId = buildDebugFingerprintId();
        fingerprintDebug.setDebugFingerprintOverride(nextFingerprintId);
        setActiveDebugFingerprintId(nextFingerprintId);
    }, []);
    const creditBuckets = React.useMemo(() => {
        if (!xCredit)
            return [];
        return [
            {
                key: 'paid',
                label: 'Paid',
                icon: jsxRuntime.jsx(server.globalLucideIcons.Settings2, { className: "size-4 text-green-500 dark:text-green-300" }),
                balance: xCredit.balancePaid,
                total: xCredit.totalPaidLimit,
                start: xCredit.paidStart,
                end: xCredit.paidEnd,
            },
            {
                key: 'oneTimePaid',
                label: 'OneTimePaid',
                icon: jsxRuntime.jsx(server.globalLucideIcons.Coins, { className: "size-4 text-amber-500 dark:text-amber-300" }),
                balance: xCredit.balanceOneTimePaid,
                total: xCredit.totalOneTimePaidLimit,
                start: xCredit.oneTimePaidStart,
                end: xCredit.oneTimePaidEnd,
            },
            {
                key: 'free',
                label: 'Free',
                icon: jsxRuntime.jsx(server.globalLucideIcons.Gift, { className: "size-4 text-purple-500 dark:text-purple-300" }),
                balance: xCredit.balanceFree,
                total: xCredit.totalFreeLimit,
                start: xCredit.freeStart,
                end: xCredit.freeEnd,
            },
        ];
    }, [xCredit]);
    const subscriptionStatus = React.useMemo(() => {
        var _a, _b;
        if (!xSubscription) {
            return {
                status: 'Never',
                priceName: '--',
                creditsAllocated: '--',
                period: 'Unavailable',
            };
        }
        return {
            status: (_a = xSubscription.status) !== null && _a !== void 0 ? _a : '--',
            priceName: (_b = xSubscription.priceName) !== null && _b !== void 0 ? _b : '--',
            creditsAllocated: typeof xSubscription.creditsAllocated === 'number'
                ? formatNumber(xSubscription.creditsAllocated)
                : '--',
            period: formatRangeText(xSubscription.subPeriodStart, xSubscription.subPeriodEnd),
        };
    }, [xSubscription]);
    const userStatus = (xUser === null || xUser === void 0 ? void 0 : xUser.status) || '--';
    const totalCredits = formatNumber(xCredit === null || xCredit === void 0 ? void 0 : xCredit.totalBalance);
    const subStatus = subscriptionStatus.status;
    const themedGhostButtonClass = utils.cn('border-slate-200 bg-white/90 hover:bg-slate-50 dark:border-white/10 dark:bg-slate-950/80 dark:hover:bg-slate-900', 'hover:border-current', lib.themeIconColor);
    const runContextParallelInitTest = () => tslib_es6.__awaiter(this, void 0, void 0, function* () {
        const debugFingerprintId = activeDebugFingerprintId;
        if (!debugFingerprintId) {
            setTestResult('Test fingerprint override is not ready yet.');
            return;
        }
        setIsRunningTest(true);
        setTestResult(`Running Frontend Prevention Test with fingerprint: ${debugFingerprintId}`);
        try {
            yield Promise.all([
                initializeDebugAnonymousUser(debugFingerprintId),
                initializeDebugAnonymousUser(debugFingerprintId),
                initializeDebugAnonymousUser(debugFingerprintId),
            ]);
            setTestResult(`Frontend Prevention Test finished. Active test fingerprint: ${debugFingerprintId}`);
        }
        catch (testError) {
            setTestResult(`Frontend Prevention Test failed: ${formatErrorMessage(testError)}`);
        }
        finally {
            setIsRunningTest(false);
        }
    });
    const initializeDebugAnonymousUser = (debugFingerprintId) => tslib_es6.__awaiter(this, void 0, void 0, function* () {
        if (isInitializingDebugAnonymousUserRef.current) {
            return;
        }
        try {
            isInitializingDebugAnonymousUserRef.current = true;
            const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
            const response = yield fetch('/api/user/anonymous/init', {
                method: 'POST',
                headers: Object.assign(Object.assign({ 'Content-Type': 'application/json', [fingerprintShared.FINGERPRINT_SOURCE_REFER]: document.referrer || '' }, fingerprintHeaders), { 'x-fingerprint-id-v8': debugFingerprintId }),
                body: JSON.stringify({ fingerprintId: debugFingerprintId }),
            });
            if (!response.ok) {
                const errorData = yield response.json().catch(() => ({}));
                throw new Error(errorData.error || 'Failed to initialize anonymous user');
            }
            yield response.json().catch(() => ({}));
        }
        finally {
            isInitializingDebugAnonymousUserRef.current = false;
        }
    });
    const runRawParallelPostTest = () => tslib_es6.__awaiter(this, void 0, void 0, function* () {
        const normalizedFingerprintId = activeDebugFingerprintId;
        if (!normalizedFingerprintId) {
            setTestResult('Test fingerprint override is not ready yet.');
            return;
        }
        setIsRunningTest(true);
        setTestResult(`Running Backend Idempotency Test with fingerprint: ${normalizedFingerprintId}`);
        try {
            const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
            const requests = Array.from({ length: 3 }, () => fetch('/api/user/anonymous/init', {
                method: 'POST',
                headers: Object.assign(Object.assign({ 'Content-Type': 'application/json', [fingerprintShared.FINGERPRINT_SOURCE_REFER]: document.referrer || '' }, fingerprintHeaders), { 'x-fingerprint-id-v8': normalizedFingerprintId }),
                body: JSON.stringify({ fingerprintId: normalizedFingerprintId }),
            }));
            const responses = yield Promise.all(requests);
            const payloads = yield Promise.all(responses.map((response) => tslib_es6.__awaiter(this, void 0, void 0, function* () {
                var _a, _b;
                const data = yield response.json().catch(() => ({}));
                return {
                    ok: response.ok,
                    status: response.status,
                    isNewUser: typeof (data === null || data === void 0 ? void 0 : data.isNewUser) === 'boolean' ? data.isNewUser : null,
                    userId: typeof ((_a = data === null || data === void 0 ? void 0 : data.xUser) === null || _a === void 0 ? void 0 : _a.userId) === 'string' ? data.xUser.userId : '--',
                    fingerprintId: typeof ((_b = data === null || data === void 0 ? void 0 : data.xUser) === null || _b === void 0 ? void 0 : _b.fingerprintId) === 'string' ? data.xUser.fingerprintId : normalizedFingerprintId,
                    error: typeof (data === null || data === void 0 ? void 0 : data.error) === 'string' ? data.error : null,
                };
            })));
            const createdUserIds = payloads
                .filter((payload) => payload.ok && payload.isNewUser === true && payload.userId !== '--')
                .map((payload) => payload.userId);
            const reusedUserIds = payloads
                .filter((payload) => payload.ok && payload.isNewUser === false && payload.userId !== '--')
                .map((payload) => payload.userId);
            const failedStatuses = payloads
                .filter((payload) => !payload.ok)
                .map((payload) => `${payload.status}${payload.error ? `:${payload.error}` : ''}`);
            setTestResult([
                `Backend Idempotency Test done.`,
                `created=${createdUserIds.length}`,
                `reused=${reusedUserIds.length}`,
                `failed=${failedStatuses.length}`,
                `createdUserIds=[${createdUserIds.join(', ')}]`,
                failedStatuses.length > 0 ? `failedStatuses=[${failedStatuses.join(', ')}]` : null,
            ].filter(Boolean).join('\n'));
        }
        catch (testError) {
            setTestResult(`Backend Idempotency Test failed: ${formatErrorMessage(testError)}`);
        }
        finally {
            setIsRunningTest(false);
        }
    });
    const regenerateTestFingerprint = () => {
        const nextFingerprintId = buildDebugFingerprintId();
        fingerprintDebug.setDebugFingerprintOverride(nextFingerprintId);
        setActiveDebugFingerprintId(nextFingerprintId);
        setTestResult(`Generated test fingerprint override: ${nextFingerprintId}`);
    };
    return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [!isOpen && (jsxRuntime.jsx("button", { onClick: handleToggle, type: "button", "aria-label": "Fingerprint debug panel", className: utils.cn('fixed left-2 top-2 md:left-2 md:top-3 z-10000 inline-flex size-8 md:size-11 items-center justify-center rounded-full', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass, 'text-white rounded-full shadow-lg hover:shadow-xl transition-all duration-300'), children: jsxRuntime.jsx(server.globalLucideIcons.Lightbulb, { className: "size-6 text-white" }) })), isOpen && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { onClick: handleBackdropClick, className: "fixed inset-0 z-9998 bg-black/60 backdrop-blur-sm" }), jsxRuntime.jsxs("div", { ref: modalRef, className: utils.cn('fixed inset-3 z-9999 mx-auto w-[min(95vw,520px)] overflow-y-auto rounded-2xl border', 'border-slate-200/70 bg-white/95 p-4 shadow-2xl backdrop-blur-sm', 'font-sans text-sm text-slate-700 dark:border-white/12 dark:bg-slate-950/95 dark:text-slate-200', 'sm:inset-auto md:left-2 sm:top-1 md:right-auto sm:w-[min(520px,95vw)] sm:p-5'), children: [jsxRuntime.jsx("header", { className: "mb-4", children: jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3", children: [jsxRuntime.jsxs("div", { className: utils.cn("flex items-center gap-2 text-base font-bold tracking-wider", lib.themeIconColor), children: [jsxRuntime.jsx(server.globalLucideIcons.ShieldUser, { className: "size-4" }), "Fingerprint Debug Panel"] }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [jsxRuntime.jsxs("button", { type: "button", onClick: () => setPanelMode((prev) => prev === 'info' ? 'test' : 'info'), className: utils.cn('inline-flex items-center gap-2 rounded-full border px-2 py-1 text-[11px] font-semibold shadow-sm transition-all duration-200', panelMode === 'test'
                                                        ? utils.cn('border-transparent text-white', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass)
                                                        : themedGhostButtonClass), "aria-pressed": panelMode === 'test', children: [jsxRuntime.jsx("span", { children: "Concurrent Test" }), jsxRuntime.jsx("span", { className: utils.cn('relative inline-flex h-5 w-9 items-center rounded-full transition-colors', panelMode === 'test'
                                                                ? 'bg-white/25'
                                                                : 'bg-slate-300 dark:bg-slate-700'), children: jsxRuntime.jsx("span", { className: utils.cn('inline-block size-4 rounded-full shadow-sm transition-transform', panelMode === 'test' ? 'bg-white' : 'bg-white dark:bg-slate-100', panelMode === 'test' ? 'translate-x-4' : 'translate-x-0.5') }) })] }), jsxRuntime.jsx("button", { type: "button", "aria-label": "Close fingerprint panel", className: "rounded-full p-2 text-slate-500 transition hover:bg-slate-100 hover:text-slate-700 dark:text-slate-300 dark:hover:bg-white/10 dark:hover:text-white", onClick: () => setIsOpen(false), children: jsxRuntime.jsx(server.globalLucideIcons.X, { className: "size-4" }) })] })] }) }), jsxRuntime.jsxs("section", { className: "space-y-1", children: [panelMode === 'info' ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(PanelSection, { icon: jsxRuntime.jsx(server.globalLucideIcons.Fingerprint, { className: "size-4" }), title: "User", rightInfo: jsxRuntime.jsx(StatusTag, { value: userStatus }), items: [
                                                    { label: 'UserID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.userId) || '' }) },
                                                    { label: 'NickName', value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.userName) || '' }) },
                                                    { label: 'FingerprintID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.fingerprintId) || fingerprintId || '' }) },
                                                    { label: 'ClerkUserID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.clerkUserId) || '' }) },
                                                    { label: 'Email', value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.email) || '' }) },
                                                    { label: 'StripeCusID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xUser === null || xUser === void 0 ? void 0 : xUser.stripeCusId) || '' }) },
                                                    { label: 'CreatedAt', value: (xUser === null || xUser === void 0 ? void 0 : xUser.createdAt) || '--' },
                                                ] }), jsxRuntime.jsxs("div", { className: "space-y-2 rounded-xl border border-slate-200/70 bg-white/80 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/50", children: [jsxRuntime.jsx(PanelHeader, { icon: jsxRuntime.jsx(server.globalLucideIcons.Gem, { className: "size-4" }), title: "Credits Info", rightInfo: jsxRuntime.jsx("span", { className: utils.cn("font-semibold", lib.themeIconColor), children: totalCredits }) }), jsxRuntime.jsx("div", { className: "space-y-3", children: creditBuckets.length > 0 ? (creditBuckets.map((bucket) => {
                                                            const percent = Math.round(computeProgress(bucket.balance, bucket.total) * 100);
                                                            return (jsxRuntime.jsxs("div", { className: "rounded-lg border border-slate-200/70 bg-white/70 p-3 dark:border-white/10 dark:bg-slate-900/40", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between text-xs font-medium text-slate-600 dark:text-slate-300", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [bucket.icon, jsxRuntime.jsx("span", { children: bucket.label })] }), jsxRuntime.jsxs("span", { className: "font-semibold text-slate-700 dark:text-slate-100", children: [formatNumber(bucket.balance), " / ", formatNumber(bucket.total)] })] }), jsxRuntime.jsx("div", { className: "mt-2 h-1.5 w-full rounded-full bg-slate-200 dark:bg-slate-800", children: jsxRuntime.jsx("div", { className: "h-full rounded-full bg-linear-to-r from-purple-500 via-pink-500 to-rose-400 transition-[width]", style: { width: `${percent}%` } }) }), jsxRuntime.jsxs("div", { className: "mt-2 flex items-center justify-between text-[11px] text-slate-500 dark:text-slate-400", children: [jsxRuntime.jsx("span", { children: formatRangeText(bucket.start, bucket.end) }), jsxRuntime.jsxs("span", { children: [percent, "%"] })] })] }, bucket.key));
                                                        })) : (jsxRuntime.jsx(EmptyPlaceholder, { label: "No Credits Yet", icon: jsxRuntime.jsx(server.globalLucideIcons.DatabaseZap, { className: "size-4" }) })) })] }), jsxRuntime.jsx(PanelSection, { icon: jsxRuntime.jsx(server.globalLucideIcons.Bell, { className: "size-4" }), title: "Subscription", rightInfo: jsxRuntime.jsx(StatusTag, { value: subStatus }), items: [
                                                    { label: 'Plan', value: subscriptionStatus.priceName },
                                                    { label: 'Period', value: subscriptionStatus.period },
                                                    { label: 'Allocated', value: subscriptionStatus.creditsAllocated },
                                                    { label: 'SubID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.paySubscriptionId) || '' }) },
                                                    { label: 'OrderID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.orderId) || '' }) },
                                                    { label: 'PriceID', value: jsxRuntime.jsx(ui.CopyableText, { text: (xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.priceId) || '' }) },
                                                ] })] })) : (jsxRuntime.jsxs("div", { className: "space-y-3 rounded-xl border border-slate-200/70 bg-white/85 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/45", children: [jsxRuntime.jsx(PanelHeader, { icon: jsxRuntime.jsx(server.globalLucideIcons.DatabaseZap, { className: "size-4" }), title: "Concurrent Base Info", rightInfo: jsxRuntime.jsx(StatusTag, { value: isRunningTest ? 'pending' : 'idle' }) }), jsxRuntime.jsxs("div", { className: "space-y-2 text-xs text-slate-500 dark:text-slate-300", children: [jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntime.jsx("span", { className: "text-slate-400 dark:text-slate-500", children: "Real Browser" }), jsxRuntime.jsx(ui.CopyableText, { text: fingerprintId || '' })] }), jsxRuntime.jsxs("div", { className: "space-y-1", children: [jsxRuntime.jsx("span", { className: "text-slate-400 dark:text-slate-500", children: "Test Override" }), jsxRuntime.jsxs("div", { className: "flex items-center gap-2 py-1", children: [jsxRuntime.jsx("div", { className: "min-w-0 flex-1 rounded-lg border border-slate-200 bg-white px-3 py-2 font-mono text-[0.5rem] sm:text-[0.625rem] md:text-xs leading-tight text-slate-700 dark:border-white/10 dark:bg-slate-950 dark:text-slate-100", children: jsxRuntime.jsx(ui.CopyableText, { text: activeDebugFingerprintId || '' }) }), jsxRuntime.jsx("button", { type: "button", disabled: isRunningTest, onClick: regenerateTestFingerprint, "aria-label": "Generate new test fingerprint", className: "inline-flex size-9 items-center justify-center rounded-lg border border-slate-200 bg-slate-50 text-slate-700 transition hover:border-slate-300 hover:bg-slate-100 disabled:cursor-not-allowed disabled:opacity-50 dark:border-white/10 dark:bg-slate-950 dark:text-slate-100 dark:hover:bg-slate-900", children: jsxRuntime.jsx(server.globalLucideIcons.RefreshCcw, { className: "size-4" }) })] })] })] }), jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: [jsxRuntime.jsx("button", { type: "button", disabled: isRunningTest, onClick: runContextParallelInitTest, className: utils.cn('shrink-0 rounded-full border px-3 py-2 text-xs font-semibold transition-all duration-200 disabled:cursor-not-allowed disabled:opacity-50', themedGhostButtonClass), children: "Frontend Prevention Test" }), jsxRuntime.jsx("button", { type: "button", disabled: isRunningTest, onClick: runRawParallelPostTest, className: utils.cn('shrink-0 rounded-full border px-3 py-2 text-xs font-semibold text-white shadow-sm transition-all duration-200 disabled:cursor-not-allowed disabled:opacity-50', 'border-transparent', lib.themeButtonGradientClass, lib.themeButtonGradientHoverClass), children: "Backend Idempotency Test" })] }), jsxRuntime.jsx("div", { className: "rounded-lg border border-dashed border-slate-200 bg-slate-50/80 p-3 dark:border-white/10 dark:bg-slate-950/50", children: jsxRuntime.jsx("pre", { className: "overflow-x-auto whitespace-pre-wrap break-all font-mono text-[11px] leading-5 text-slate-600 dark:text-slate-300", children: testResult || 'No test executed yet.' }) })] })), error && (jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-3 rounded-xl border border-amber-200 bg-amber-50 p-3 text-xs text-amber-600 shadow-sm dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-200", children: [jsxRuntime.jsxs("div", { className: "flex items-start gap-2", children: [jsxRuntime.jsx(server.globalLucideIcons.X, { className: "mt-0.5 size-4 shrink-0" }), jsxRuntime.jsx("span", { children: error })] }), jsxRuntime.jsx("button", { type: "button", "aria-label": "Dismiss error", onClick: clearError, className: "shrink-0 rounded-full p-1 text-amber-500 transition hover:bg-amber-100 hover:text-amber-700 dark:text-amber-200 dark:hover:bg-amber-500/10 dark:hover:text-amber-100", children: jsxRuntime.jsx(server.globalLucideIcons.X, { className: "size-4" }) })] }))] })] })] }))] }));
}
/* ==================== 新增辅助组件 ==================== */
// 标题行：左侧图标+标题，右侧信息（右对齐）
function PanelHeader({ icon, title, rightInfo }) {
    return (jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-3", children: [jsxRuntime.jsxs("div", { className: "flex items-center gap-2 text-sm font-semibold text-slate-700 dark:text-slate-100", children: [jsxRuntime.jsx("span", { className: "flex size-6 items-center justify-center rounded-full bg-slate-100 text-slate-600 dark:bg-slate-800 dark:text-slate-300", children: icon }), jsxRuntime.jsx("span", { className: utils.cn("rounded-full bg-purple-100 px-2 py-1 text-xs font-bold", lib.themeIconColor), children: title })] }), jsxRuntime.jsx("span", { className: "text-sm font-medium text-slate-600 dark:text-slate-300", children: rightInfo })] }));
}
function PanelSection({ icon, title, rightInfo, items }) {
    return (jsxRuntime.jsxs("div", { className: "rounded-xl border border-slate-200/70 bg-white/85 p-4 shadow-sm dark:border-white/12 dark:bg-slate-900/45", children: [jsxRuntime.jsx(PanelHeader, { icon: icon, title: title, rightInfo: rightInfo }), jsxRuntime.jsx("dl", { className: "grid grid-cols-1 gap-y-1.5 text-xs text-slate-500 dark:text-slate-300", children: items.map((item) => (jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [jsxRuntime.jsx("dt", { className: "text-slate-400 dark:text-slate-500", children: item.label }), jsxRuntime.jsx("dd", { className: "text-right font-medium text-slate-600 dark:text-slate-100", children: item.value })] }, item.label))) })] }));
}
function EmptyPlaceholder({ label, icon }) {
    return (jsxRuntime.jsxs("div", { className: "flex items-center justify-center gap-2 rounded-lg border border-dashed border-slate-200 bg-slate-50 py-6 text-xs text-slate-400 dark:border-white/10 dark:bg-slate-900/30 dark:text-slate-500", children: [icon, jsxRuntime.jsx("span", { children: label })] }));
}
function formatNumber(value) {
    if (typeof value !== 'number' || Number.isNaN(value))
        return '--';
    return new Intl.NumberFormat('zh-CN', { maximumFractionDigits: 0 }).format(value);
}
function computeProgress(balance, total) {
    if (typeof balance !== 'number' || typeof total !== 'number' || Number.isNaN(balance) || Number.isNaN(total) || total <= 0) {
        return 0;
    }
    const ratio = balance / total;
    if (!Number.isFinite(ratio))
        return 0;
    return Math.min(Math.max(ratio, 0), 1);
}
function formatRangeText(start, end) {
    const safeStart = start && start.trim() ? start : '';
    const safeEnd = end && end.trim() ? end : '';
    if (!safeStart && !safeEnd) {
        return 'No records';
    }
    if (!safeStart) {
        return safeEnd;
    }
    if (!safeEnd) {
        return safeStart;
    }
    return `${safeStart} - ${safeEnd}`;
}
function StatusTag({ value }) {
    if (!value)
        return jsxRuntime.jsx("span", { className: "text-slate-400", children: "None" });
    const normalized = value.toLowerCase();
    const colorMap = {
        // 绿色：正常/活跃
        registered: 'bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-300',
        active: 'bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-300',
        trialing: 'bg-green-100 text-green-700 dark:bg-green-500/20 dark:text-green-300',
        // 灰色：失效/删除
        canceled: 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-400',
        frozen: 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-400',
        deleted: 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-400',
        expired: 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-400',
        past_due: 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-400',
        // 橙色：待处理/异常
        pending: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-300',
        failed: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-300',
        unpaid: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-300',
        incomplete: 'bg-amber-100 text-amber-700 dark:bg-amber-500/20 dark:text-amber-300',
    };
    const defaultColor = 'bg-slate-100 text-slate-600 dark:bg-slate-700 dark:text-slate-400';
    const badgeClass = colorMap[normalized] || defaultColor;
    return (jsxRuntime.jsx("span", { className: utils.cn('inline-block rounded-full px-2 py-0.5 text-xs capitalize font-medium', badgeClass), children: value }));
}
function buildDebugFingerprintId() {
    const timestamp = new Date().toISOString().replace(/[-:TZ.]/g, '').slice(0, 14);
    const randomSuffix = Math.random().toString(36).slice(2, 8);
    return `fp_test_dbg_${timestamp}_${randomSuffix}`;
}
function formatErrorMessage(error) {
    if (error instanceof Error) {
        return error.message;
    }
    if (typeof error === 'string') {
        return error;
    }
    return 'Unknown error';
}

exports.FingerprintProvider = FingerprintProvider;
exports.FingerprintStatus = FingerprintStatus;
exports.useFingerprintContext = useFingerprintContext;
exports.useFingerprintContextSafe = useFingerprintContextSafe;
exports.withFingerprint = withFingerprint;
