// 浏览器端函数调用链追踪功能
// 使用方法：在HTML页面中引入此文件，然后调用相关函数

// 全局调用链追踪状态
const callChain = [];
// 自动追踪状态
const autoTracking = {
    enabled: false,
    activeFunctions: new Map(), // functionId -> {startTime, functionName, location, caller}
    functionCounter: 0
};

// 函数调用链追踪功能
function createTrackedFunction(fn, functionName) {
    return function (...args) {
        const startTime = Date.now();
        const stack = new Error().stack;
        const stackLines = stack?.split('\n').slice(2) || [];

        // 解析当前函数信息
        const currentFn = parseStackLine(stackLines[0] || '');
        const actualFnName = functionName || currentFn.functionName;

        // 查找调用者信息
        let callerInfo = null;
        for (let i = 1; i < stackLines.length && i < 10; i++) {
            const caller = parseStackLine(stackLines[i]);
            if (!caller.functionName.includes('createTrackedFunction') &&
                !caller.functionName.includes('trackedCall')) {
                callerInfo = caller;
                break;
            }
        }

        // 记录进入函数
        const chainEntry = {
            functionName: actualFnName,
            timestamp: startTime,
            file: currentFn.file,
            line: currentFn.line,
            column: currentFn.column,
            caller: callerInfo ? {
                functionName: callerInfo.functionName,
                file: callerInfo.file,
                line: callerInfo.line
            } : undefined
        };
        callChain.push(chainEntry);

        // 发送函数进入日志
        if (window.logSender) {
            window.logSender.customLog('trace', {
                type: 'function_call',
                action: 'enter',
                functionName: actualFnName,
                timestamp: startTime,
                location: {
                    file: currentFn.file,
                    line: currentFn.line,
                    column: currentFn.column
                },
                caller: callerInfo ? {
                    functionName: callerInfo.functionName,
                    location: {
                        file: callerInfo.file,
                        line: callerInfo.line
                    }
                } : undefined,
                callDepth: callChain.length,
                args: args.length > 0 ? args.map(arg => {
                    try {
                        return typeof arg === 'object' ? JSON.stringify(arg) : String(arg);
                    } catch {
                        return '[Circular or Non-serializable]';
                    }
                }) : undefined
            });
        }

        try {
            const result = fn.apply(this, args);

            // 如果返回Promise，处理异步调用
            if (result && typeof result.then === 'function') {
                return result.then((resolvedValue) => {
                    const endTime = Date.now();
                    const duration = endTime - startTime;

                    // 移除调用链记录
                    callChain.pop();

                    // 发送异步函数返回日志
                    if (window.logSender) {
                        window.logSender.customLog('trace', {
                            type: 'function_call',
                            action: 'exit',
                            functionName: actualFnName,
                            timestamp: endTime,
                            duration,
                            result: {
                                type: 'resolved',
                                value: typeof resolvedValue === 'object' ? JSON.stringify(resolvedValue) : String(resolvedValue)
                            },
                            callDepth: callChain.length
                        });
                    }

                    return resolvedValue;
                }).catch((error) => {
                    const endTime = Date.now();
                    const duration = endTime - startTime;

                    // 移除调用链记录
                    callChain.pop();

                    // 发送异步函数错误日志
                    if (window.logSender) {
                        window.logSender.customLog('error', {
                            type: 'function_call',
                            action: 'error',
                            functionName: actualFnName,
                            timestamp: endTime,
                            duration,
                            error: {
                                message: error.message,
                                stack: error.stack
                            },
                            callDepth: callChain.length
                        });
                    }

                    throw error;
                });
            } else {
                // 同步函数返回
                const endTime = Date.now();
                const duration = endTime - startTime;

                // 移除调用链记录
                callChain.pop();

                // 发送同步函数返回日志
                if (window.logSender) {
                    window.logSender.customLog('trace', {
                        type: 'function_call',
                        action: 'exit',
                        functionName: actualFnName,
                        timestamp: endTime,
                        duration,
                        result: {
                            type: 'sync',
                            value: typeof result === 'object' ? JSON.stringify(result) : String(result)
                        },
                        callDepth: callChain.length
                    });
                }

                return result;
            }
        } catch (error) {
            const endTime = Date.now();
            const duration = endTime - startTime;

            // 移除调用链记录
            callChain.pop();

            // 发送同步函数错误日志
            if (window.logSender) {
                window.logSender.customLog('error', {
                    type: 'function_call',
                    action: 'error',
                    functionName: actualFnName,
                    timestamp: endTime,
                    duration,
                    error: {
                        message: error.message,
                        stack: error.stack
                    },
                    callDepth: callChain.length
                });
            }

            throw error;
        }
    };
}

