/**
 * Sistema de Logging de Errores - Frontend
 * Detecta y registra errores en tiempo real
 */

class ErrorLogger {
    constructor() {
        this.errors = [];
        this.isDebugMode = true;
        this.maxErrors = 100;
        this.init();
    }

    init() {
        // Capturar errores JavaScript globales
        window.addEventListener('error', (event) => {
            this.logError({
                type: 'JavaScript Error',
                message: event.message,
                filename: event.filename,
                line: event.lineno,
                column: event.colno,
                stack: event.error ? event.error.stack : 'No stack trace',
                timestamp: new Date().toISOString(),
                url: window.location.href
            });
        });

        // Capturar promesas rechazadas
        window.addEventListener('unhandledrejection', (event) => {
            this.logError({
                type: 'Unhandled Promise Rejection',
                message: event.reason ? event.reason.toString() : 'Unknown promise rejection',
                stack: event.reason && event.reason.stack ? event.reason.stack : 'No stack trace',
                timestamp: new Date().toISOString(),
                url: window.location.href
            });
        });

        // Interceptar fetch para capturar errores de red
        this.interceptFetch();
        
        // Interceptar XMLHttpRequest
        this.interceptXHR();

        // Crear panel de debug si está en modo debug
        if (this.isDebugMode) {
            this.createDebugPanel();
        }
    }

    logError(errorData) {
        // Agregar a la lista de errores
        this.errors.unshift(errorData);
        
        // Mantener solo los últimos errores
        if (this.errors.length > this.maxErrors) {
            this.errors = this.errors.slice(0, this.maxErrors);
        }

        // Log en consola
        console.error('🚨 Error detectado:', errorData);

        // Actualizar panel de debug
        if (this.isDebugMode) {
            this.updateDebugPanel();
        }

        // Enviar error al servidor (opcional)
        this.sendErrorToServer(errorData);
    }

    interceptFetch() {
        const originalFetch = window.fetch;
        window.fetch = async (...args) => {
            try {
                const response = await originalFetch(...args);
                
                // Log de requests exitosos
                if (this.isDebugMode) {
                    console.log('✅ Fetch exitoso:', {
                        url: args[0],
                        status: response.status,
                        statusText: response.statusText
                    });
                }

                // Si la respuesta no es exitosa, registrar como error
                if (!response.ok) {
                    const errorText = await response.clone().text();
                    this.logError({
                        type: 'HTTP Error',
                        message: `HTTP ${response.status}: ${response.statusText}`,
                        url: args[0],
                        status: response.status,
                        statusText: response.statusText,
                        responseText: errorText,
                        timestamp: new Date().toISOString()
                    });
                }

                return response;
            } catch (error) {
                this.logError({
                    type: 'Network Error',
                    message: error.message,
                    url: args[0],
                    stack: error.stack,
                    timestamp: new Date().toISOString()
                });
                throw error;
            }
        };
    }

    interceptXHR() {
        const originalOpen = XMLHttpRequest.prototype.open;
        const originalSend = XMLHttpRequest.prototype.send;

        XMLHttpRequest.prototype.open = function(method, url, ...args) {
            this._errorLogger_method = method;
            this._errorLogger_url = url;
            return originalOpen.apply(this, [method, url, ...args]);
        };

        XMLHttpRequest.prototype.send = function(...args) {
            const xhr = this;
            
            xhr.addEventListener('error', () => {
                window.errorLogger.logError({
                    type: 'XHR Error',
                    message: 'XMLHttpRequest failed',
                    method: xhr._errorLogger_method,
                    url: xhr._errorLogger_url,
                    status: xhr.status,
                    statusText: xhr.statusText,
                    timestamp: new Date().toISOString()
                });
            });

            xhr.addEventListener('load', () => {
                if (xhr.status >= 400) {
                    window.errorLogger.logError({
                        type: 'XHR HTTP Error',
                        message: `HTTP ${xhr.status}: ${xhr.statusText}`,
                        method: xhr._errorLogger_method,
                        url: xhr._errorLogger_url,
                        status: xhr.status,
                        statusText: xhr.statusText,
                        responseText: xhr.responseText,
                        timestamp: new Date().toISOString()
                    });
                }
            });

            return originalSend.apply(this, args);
        };
    }

