import { format, inspect } from 'node:util';
// Save original console before it might be patched (must be at module level)
const originalConsole = {
    log: console.log.bind(console),
    error: console.error.bind(console),
    warn: console.warn.bind(console),
    debug: console.debug.bind(console),
};
const LOG_LEVELS = {
    trace: 0,
    debug: 1,
    info: 2,
    warn: 3,
    error: 4,
};
const BOLD = '\x1b[1m';
const RESET = '\x1b[0m';
// Helper to convert hex color to ANSI 24-bit color code
function hexToAnsi(hex) {
    const r = parseInt(hex.slice(1, 3), 16);
    const g = parseInt(hex.slice(3, 5), 16);
    const b = parseInt(hex.slice(5, 7), 16);
    return `\x1b[38;2;${r};${g};${b}m`;
}
function shouldUseColors() {
    // FORCE_COLOR overrides all checks (used when stdout is piped but we still want colors)
    if (process.env.FORCE_COLOR === '1') {
        return true;
    }
    // Check for NO_COLOR environment variable (any non-empty value disables colors)
    if (process.env.NO_COLOR) {
        return false;
    }
    // Check for TERM=dumb
    if (process.env.TERM === 'dumb') {
        return false;
    }
    // Check if stdout is a TTY
    if (!process.stdout || typeof process.stdout.isTTY === 'undefined') {
        return false;
    }
    if (!process.stdout.isTTY) {
        return false;
    }
    return true;
}
const USE_COLORS = shouldUseColors();
function getLogColors(scheme) {
    if (scheme === 'light') {
        // Darker, high-contrast colors for light backgrounds
        return {
            trace: {
                level: hexToAnsi('#008B8B') + BOLD, // Dark cyan
                message: hexToAnsi('#4B4B4B'), // Dark gray
                timestamp: hexToAnsi('#808080'), // Gray
            },
            debug: {
                level: hexToAnsi('#0000CD') + BOLD, // Medium blue
                message: hexToAnsi('#006400'), // Dark green
                timestamp: hexToAnsi('#808080'),
            },
            info: {
                level: hexToAnsi('#FF8C00') + BOLD, // Dark orange
                message: hexToAnsi('#0066CC') + BOLD, // Strong blue
                timestamp: hexToAnsi('#808080'),
            },
            warn: {
                level: hexToAnsi('#9400D3') + BOLD, // Dark violet
                message: hexToAnsi('#8B008B'), // Dark magenta
                timestamp: hexToAnsi('#808080'),
            },
            error: {
                level: hexToAnsi('#DC143C') + BOLD, // Crimson
                message: hexToAnsi('#8B0000') + BOLD, // Dark red
                timestamp: hexToAnsi('#808080'),
            },
        };
    }
    // Dark mode colors (brighter for dark backgrounds)
    return {
        trace: {
            level: hexToAnsi('#00FFFF') + BOLD, // Cyan
            message: hexToAnsi('#A0A0A0'), // Light gray
            timestamp: hexToAnsi('#666666'),
        },
        debug: {
            level: hexToAnsi('#5C9CFF') + BOLD, // Blue
            message: hexToAnsi('#90EE90'), // Light green
            timestamp: hexToAnsi('#666666'),
        },
        info: {
            level: hexToAnsi('#FFD700') + BOLD, // Gold/Yellow
            message: hexToAnsi('#FFFFFF') + BOLD, // White
            timestamp: hexToAnsi('#666666'),
        },
        warn: {
            level: hexToAnsi('#FF00FF') + BOLD, // Magenta
            message: hexToAnsi('#FF00FF'), // Magenta
            timestamp: hexToAnsi('#666666'),
        },
        error: {
            level: hexToAnsi('#FF4444') + BOLD, // Red
            message: hexToAnsi('#FF4444'), // Red
            timestamp: hexToAnsi('#666666'),
        },
    };
}
/**
 * Console logger implementation
 */