// 解析调用栈信息
// 0: "install/console.log@file:///Users/cloud/develop/webhook-serverless/lib/browser-index.js:110:38"
// ​
// 1: "install/console.log@file:///Users/cloud/develop/webhook-serverless/lib/browser-index.js:110:38"
// ​
// 2: "processUserData@file:///Users/cloud/develop/webhook-serverless/browser-call-chain-demo.html?ddd:192:25"
// ​
// 3: "testFunctionTracking@file:///Users/cloud/develop/webhook-serverless/browser-call-chain-demo.html?ddd:208:54"
// ​
// 4: "onclick@file:///Users/cloud/develop/webhook-serverless/browser-call-chain-demo.html?ddd:1:1"
function parseStackLine(stackLine) {
    stackLine = 'testSimpleAutoTracking@file:///Users/cloud/develop/webhook-serverless/browser-call-chain-demo.html?ddd:225:21'
    // 清理输入：移除可能的行号前缀（如 "3: "）
    const cleanLine = stackLine.replace(/^\d+:\s*/, '').trim();

    // 匹配Mozilla/Firefox格式: functionName@file:line:column
    // 示例: "testFunctionTracking@file:///Users/cloud/develop/webhook-serverless/browser-call-chain-demo.html?ddd:208:54"
    const mozillaMatch = cleanLine.match(/^([^@]*)@(.+?):(\d+):(\d+)$/); // 匹配 "functionName@file:line:column"
    {{mozillaMatch}}
    if (mozillaMatch) {
        const [, fnName, file, line, column] = mozillaMatch;
        return {
            functionFullName: fnName.trim(),
            functionName: fnName.trim(),
            file: file,
            line: parseInt(line),
            column: parseInt(column)
        };
    }

    // 匹配标准Chrome格式: at functionName (file:line:column)
    // 示例: "at validateAndSave (file:///Users/cloud/develop/webhook-serverless/browser-call-chain-demo.html:198:29)"
    const chromeMatch = cleanLine.match(/^at\s+(.+?)\s*\(([^:]+):(\d+):(\d+)\)$/);
    if (chromeMatch) {
        const [, fnName, file, line, column] = chromeMatch;
        return {
            functionFullName: fnName.trim(),
            functionName: fnName.trim(),
            file: file,
            line: parseInt(line),
            column: parseInt(column)
        };
    }

    // 处理简化的Chrome格式: at file:line:column (没有函数名)
    const chromeFileOnlyMatch = cleanLine.match(/^at\s+([^:]+):(\d+):(\d+)/);
    if (chromeFileOnlyMatch) {
        const [, file, line, column] = chromeFileOnlyMatch;
        return {
            functionName: 'anonymous',
            file: file,
            line: parseInt(line),
            column: parseInt(column)
        };
    }

    // 处理HTML内联脚本的情况: at html:line:column
    const htmlMatch = cleanLine.match(/^at\s+html:(\d+):(\d+)/);
    if (htmlMatch) {
        const [, line, column] = htmlMatch;
        return {
            functionName: 'html_inline_function',
            file: 'inline',
            line: parseInt(line),
            column: parseInt(column)
        };
    }

    // 处理其他格式 - 直接提取函数名
    const simpleMatch = cleanLine.match(/^at\s+(.+)$/);
    if (simpleMatch) {
        const fullMatch = simpleMatch[1].trim();
        // 如果不是文件路径格式，认为是函数名
        if (!fullMatch.includes('://') && !fullMatch.includes('<')) {
            return {
                functionName: fullMatch.split('.').pop() || 'anonymous',
                file: null,
                line: null,
                column: null
            };
        }
    }

    // 如果没有任何匹配，返回默认值
    return {
        functionName: 'anonymous'
    };
}

// 初始化调用链追踪
function initCallChainTracking(logSender, options = {}) {
    window.LogSender = logSender;
    window.logSender = logSender;

    if (options.autoTracking) {
        enableAutoTracking();
    }

    console.log('🔗 函数调用链追踪已启用' + (options.autoTracking ? ' (自动追踪模式)' : ''));
}

