import LogSender from '../index.js';

// 全局调用链追踪状态 - 自动启用，无需手动初始化
const callChain: Array<{
    functionName: string;
    timestamp: number;
    file?: string;
    line?: number;
    column?: number;
    caller?: {
        functionName: string;
        file?: string;
        line?: number;
    };
    args?: any[];
    duration?: number;
    result?: any;
    error?: any;
}> = [];

// 自动检测并使用LogSender实例
function getLogger(): LogSender | null {
    // 尝试从全局获取LogSender实例
    if (typeof window !== 'undefined' && (window as any).LogSender) {
        // 浏览器环境，从window获取
        return (window as any).LogSender;
    }
    if (typeof global !== 'undefined' && (global as any).LogSender) {
        // Node.js环境，从global获取
        return (global as any).LogSender;
    }
    if (typeof globalThis !== 'undefined' && (globalThis as any).LogSender) {
        // 全局环境，从globalThis获取
        return (globalThis as any).LogSender;
    }
    // 如果没有找到实例，返回null
    return null;
}

// 自动初始化追踪器 - 当LogSender可用时自动启用
let isAutoTrackingEnabled = false;
export function enableAutoCallChainTracking() {
    if (!isAutoTrackingEnabled) {
        isAutoTrackingEnabled = true;
        // 定期检查LogSender是否可用
        const checkInterval = setInterval(() => {
            const logger = getLogger();
            if (logger) {
                clearInterval(checkInterval);
                console.log('🔗 自动启用函数调用链追踪');
            }
        }, 1000);
    }
}

// 初始化追踪器 - 兼容现有API
export function initCallChainTracking(logSender: LogSender) {
    (globalThis as any).LogSender = logSender;
    if (typeof window !== 'undefined') {
        (window as any).LogSender = logSender;
    }
    if (typeof global !== 'undefined') {
        (global as any).LogSender = logSender;
    }
}

// 解析调用栈信息
function parseStackLine(stackLine: string): { functionName: string; file?: string; line?: number; column?: number } {
    // 匹配格式: at functionName (file:line:column) 或 at file:line:column
    const match = stackLine.match(/at\s+(?:(.+?)\s*\()?([^:)]+):(\d+):(\d+)\)?/);
    if (match) {
        const [, fnName, file, line, column] = match;
        return {
            functionName: fnName?.split('.').pop() || 'anonymous',
            file: file,
            line: parseInt(line),
            column: parseInt(column)
        };
    }
    // 简单的at functionName格式
    const simpleMatch = stackLine.match(/at\s+(.+)$/);
    return {
        functionName: simpleMatch ? simpleMatch[1].split('.').pop() || 'anonymous' : 'anonymous'
    };
}

// 创建函数包装器
export function createTrackedFunction<T extends (...args: any[]) => any>(
    fn: T,
    functionName?: string
): T {
    return ((...args: Parameters<T>) => {
        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);

        // 发送调用链日志
        const currentLogger = getLogger();
        if (currentLogger) {
            currentLogger.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(...args);

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

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

                    // 发送返回日志
                    const asyncLogger = getLogger();
                    if (asyncLogger) {
                        asyncLogger.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: any) => {
                    const endTime = Date.now();
                    const duration = endTime - startTime;

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

                    // 发送错误日志
                    const asyncErrorLogger = getLogger();
                    if (asyncErrorLogger) {
                        asyncErrorLogger.customLog('error', {
                            type: 'function_call',
                            action: 'error',
                            functionName: actualFnName,
                            timestamp: endTime,
                            duration,
                            error: {
                                message: (error as Error).message,
                                stack: (error as Error).stack
                            },
                            callDepth: callChain.length
                        });
                    }

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

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

                // 发送返回日志
                const syncLogger = getLogger();
                if (syncLogger) {
                    syncLogger.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();

            // 发送错误日志
            const errorLogger = getLogger();
            if (errorLogger) {
                errorLogger.customLog('error', {
                    type: 'function_call',
                    action: 'error',
                    functionName: actualFnName,
                    timestamp: endTime,
                    duration,
                    error: {
                        message: (error as Error).message,
                        stack: (error as Error).stack
                    },
                    callDepth: callChain.length
                });
            }

            throw error;
        }
    }) as T;
}

// 追踪函数装饰器
export function trackFunction(functionName?: string) {
    return function <T extends (...args: any[]) => any>(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalMethod = descriptor.value;
        descriptor.value = createTrackedFunction(originalMethod, functionName || propertyKey);
        return descriptor;
    };
}

// 追踪类方法装饰器
export function trackMethods(target: any) {
    const descriptors = Object.getOwnPropertyDescriptors(target.prototype || target);

    for (const [propertyKey, descriptor] of Object.entries(descriptors)) {
        if (typeof descriptor.value === 'function' &&
            propertyKey !== 'constructor' &&
            !propertyKey.startsWith('_')) {
            descriptor.value = createTrackedFunction(descriptor.value, propertyKey);
        }
    }
}

// 导出兼容的旧函数
export function trace() {
    const stack = new Error().stack;
    console.log('%c调用栈:', 'color: blue; font-weight: bold');
    console.log(stack && stack.split('\n').slice(2, 6).join('\n'));

    // 同时发送到日志系统
    const traceLogger = getLogger();
    if (traceLogger) {
        traceLogger.customLog('trace', {
            type: 'stack_trace',
            stack: stack?.split('\n').slice(2, 6),
            timestamp: Date.now()
        });
    }
}

export function getFnName(msg = '') {
    const stack = new Error().stack;
    const caller = stack && stack.split('\n')[2]?.trim();
    const match = caller && caller.match(/at (\S+) /);
    const fnName = match ? match[1].split('.').pop() : 'anonymous';

    console.groupCollapsed(`🔍 ${fnName} ${msg}`);
    console.log('📍 调用栈:', caller);
    console.groupEnd();

    // 发送到日志系统
    const fnLogger = getLogger();
    if (fnLogger) {
        fnLogger.customLog('trace', {
            type: 'function_name',
            functionName: fnName,
            message: msg,
            caller,
            timestamp: Date.now()
        });
    }

    return fnName;
}

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

// 清理调用链（用于测试或重置）
export function clearCallChain() {
    callChain.length = 0;
}