/**
 * Web Overlay Adapter for MbetterClient
 *
 * This script bridges the gap between Qt WebChannel and Web postMessage communication.
 * It provides a compatible interface for overlay templates when running in a web browser
 * instead of the Qt player.
 *
 * When included in a template, it will:
 * 1. Detect if running in Qt WebChannel or Web environment
 * 2. Set up appropriate communication channels
 * 3. Provide a unified interface for data access
 * 4. Prevent Qt-specific script loading errors in web browser
 *
 * Usage: Include this script as the FIRST script in templates:
 *   <script src="/js/overlay-web-adapter.js"></script>
 *   <script>
 *       // Conditionally load Qt scripts only in Qt environment
 *       if (window.loadQtScripts) {
 *           window.loadQtScripts();
 *       }
 *   </script>
 */

(function() {
    // Store original console.log BEFORE any overrides happen
    const originalConsoleLog = console.log.bind(console);
    
    // Debug mode - set to true to enable verbose logging
    const DEBUG = false;
    
    // Debug log function - only logs when DEBUG is true
    const debugLog = (...args) => {
        if (DEBUG) {
            originalConsoleLog('[WebAdapter]', ...args);
        }
    };

    // Check if we're running in Qt WebChannel environment
    const isQtEnvironment = typeof qt !== 'undefined' && qt.webChannelTransport;
    
    // If in Qt environment, don't run the web adapter - Qt scripts are loaded by the template
    if (isQtEnvironment) {
        debugLog('Qt environment detected, web adapter not needed');
        return;
    }
    
    debugLog('Web environment detected, setting up postMessage bridge');
    
    // Web environment - prevent Qt script loading errors
    // Create dummy QWebChannel for browsers (prevents errors from qrc:/// URLs)
    window.QWebChannel = function(transport, callback) {
        debugLog('QWebChannel called in web environment - using adapter instead');
        // The adapter already set up window.overlay, so just call callback if provided
        if (callback && window.overlay) {
            callback({ objects: { overlay: window.overlay } });
        }
    };
    
    // Global error handler to suppress Qt URL scheme errors
    window.addEventListener('error', function(event) {
        if (event.target && (event.target.tagName === 'SCRIPT' || event.target.tagName === 'LINK')) {
            const src = event.target.src || event.target.href || '';
            if (src.startsWith('qrc:///') || src.startsWith('overlay://')) {
                debugLog('Suppressed Qt URL error:', src);
                event.preventDefault();
                event.stopPropagation();
                return true;
            }
        }
    }, true); // Use capture phase to catch errors early
    
    // Also handle uncaught errors from Qt URL fetches
    window.addEventListener('unhandledrejection', function(event) {
        if (event.reason && event.reason.message) {
            const msg = event.reason.message;
            if (msg.includes('qrc:///') || msg.includes('overlay://')) {
                debugLog('Suppressed Qt URL promise rejection:', msg);
                event.preventDefault();
                return true;
            }
        }
    });
    
    // Prevent fetch/XMLHttpRequest errors for Qt URLs
    const originalFetch = window.fetch;
    window.fetch = function(url, options) {
        if (typeof url === 'string' && (url.startsWith('qrc:///') || url.startsWith('overlay://'))) {
            debugLog('Blocking fetch to Qt URL:', url);
            return Promise.resolve(new Response('', { status: 200 }));
        }
        return originalFetch.apply(this, arguments);
    };
    
    // Override XMLHttpRequest to prevent Qt URL errors
    const originalOpen = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function(method, url) {
        if (typeof url === 'string' && (url.startsWith('qrc:///') || url.startsWith('overlay://'))) {
            debugLog('Blocking XHR to Qt URL:', url);
            // Return without actually opening - will fail silently
            return;
        }
        return originalOpen.apply(this, arguments);
    };
    
    // Override document.write to prevent Qt scripts from being written
    const originalWrite = document.write;
    document.write = function(content) {
        if (typeof content === 'string' && (content.includes('qrc:///') || content.includes('overlay://'))) {
            debugLog('Blocking document.write with Qt URLs');
            return;
        }
        return originalWrite.apply(this, arguments);
    };
    
    // Web environment - set up postMessage bridge
    debugLog('Setting up postMessage bridge for web environment');
    
    // Check if we're in standalone mode (no parent window to respond)
    const isStandaloneMode = window.parent === window;
    if (isStandaloneMode) {
        debugLog('Standalone mode detected - no parent window, will use direct API calls');
    }
    
    // Data storage
    let fixtureData = null;
    let timerState = { running: false, remaining_seconds: 0 };
    let licenseText = '';
    let completedMatches = [];
    let overlayData = {};
    let winningOutcomes = [];
    
    // Signal emulation - simple event system
    class Signal {
        constructor() {
            this.callbacks = [];
        }
        
        connect(callback) {
            this.callbacks.push(callback);
        }
        
        disconnect(callback) {
            const index = this.callbacks.indexOf(callback);
            if (index > -1) {
                this.callbacks.splice(index, 1);
            }
        }
        
        emit(data) {
            this.callbacks.forEach(callback => {
                try {
                    callback(data);
                } catch (e) {
                    console.error('[WebAdapter] Signal callback error:', e);
                }
            });
        }
    }
    
    // Create overlay object that mimics Qt WebChannel interface
    window.overlay = {
        // Signals
        dataUpdated: new Signal(),
        
        // Log function - use original console.log to avoid recursion
        log: function(message) {
            debugLog('[Overlay]', message);
        },
        
        // Get fixture data - returns Promise (async like Qt)
        getFixtureData: function() {
            return new Promise(async (resolve) => {
                debugLog('getFixtureData called, current data:', fixtureData ? fixtureData.length + ' fixtures' : 'null');
                
                if (fixtureData && fixtureData.length > 0) {
                    debugLog('Returning cached fixture data');
                    resolve(JSON.stringify(fixtureData));
                } else if (isStandaloneMode) {
                    // Standalone mode - fetch directly from API
                    debugLog('Standalone mode - fetching fixture data directly from API');
                    try {
                        const apiBaseUrl = window.location.origin;
                        const response = await fetch(`${apiBaseUrl}/api/overlay/fixtures`, {
                            method: 'GET',
                            credentials: 'include',
                            headers: {
                                'Accept': 'application/json',
                                'Content-Type': 'application/json'
                            }
                        });
                        
                        if (response.ok) {
                            const data = await response.json();
                            debugLog('API returned fixture data:', data ? data.length : 0, 'fixtures');
                            fixtureData = data || [];
                            resolve(JSON.stringify(fixtureData));
                        } else {
                            debugLog('API request failed:', response.status, response.statusText);
                            resolve(JSON.stringify([]));
                        }
                    } catch (error) {
                        debugLog('API fetch error:', error.message);
                        resolve(JSON.stringify([]));
                    }
                } else {
                    // Request data from parent
                    debugLog('Requesting fixture data from parent');
                    requestFixtureData();
                    // Wait for response with timeout
                    let attempts = 0;
                    const maxAttempts = 100; // 10 seconds
                    const checkData = setInterval(() => {
                        attempts++;
                        if (fixtureData && fixtureData.length > 0) {
                            clearInterval(checkData);
                            debugLog('Fixture data received after', attempts * 100, 'ms');
                            resolve(JSON.stringify(fixtureData));
                        } else if (attempts > maxAttempts) {
                            clearInterval(checkData);
                            debugLog('Fixture data timeout, returning empty array');
                            resolve(JSON.stringify([]));
                        }
                    }, 100);
                }
            });
        },
        
        // Get timer state - returns Promise
        getTimerState: function() {
            return new Promise((resolve) => {
                resolve(JSON.stringify(timerState));
            });
        },
        
        // Get license text - returns Promise
        getLicenseText: function() {
            return new Promise((resolve) => {
                if (licenseText) {
                    resolve(JSON.stringify({ license_text: licenseText }));
                } else {
                    // Request data from parent
                    requestLicenseText();
                    let attempts = 0;
                    const checkData = setInterval(() => {
                        attempts++;
                        if (licenseText) {
                            clearInterval(checkData);
                            resolve(JSON.stringify({ license_text: licenseText }));
                        } else if (attempts > 50) {
                            clearInterval(checkData);
                            resolve(JSON.stringify({ license_text: '' }));
                        }
                    }, 100);
                }
            });
        },
        
        // Get completed matches - returns Promise
        getCompletedMatches: function() {
            return new Promise(async (resolve) => {
                debugLog('getCompletedMatches called, current data:', completedMatches ? completedMatches.length + ' matches' : 'null');
                
                if (completedMatches && completedMatches.length > 0) {
                    debugLog('Returning cached completed matches');
                    resolve(JSON.stringify(completedMatches));
                } else if (isStandaloneMode) {
                    // Standalone mode - fetch directly from API
                    debugLog('Standalone mode - fetching completed matches directly from API');
                    try {
                        const apiBaseUrl = window.location.origin;
                        const response = await fetch(`${apiBaseUrl}/api/overlay/completed-matches`, {
                            method: 'GET',
                            credentials: 'include',
                            headers: {
                                'Accept': 'application/json',
                                'Content-Type': 'application/json'
                            }
                        });
                        
                        if (response.ok) {
                            const data = await response.json();
                            debugLog('API returned completed matches:', data ? data.length : 0, 'matches');
                            completedMatches = data || [];
                            resolve(JSON.stringify(completedMatches));
                        } else {
                            debugLog('API request failed:', response.status, response.statusText);
                            resolve(JSON.stringify([]));
                        }
                    } catch (error) {
                        debugLog('API fetch error:', error.message);
                        resolve(JSON.stringify([]));
                    }
                } else {
                    // Request data from parent
                    debugLog('Requesting completed matches from parent');
                    requestCompletedMatches();
                    let attempts = 0;
                    const maxAttempts = 50;
                    const checkData = setInterval(() => {
                        attempts++;
                        if (completedMatches && completedMatches.length > 0) {
                            clearInterval(checkData);
                            debugLog('Completed matches received after', attempts * 100, 'ms');
                            resolve(JSON.stringify(completedMatches));
                        } else if (attempts > maxAttempts) {
                            clearInterval(checkData);
                            debugLog('Completed matches timeout, returning empty array');
                            resolve(JSON.stringify([]));
                        }
                    }, 100);
                }
            });
        },
        
        // Get winning outcomes - returns Promise
        getWinningOutcomes: function(matchId) {
            return new Promise(async (resolve) => {
                if (isStandaloneMode) {
                    // Standalone mode - fetch directly from API
                    debugLog('Standalone mode - fetching winning outcomes from API for match:', matchId);
                    try {
                        const apiBaseUrl = window.location.origin;
                        const response = await fetch(`${apiBaseUrl}/api/overlay/winning-outcomes/${matchId}`, {
                            method: 'GET',
                            credentials: 'include',
                            headers: {
                                'Accept': 'application/json',
                                'Content-Type': 'application/json'
                            }
                        });
                        
                        if (response.ok) {
                            const data = await response.json();
                            debugLog('API returned winning outcomes:', data ? data.length : 0, 'outcomes');
                            resolve(JSON.stringify(data || []));
                        } else {
                            debugLog('API request failed:', response.status, response.statusText);
                            resolve(JSON.stringify([]));
                        }
                    } catch (error) {
                        debugLog('API fetch error:', error.message);
                        resolve(JSON.stringify([]));
                    }
                } else {
                    // Request data from parent
                    requestWinningOutcomes(matchId);
                    let attempts = 0;
                    const checkData = setInterval(() => {
                        attempts++;
                        if (winningOutcomes && winningOutcomes.length > 0) {
                            clearInterval(checkData);
                            resolve(JSON.stringify(winningOutcomes));
                        } else if (attempts > 30) {
                            clearInterval(checkData);
                            resolve(JSON.stringify([]));
                        }
                    }, 100);
                }
            });
        },
        
        // Get current overlay data - returns Promise (used by results template)
        getCurrentData: function() {
            return new Promise((resolve) => {
                debugLog('getCurrentData called, returning overlayData');
                resolve(JSON.stringify(overlayData));
            });
        }
    };
    
    // Request functions - send postMessage to parent
    function requestFixtureData() {
        if (window.parent !== window) {
            window.parent.postMessage({ type: 'requestFixtureData' }, '*');
        }
    }
    
    function requestTimerState() {
        if (window.parent !== window) {
            window.parent.postMessage({ type: 'requestTimerState' }, '*');
        }
    }
    
    function requestLicenseText() {
        if (window.parent !== window) {
            window.parent.postMessage({ type: 'requestLicenseText' }, '*');
        }
    }
    
    function requestCompletedMatches() {
        if (window.parent !== window) {
            window.parent.postMessage({ type: 'requestCompletedMatches' }, '*');
        }
    }
    
    function requestWinningOutcomes(matchId) {
        if (window.parent !== window) {
            window.parent.postMessage({ type: 'requestWinningOutcomes', matchId: matchId }, '*');
        }
    }
    
    // Listen for messages from parent window
    window.addEventListener('message', function(event) {
        // Accept messages from same origin or any origin (for iframe embedding)
        const message = event.data;
        
        if (!message || typeof message !== 'object') {
            return;
        }
        
        debugLog('Received message:', message.type);
        
        switch (message.type) {
            case 'fixtureData':
                fixtureData = message.fixtures || [];
                debugLog('Fixture data updated:', fixtureData.length, 'fixtures');
                break;
                
            case 'timerState':
                timerState = message.running !== undefined ? {
                    running: message.running,
                    remaining_seconds: message.remaining_seconds || 0
                } : message;
                debugLog('Timer state updated:', timerState);
                // Emit signal for templates listening to dataUpdated
                window.overlay.dataUpdated.emit({ timer_update: timerState });
                break;
                
            case 'timerUpdate':
                timerState = message.running !== undefined ? {
                    running: message.running,
                    remaining_seconds: message.remaining_seconds || 0
                } : message;
                debugLog('Timer update received:', timerState);
                window.overlay.dataUpdated.emit({ timer_update: timerState });
                break;
                
            case 'licenseText':
                licenseText = message.licenseText || '';
                debugLog('License text updated');
                break;
                
            case 'completedMatches':
                completedMatches = message.matches || [];
                debugLog('Completed matches updated:', completedMatches.length, 'matches');
                break;
                
            case 'winningOutcomes':
                winningOutcomes = message.outcomes || [];
                debugLog('Winning outcomes updated:', winningOutcomes.length, 'outcomes');
                break;
                
            case 'initialData':
                // Initial data bundle sent when template loads
                if (message.overlayData) {
                    overlayData = message.overlayData;
                }
                if (message.timerState) {
                    timerState = message.timerState;
                }
                if (message.licenseText) {
                    licenseText = message.licenseText;
                }
                debugLog('Initial data received');
                // Emit signal for templates
                window.overlay.dataUpdated.emit(overlayData);
                break;
                
            case 'dataUpdated':
                // Overlay data update
                overlayData = { ...overlayData, ...message };
                debugLog('Overlay data updated:', Object.keys(message));
                // Emit signal for templates
                window.overlay.dataUpdated.emit(message);
                break;
                
            case 'matchUpdate':
                debugLog('Match update received:', message);
                // Update overlay data with match info
                overlayData = { ...overlayData, ...message };
                // Emit the match data directly so templates can access data.match
                window.overlay.dataUpdated.emit(message);
                break;
                
            case 'resultUpdate':
                debugLog('Result update received:', message);
                // Emit the result data directly (not wrapped) so templates can process it
                // The message contains: outcome, result, under_over_result, match_id, etc.
                overlayData = { ...overlayData, ...message };
                window.overlay.dataUpdated.emit(message);
                break;
                
            case 'videoStateChanged':
                debugLog('Video state changed:', message.state);
                break;
                
            case 'streamStateChanged':
                debugLog('Stream state changed:', message.state);
                break;
                
            case 'positionChanged':
                // Video position update - can be used for time-based overlays
                break;
                
            default:
                debugLog('Unknown message type:', message.type);
        }
    });
    
    // Request initial data when DOM is ready
    function requestInitialData() {
        debugLog('Requesting initial data from parent');
        
        if (window.parent !== window) {
            window.parent.postMessage({ type: 'requestInitialData' }, '*');
        }
        
        // Also request specific data
        requestFixtureData();
        requestTimerState();
        requestLicenseText();
        requestCompletedMatches();
    }
    
    // Wait for DOM to be ready, then request initial data
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function() {
            // Small delay to ensure parent is ready
            setTimeout(requestInitialData, 100);
        });
    } else {
        setTimeout(requestInitialData, 100);
    }
    
    debugLog('Web overlay adapter initialized');
    
    // Flush any buffered console logs
    if (typeof window.flushConsoleBuffer === 'function') {
        setTimeout(window.flushConsoleBuffer, 200);
    }
})();