// 获取当前调用链
function getCallChain() {
    return [...callChain];
}

// 清理调用链
function clearCallChain() {
    callChain.length = 0;
}

// 启用自动追踪功能
function enableAutoTracking() {
    if (autoTracking.enabled) return;

    autoTracking.enabled = true;

    // 重写console方法以实现自动追踪
    const originalConsoleLog = console.log;
    const originalConsoleError = console.error;
    const originalConsoleWarn = console.warn;
    const originalConsoleInfo = console.info;
    const originalConsoleDebug = console.debug;

    function trackFunctionCall() {
        // console.log('in trackFunctionCall')
        try {
            const stack = new Error().stack;
            if (!stack) return null;

            const stackLines = stack.split('\n').slice(2); // 跳过当前函数和console包装器

            for (let i = 0; i < stackLines.length && i < 10; i++) {
                const rawLine = stackLines[i].trim();
                const callerInfo = parseStackLine(rawLine);

                // 过滤掉系统和库函数，但允许一些合理的函数名
                if (callerInfo && callerInfo.functionName &&
                    !callerInfo.functionName.includes('console') &&
                    !callerInfo.functionName.includes('trackFunctionCall') &&
                    !callerInfo.functionName.includes('enableAutoTracking') &&
                    !callerInfo.functionName.includes('LogSender') &&
                    callerInfo.functionName !== 'anonymous' &&
                    callerInfo.functionName.length > 0) {

                    const functionId = `${callerInfo.file || 'unknown'}:${callerInfo.line || 0}:${callerInfo.column || 0}`;

                    // if (!autoTracking.activeFunctions.has(functionId)) {
                        // 函数进入
                        const startTime = Date.now();
                        autoTracking.activeFunctions.set(functionId, {
                            startTime,
                            functionName: callerInfo.functionName,
                            location: {
                                file: callerInfo.file,
                                line: callerInfo.line,
                                column: callerInfo.column
                            },
                            caller: null
                        });

                        // 发送函数进入日志 - 使用时间窗口机制避免重复发送
                        const timeWindow = 1000; // 1秒内不重复发送相同函数的追踪
                        const lastSent = autoTracking.activeFunctions.get(`last_sent_${functionId}`) || 0;

                        if (window.LogSender && (Date.now() - lastSent > timeWindow)) {
                            autoTracking.activeFunctions.set(`last_sent_${functionId}`, Date.now());
                            window.LogSender.customLog('trace', {
                                type: 'auto_function_call',
                                action: 'enter',
                                functionName: callerInfo.functionName,
                                timestamp: startTime,
                                location: {
                                    file: callerInfo.file,
                                    line: callerInfo.line,
                                    column: callerInfo.column
                                },
                                callDepth: Math.min(autoTracking.activeFunctions.size, 10), // 限制深度避免过大
                                autoTracked: true
                            });
                        }
                    // }
                    break;
                }
            }
        } catch (error) {
            // 静默处理错误，避免递归
        }
    }

    // 包装console方法
    console.log = function(...args) {

        trackFunctionCall();
        originalConsoleLog.apply(console, args);
    };

    console.error = function(...args) {
        trackFunctionCall();
        originalConsoleError.apply(console, args);
    };

    console.warn = function(...args) {
        trackFunctionCall();
        originalConsoleWarn.apply(console, args);
    };

    console.info = function(...args) {
        trackFunctionCall();
        originalConsoleInfo.apply(console, args);
    };

    console.debug = function(...args) {
        trackFunctionCall();
        originalConsoleDebug.apply(console, args);
    };

    console.log('🔍 自动函数追踪已启用 - 任何包含console日志的函数都将被自动追踪');
}

// 导出到全局
if (typeof window !== 'undefined') {
    window.createTrackedFunction = createTrackedFunction;
    window.initCallChainTracking = initCallChainTracking;
    window.getCallChain = getCallChain;
    window.clearCallChain = clearCallChain;
    window.enableAutoTracking = enableAutoTracking;
}

// 使用说明：
// 1. 在HTML中引入此文件: <script src="lib/utils/browserTrack.ts"></script>
// 2. 初始化: const logger = new LogSender('http://localhost:3001', 'my-app');
//              logger.install();
//              initCallChainTracking(logger);
// 3. 使用: const trackedFn = createTrackedFunction(myFunction, 'myFunction');
//          trackedFn(args);