import {monitor} from "./frameloop";

/**
 * Centralized logging system with performance monitoring integration
 * @class Logger
 */
export class Logger {
    /** @type {boolean} Enable/disable logging */
    static enabled = import.meta.env.MODE !== 'production';
    
    /** @type {string} Log level: 'debug', 'info', 'warn', 'error', 'none' */
    static level = import.meta.env.VITE_LOG_LEVEL || (import.meta.env.MODE === 'production' ? 'error' : 'debug');
    
    /** @type {Object} Log level priorities */
    static levels = {
        debug: 0,
        info: 1,
        warn: 2, 
        error: 3,
        none: 99
    };

    /**
     * Log debug messages (development only)
     * @param {...any} args - Arguments to log
     */
    static debug(...args) {
        this._write('log', '[DEBUG]', args, 'debug');
    }

    /**
     * Log general information
     * @param {...any} args - Arguments to log
     */
    static log(...args) {
        this._write('log', '[LOG]', args, 'info');
    }

    /**
     * Log informational messages
     * @param {...any} args - Arguments to log
     */
    static info(...args) {
        this._write('info', '[INFO]', args, 'info');
    }

    /**
     * Log warning messages
     * @param {...any} args - Arguments to log
     */
    static warn(...args) {
        this._write('warn', '[WARN]', args, 'warn');
    }

    /**
     * Log error messages
     * @param {...any} args - Arguments to log
     */
    static error(...args) {
        this._write('error', '[ERROR]', args, 'error');
    }

    /**
     * Internal method to write log messages
     * @private
     * @param {string} consoleMethod - Console method to use
     * @param {string} prefix - Log level prefix
     * @param {Array} args - Arguments to log
     * @param {string} logLevel - Log level (debug, info, warn, error)
     */
    static _write(consoleMethod, prefix, args, logLevel = 'info') {
        if (!this.enabled) return;
        
        // Check if this log level should be output
        const currentLevelPriority = this.levels[this.level] || this.levels.info;
        const messageLevelPriority = this.levels[logLevel] || this.levels.info;
        
        if (messageLevelPriority < currentLevelPriority) {
            return;
        }

        const date = new Date();
        const timestamp = date.toLocaleTimeString('de-DE');

        const msg = `${prefix} [${timestamp}] ${args.map(a => {
            if (a instanceof Error) {
                return `${a.name}: ${a.message}\n${a.stack || ''}`;
            } else if (typeof a === 'object' && a !== null) {
                try {
                    return JSON.stringify(a);
                } catch (e) {
                    return '[Circular Object]';
                }
            }
            return a;
        }).join(' ')}`;

        if(typeof console[consoleMethod] === 'function') {
            console[consoleMethod](msg);
        }

        // Safe monitor logging
        if (monitor && typeof monitor.log === 'function') {
            try {
                monitor.log(msg);
            } catch (e) {
                // Silent fail if monitor fails
            }
        }
    }

    /**
     * Set log level dynamically
     * @param {string} level - New log level (debug, info, warn, error, none)
     */
    static setLevel(level) {
        if (this.levels.hasOwnProperty(level)) {
            this.level = level;
            this.info(`[Logger] Log level set to: ${level}`);
        } else {
            this.warn(`[Logger] Invalid log level: ${level}. Valid levels:`, Object.keys(this.levels));
        }
    }

    /**
     * Enable/disable logging
     * @param {boolean} enabled - Enable or disable logging
     */
    static setEnabled(enabled) {
        this.enabled = !!enabled;
        if (enabled) {
            console.log('[Logger] Logging enabled');
        }
    }
}