    createDebugPanel() {
        // Crear panel flotante de debug
        const panel = document.createElement('div');
        panel.id = 'error-debug-panel';
        panel.innerHTML = `
            <div style="
                position: fixed;
                top: 10px;
                right: 10px;
                width: 400px;
                max-height: 500px;
                background: #1a1a1a;
                color: #fff;
                border: 1px solid #333;
                border-radius: 8px;
                font-family: 'Courier New', monospace;
                font-size: 12px;
                z-index: 10000;
                box-shadow: 0 4px 20px rgba(0,0,0,0.3);
                display: none;
            ">
                <div style="
                    background: #333;
                    padding: 10px;
                    border-radius: 8px 8px 0 0;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                ">
                    <span>🚨 Error Logger</span>
                    <div>
                        <button id="clear-errors" style="
                            background: #ff4444;
                            color: white;
                            border: none;
                            padding: 4px 8px;
                            border-radius: 4px;
                            cursor: pointer;
                            margin-right: 5px;
                        ">Limpiar</button>
                        <button id="toggle-debug" style="
                            background: #666;
                            color: white;
                            border: none;
                            padding: 4px 8px;
                            border-radius: 4px;
                            cursor: pointer;
                        ">Ocultar</button>
                    </div>
                </div>
                <div id="error-list" style="
                    max-height: 400px;
                    overflow-y: auto;
                    padding: 10px;
                ">
                    <div style="color: #888;">No hay errores registrados</div>
                </div>
            </div>
        `;

        document.body.appendChild(panel);

        // Event listeners
        document.getElementById('clear-errors').addEventListener('click', () => {
            this.clearErrors();
        });

        document.getElementById('toggle-debug').addEventListener('click', () => {
            this.toggleDebugPanel();
        });

        // Mostrar/ocultar con Ctrl+Shift+E
        document.addEventListener('keydown', (e) => {
            if (e.ctrlKey && e.shiftKey && e.key === 'E') {
                this.toggleDebugPanel();
            }
        });
    }

    updateDebugPanel() {
        const errorList = document.getElementById('error-list');
        if (!errorList) return;

        if (this.errors.length === 0) {
            errorList.innerHTML = '<div style="color: #888;">No hay errores registrados</div>';
            return;
        }

        errorList.innerHTML = this.errors.map(error => `
            <div style="
                border-bottom: 1px solid #333;
                padding: 8px 0;
                margin-bottom: 8px;
            ">
                <div style="color: #ff6b6b; font-weight: bold;">
                    ${error.type}
                </div>
                <div style="color: #ffd93d; margin: 4px 0;">
                    ${error.message}
                </div>
                <div style="color: #888; font-size: 10px;">
                    ${error.timestamp}
                </div>
                ${error.url ? `<div style="color: #74c0fc; font-size: 10px;">URL: ${error.url}</div>` : ''}
                ${error.stack ? `<details style="margin-top: 4px;">
                    <summary style="color: #aaa; cursor: pointer;">Stack Trace</summary>
                    <pre style="color: #ccc; font-size: 10px; margin: 4px 0; white-space: pre-wrap;">${error.stack}</pre>
                </details>` : ''}
            </div>
        `).join('');
    }

    toggleDebugPanel() {
        const panel = document.getElementById('error-debug-panel');
        if (panel) {
            const display = panel.style.display;
            panel.style.display = display === 'none' ? 'block' : 'none';
        }
    }

    clearErrors() {
        this.errors = [];
        this.updateDebugPanel();
    }

    sendErrorToServer(errorData) {
        // Enviar error al servidor para logging
        fetch('log_error.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(errorData)
        }).catch(() => {
            // Silenciar errores del logging para evitar loops
        });
    }

    // Método público para logging manual
    log(message, type = 'Manual Log') {
        this.logError({
            type: type,
            message: message,
            timestamp: new Date().toISOString(),
            url: window.location.href
        });
    }

    // Obtener todos los errores
    getErrors() {
        return this.errors;
    }

    // Exportar errores como JSON
    exportErrors() {
        const dataStr = JSON.stringify(this.errors, null, 2);
        const dataBlob = new Blob([dataStr], {type: 'application/json'});
        const url = URL.createObjectURL(dataBlob);
        const link = document.createElement('a');
        link.href = url;
        link.download = `errors_${new Date().toISOString().slice(0,19).replace(/:/g, '-')}.json`;
        link.click();
    }
}

// Inicializar el logger globalmente
window.errorLogger = new ErrorLogger();

// Agregar botón flotante para mostrar/ocultar debug
document.addEventListener('DOMContentLoaded', () => {
    const debugButton = document.createElement('button');
    debugButton.innerHTML = '🚨';
    debugButton.style.cssText = `
        position: fixed;
        bottom: 20px;
        right: 20px;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        background: #ff4444;
        color: white;
        border: none;
        font-size: 20px;
        cursor: pointer;
        z-index: 9999;
        box-shadow: 0 2px 10px rgba(0,0,0,0.3);
        transition: all 0.3s ease;
    `;
    
    debugButton.addEventListener('click', () => {
        window.errorLogger.toggleDebugPanel();
    });

    debugButton.addEventListener('mouseenter', () => {
        debugButton.style.transform = 'scale(1.1)';
    });

    debugButton.addEventListener('mouseleave', () => {
        debugButton.style.transform = 'scale(1)';
    });

    document.body.appendChild(debugButton);
});

console.log('🚨 Error Logger inicializado. Presiona Ctrl+Shift+E para mostrar/ocultar el panel de debug.');