export class ConsoleLogger {
    level;
    showTimestamp;
    colorScheme;
    colors;
    showPrefix = true;
    context;
    constructor(level = 'info', showTimestamp = false, colorScheme = 'dark', context = {}) {
        this.level = level;
        this.showTimestamp = showTimestamp;
        this.colorScheme = colorScheme;
        this.colors = getLogColors(this.colorScheme);
        this.context = context;
    }
    setLevel(level) {
        this.level = level;
    }
    setTimestamp(enabled) {
        this.showTimestamp = enabled;
    }
    setColorScheme(scheme) {
        this.colorScheme = scheme;
        this.colors = getLogColors(this.colorScheme);
    }
    setShowPrefix(show) {
        this.showPrefix = show;
    }
    shouldLog(level) {
        return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
    }
    formatMessage(message, args) {
        try {
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            const base = format(message, ...args);
            if (!this.context || Object.keys(this.context).length === 0) {
                return base;
            }
            const ctx = Object.entries(this.context)
                .map(([k, v]) => `${k}=${typeof v === 'object' ? inspect(v, { depth: 2, maxArrayLength: 50, colors: false }) : String(v)}`)
                .join(' ');
            const result = `${base} ${ctx}`;
            const MAX_LENGTH = 10000;
            if (result.length > MAX_LENGTH) {
                return `${result.slice(0, MAX_LENGTH)} …(+${result.length - MAX_LENGTH} chars truncated)`;
            }
            return result;
        }
        catch {
            const base = [String(message), ...args.map((a) => String(a))].join(' ');
            return this.context && Object.keys(this.context).length > 0
                ? `${base} ${JSON.stringify(this.context)}`
                : base;
        }
    }
    log(level, message, ...args) {
        if (!this.shouldLog(level)) {
            return;
        }
        const colors = this.colors[level];
        const levelText = `[${level.toUpperCase()}]`;
        const formattedMessage = this.formatMessage(message, args);
        let output = '';
        if (USE_COLORS) {
            if (this.showPrefix) {
                if (this.showTimestamp) {
                    const timestamp = new Date().toISOString();
                    output = `${colors.timestamp}[${timestamp}]${RESET} ${colors.level}${levelText}${RESET} ${colors.message}${formattedMessage}${RESET}`;
                }
                else {
                    output = `${colors.level}${levelText}${RESET} ${colors.message}${formattedMessage}${RESET}`;
                }
            }
            else {
                // No prefix - just the message with color
                output = `${colors.message}${formattedMessage}${RESET}`;
            }
        }
        else {
            // No colors - plain text output
            if (this.showPrefix) {
                if (this.showTimestamp) {
                    const timestamp = new Date().toISOString();
                    output = `[${timestamp}] ${levelText} ${formattedMessage}`;
                }
                else {
                    output = `${levelText} ${formattedMessage}`;
                }
            }
            else {
                // No prefix, no colors - just message
                output = formattedMessage;
            }
        }
        // Use original console to avoid recursive logging when console is patched
        if (level === 'error') {
            originalConsole.error(output);
        }
        else if (level === 'warn') {
            originalConsole.warn(output);
        }
        else {
            originalConsole.log(output);
        }
    }
    trace(message, ...args) {
        this.log('trace', message, ...args);
    }
    debug(message, ...args) {
        this.log('debug', message, ...args);
    }
    info(message, ...args) {
        this.log('info', message, ...args);
    }
    warn(message, ...args) {
        this.log('warn', message, ...args);
    }
    error(message, ...args) {
        this.log('error', message, ...args);
    }
    fatal(message, ...args) {
        this.log('error', message, ...args);
        process.exit(1);
    }
    child(opts) {
        return new ConsoleLogger(this.level, this.showTimestamp, this.colorScheme, {
            ...this.context,
            ...opts,
        });
    }
}
/**
 * Create a new console logger instance
 *
 * @param level - The minimum log level to display
 * @param showTimestamp - Whether to show timestamps in log messages
 * @param colorScheme - The color scheme to use ('light' or 'dark')
 * @param context - Initial context for the logger
 * @returns A new ConsoleLogger instance
 */
export function createLogger(level = 'info', showTimestamp = false, colorScheme = 'dark', context = {}) {
    return new ConsoleLogger(level, showTimestamp, colorScheme, context);
}
//# sourceMappingURL=logger.js.map