/**
 * SLM Framework - Logger System
 * Sistema de logging estructurado para desarrollo y producción
 */

const fs = require('fs');
const path = require('path');
const moment = require('moment-timezone');

// Configuración
const LOG_DIR = path.join(__dirname, '../../logs');
const ERROR_DIR = path.join(__dirname, '../../error');
const IS_DEVELOPMENT = process.env.NODE_ENV === 'development';

// Crear directorios si no existen
[LOG_DIR, ERROR_DIR].forEach(dir => {
    if (!fs.existsSync(dir)) {
        fs.mkdirSync(dir, { recursive: true });
    }
});

/**
 * Niveles de log
 */
const LOG_LEVELS = {
    INFO: 'INFO',
    ERROR: 'ERROR',
    WARNING: 'WARNING',
    SECURITY: 'SECURITY',
    HTTP: 'HTTP'
};

/**
 * Colores para consola (solo desarrollo)
 */
const COLORS = {
    INFO: '\x1b[36m',      // Cyan
    ERROR: '\x1b[31m',     // Red
    WARNING: '\x1b[33m',   // Yellow
    SECURITY: '\x1b[35m',  // Magenta
    HTTP: '\x1b[32m',      // Green
    RESET: '\x1b[0m'
};

/**
 * Formatea timestamp
 */
function getTimestamp() {
    return moment().tz('America/Mexico_City').format('YYYY-MM-DD HH:mm:ss');
}

/**
 * Escribe log a archivo
 */
function writeToFile(level, message, data, isError = false) {
    try {
        const timestamp = getTimestamp();
        const date = moment().format('YYYY-MM-DD');
        const dir = isError ? ERROR_DIR : LOG_DIR;
        const fileName = `${date}.log`;
        const filePath = path.join(dir, fileName);

        const logEntry = {
            timestamp,
            level,
            message,
            ...(data && { data }),
            pid: process.pid
        };

        const logLine = JSON.stringify(logEntry) + '\n';

        fs.appendFileSync(filePath, logLine, 'utf8');
    } catch (err) {
        // Fallback a consola si falla escritura
        console.error('Failed to write log:', err.message);
    }
}

/**
 * Formatea mensaje para consola
 */
function formatConsoleMessage(level, message, data) {
    const timestamp = getTimestamp();
    const color = COLORS[level] || COLORS.RESET;
    const reset = COLORS.RESET;

    let output = `${color}[${timestamp}] [${level}]${reset} ${message}`;

    if (data && Object.keys(data).length > 0) {
        output += '\n' + JSON.stringify(data, null, 2);
    }

    return output;
}

/**
 * Log genérico
 */
function log(level, message, data = null) {
    const isError = level === LOG_LEVELS.ERROR;

    // Escribir a archivo
    writeToFile(level, message, data, isError);

    // Mostrar en consola (con colores en desarrollo)
    if (IS_DEVELOPMENT || isError) {
        const consoleMessage = formatConsoleMessage(level, message, data);

        if (isError) {
            console.error(consoleMessage);
        } else {
            console.log(consoleMessage);
        }
    }
}

/**
 * Log de información
 */
function info(message, data = null) {
    log(LOG_LEVELS.INFO, message, data);
}

/**
 * Log de error
 */
function error(message, data = null) {
    log(LOG_LEVELS.ERROR, message, data);
}

/**
 * Log de advertencia
 */
function warning(message, data = null) {
    log(LOG_LEVELS.WARNING, message, data);
}

/**
 * Log de seguridad
 */
function security(message, data = null) {
    log(LOG_LEVELS.SECURITY, message, data);
}

/**
 * Middleware de logging HTTP
 */
function httpLogger(req, res, next) {
    const startTime = Date.now();
    const timestamp = getTimestamp();

    // Capturar cuando termina la respuesta
    res.on('finish', () => {
        const duration = Date.now() - startTime;
        const logData = {
            method: req.method,
            path: req.path,
            status: res.statusCode,
            duration: `${duration}ms`,
            ip: req.ip || req.connection?.remoteAddress,
            userAgent: req.get('user-agent')
        };

        // Solo loggear en desarrollo o errores
        if (IS_DEVELOPMENT || res.statusCode >= 400) {
            log(LOG_LEVELS.HTTP, `${req.method} ${req.path}`, logData);
        } else {
            // En producción, solo escribir a archivo sin consola
            writeToFile(LOG_LEVELS.HTTP, `${req.method} ${req.path}`, logData);
        }
    });

    next();
}

module.exports = {
    info,
    error,
    warning,
    security,
    httpLogger,
    LOG_LEVELS
};
