/**
 * MbetterClient Dashboard JavaScript - Offline-first functionality
 */

// Dashboard namespace
window.Dashboard = (function() {
    'use strict';
    
    let config = {};
    let statusInterval = null;
    let isOnline = navigator.onLine;
    let cache = {};
    
    // Initialize dashboard
    function init(userConfig) {
        config = Object.assign({
            statusUpdateInterval: 30000,
            apiEndpoint: '/api',
            user: null
        }, userConfig);

        console.log('Dashboard initializing...', config);

        // Setup event listeners
        setupEventListeners();

        // Start status updates
        startStatusUpdates();

        // Setup offline/online detection
        setupOfflineDetection();

        // Load cached data
        loadFromCache();

        // Initialize match timer
        initMatchTimer();

        console.log('Dashboard initialized successfully');
    }
    
    // Setup event listeners
    function setupEventListeners() {
        // Generic API form handling
        document.addEventListener('submit', function(e) {
            if (e.target.classList.contains('api-form')) {
                e.preventDefault();
                handleApiForm(e.target);
            }
        });
        
        // Generic API button handling
        document.addEventListener('click', function(e) {
            if (e.target.classList.contains('api-btn')) {
                e.preventDefault();
                handleApiButton(e.target);
            }
        });
        
        // Toast notifications
        setupToastNotifications();
    }
    
    // Setup offline/online detection
    function setupOfflineDetection() {
        window.addEventListener('online', function() {
            isOnline = true;
            showNotification('Connection restored', 'success');
            updateOnlineStatus();
            // Sync cached changes when coming back online
            syncCachedChanges();
        });
        
        window.addEventListener('offline', function() {
            isOnline = false;
            showNotification('You are now offline', 'warning');
            updateOnlineStatus();
        });
        
        updateOnlineStatus();
    }
    
    // Update online status indicator
    function updateOnlineStatus() {
        const indicators = document.querySelectorAll('.online-status');
        indicators.forEach(function(indicator) {
            indicator.textContent = isOnline ? 'Online' : 'Offline';
            indicator.className = 'online-status badge ' + (isOnline ? 'bg-success' : 'bg-warning');
        });
    }
    
    // Start periodic status updates
    function startStatusUpdates() {
        if (statusInterval) {
            clearInterval(statusInterval);
        }
        
        // Initial update
        updateSystemStatus();
        
        // Periodic updates
        statusInterval = setInterval(function() {
            if (isOnline) {
                updateSystemStatus();
            }
        }, config.statusUpdateInterval);
    }
    
    // Update system status
    function updateSystemStatus() {
        apiRequest('GET', '/status')
        .then(function(data) {
            updateStatusDisplay(data);
            cacheData('system_status', data);
        })
        .catch(function(error) {
            console.error('Failed to update system status:', error);
            // Use cached data if available
            const cached = getFromCache('system_status');
            if (cached) {
                updateStatusDisplay(cached);
            }
        });
    }
    
    // Update status display elements
    function updateStatusDisplay(data) {
        // Update system status
        const systemStatus = document.getElementById('system-status');
        if (systemStatus && data.status) {
            systemStatus.textContent = data.status.charAt(0).toUpperCase() + data.status.slice(1);
            systemStatus.className = 'badge ' + (data.status === 'online' ? 'bg-success' : 'bg-danger');
        }
        
        // Update last updated time
        const lastUpdated = document.getElementById('last-updated');
        if (lastUpdated) {
            lastUpdated.textContent = new Date().toLocaleTimeString();
        }
        
        // Update component status
        if (data.components) {
            Object.keys(data.components).forEach(function(component) {
                const badge = document.getElementById(component + '-badge');
                if (badge) {
                    const status = data.components[component];
                    badge.className = 'badge me-1 ' + (status === 'running' ? 'bg-success' : 'bg-secondary');
                }
            });
        }
    }
    
    // Generic API request handler
    function apiRequest(method, endpoint, data) {
        const url = config.apiEndpoint + endpoint;
        const options = {
            method: method,
            headers: {
                'Content-Type': 'application/json',
            }
        };
        
        if (data) {
            options.body = JSON.stringify(data);
        }
        
        return fetch(url, options)
        .then(function(response) {
            if (!response.ok) {
                throw new Error('API request failed: ' + response.status);
            }
            return response.json();
        });
    }
    
    // Handle API form submissions
    function handleApiForm(form) {
        const formData = new FormData(form);
        const data = {};
        
        formData.forEach(function(value, key) {
            data[key] = value;
        });
        
        const method = form.dataset.method || 'POST';
        const endpoint = form.dataset.endpoint;
        
        if (!endpoint) {
            console.error('Form missing data-endpoint attribute');
            return;
        }
        
        showLoading(form);
        
        apiRequest(method, endpoint, data)
        .then(function(response) {
            hideLoading(form);
            
            if (response.success) {
                showNotification(response.message || 'Operation completed successfully', 'success');
                form.reset();
                
                // Refresh data if needed
                const refreshTarget = form.dataset.refresh;
                if (refreshTarget) {
                    refreshSection(refreshTarget);
                }
            } else {
                showNotification(response.error || 'Operation failed', 'error');
            }
        })
        .catch(function(error) {
            hideLoading(form);
            showNotification('Error: ' + error.message, 'error');
            
            // Cache the operation for later if offline
            if (!isOnline) {
                cacheOperation(method, endpoint, data);
                showNotification('Operation cached for when connection is restored', 'info');
            }
        });
    }
    
    // Handle API button clicks
    function handleApiButton(button) {
        const method = button.dataset.method || 'POST';
        const endpoint = button.dataset.endpoint;
        const data = JSON.parse(button.dataset.data || '{}');
        
        if (!endpoint) {
            console.error('Button missing data-endpoint attribute');
            return;
        }
        
        // Confirmation if requested
        if (button.dataset.confirm) {
            if (!confirm(button.dataset.confirm)) {
                return;
            }
        }
        
        showLoading(button);
        
        apiRequest(method, endpoint, data)
        .then(function(response) {
            hideLoading(button);
            
            if (response.success) {
                showNotification(response.message || 'Operation completed successfully', 'success');
                
                // Refresh data if needed
                const refreshTarget = button.dataset.refresh;
                if (refreshTarget) {
                    refreshSection(refreshTarget);
                }
            } else {
                showNotification(response.error || 'Operation failed', 'error');
            }
        })
        .catch(function(error) {
            hideLoading(button);
            showNotification('Error: ' + error.message, 'error');
            
            // Cache the operation for later if offline
            if (!isOnline) {
                cacheOperation(method, endpoint, data);
                showNotification('Operation cached for when connection is restored', 'info');
            }
        });
    }
    
    // Show loading state
    function showLoading(element) {
        element.classList.add('loading');
        element.disabled = true;
    }
    
    // Hide loading state
    function hideLoading(element) {
        element.classList.remove('loading');
        element.disabled = false;
    }
    
    // Refresh a section
    function refreshSection(sectionId) {
        const section = document.getElementById(sectionId);
        if (!section) return;
        
        // Add refresh logic here based on section type
        console.log('Refreshing section:', sectionId);
    }
    
    // Cache management
    function cacheData(key, data) {
        try {
            cache[key] = {
                data: data,
                timestamp: Date.now()
            };
            localStorage.setItem('dashboard_cache', JSON.stringify(cache));
        } catch (e) {
            console.warn('Failed to cache data:', e);
        }
    }
    
    function getFromCache(key) {
        try {
            const cached = cache[key];
            if (cached && (Date.now() - cached.timestamp) < 300000) { // 5 minutes
                return cached.data;
            }
        } catch (e) {
            console.warn('Failed to get cached data:', e);
        }
        return null;
    }
    
    function loadFromCache() {
        try {
            const cached = localStorage.getItem('dashboard_cache');
            if (cached) {
                cache = JSON.parse(cached);
            }
        } catch (e) {
            console.warn('Failed to load cache:', e);
            cache = {};
        }
    }
    
    // Cache operations for offline sync
    function cacheOperation(method, endpoint, data) {
        try {
            let operations = JSON.parse(localStorage.getItem('cached_operations') || '[]');
            operations.push({
                method: method,
                endpoint: endpoint,
                data: data,
                timestamp: Date.now()
            });
            localStorage.setItem('cached_operations', JSON.stringify(operations));
        } catch (e) {
            console.warn('Failed to cache operation:', e);
        }
    }
    
    // Sync cached operations when coming back online
    function syncCachedChanges() {
        try {
            const operations = JSON.parse(localStorage.getItem('cached_operations') || '[]');
            
            if (operations.length === 0) return;
            
            console.log('Syncing', operations.length, 'cached operations');
            
            operations.forEach(function(operation, index) {
                apiRequest(operation.method, operation.endpoint, operation.data)
                .then(function(response) {
                    console.log('Synced operation', index + 1, '/', operations.length);
                })
                .catch(function(error) {
                    console.error('Failed to sync operation:', error);
                });
            });
            
            // Clear cached operations
            localStorage.removeItem('cached_operations');
            showNotification('Cached changes synchronized', 'success');
            
        } catch (e) {
            console.warn('Failed to sync cached operations:', e);
        }
    }
    
    // Toast notifications
    function setupToastNotifications() {
        // Create toast container if it doesn't exist
        if (!document.getElementById('toast-container')) {
            const container = document.createElement('div');
            container.id = 'toast-container';
            container.className = 'toast-container position-fixed bottom-0 end-0 p-3';
            container.style.zIndex = '1060';
            document.body.appendChild(container);
        }
    }
    
    function showNotification(message, type) {
        const container = document.getElementById('toast-container');
        if (!container) return;
        
        const toastId = 'toast-' + Date.now();
        const iconClass = {
            'success': 'fas fa-check-circle text-success',
            'error': 'fas fa-exclamation-triangle text-danger',
            'warning': 'fas fa-exclamation-triangle text-warning',
            'info': 'fas fa-info-circle text-info'
        }[type] || 'fas fa-info-circle text-info';
        
        const toast = document.createElement('div');
        toast.id = toastId;
        toast.className = 'toast';
        toast.setAttribute('role', 'alert');
        toast.innerHTML = `
            <div class="toast-header">
                <i class="${iconClass} me-2"></i>
                <strong class="me-auto">MbetterClient</strong>
                <small class="text-muted">now</small>
                <button type="button" class="btn-close" data-bs-dismiss="toast"></button>
            </div>
            <div class="toast-body">
                ${message}
            </div>
        `;
        
        container.appendChild(toast);
        
        // Initialize and show toast
        if (typeof bootstrap !== 'undefined') {
            const bsToast = new bootstrap.Toast(toast, { delay: 5000 });
            bsToast.show();
            
            // Remove from DOM after hiding
            toast.addEventListener('hidden.bs.toast', function() {
                toast.remove();
            });
        } else {
            // Fallback without Bootstrap
            setTimeout(function() {
                toast.remove();
            }, 5000);
        }
    }
    
    // Video control helpers
    function updateVideoStatus() {
        apiRequest('GET', '/video/status')
        .then(function(data) {
            const statusElement = document.getElementById('video-status');
            if (statusElement && data.player_status) {
                statusElement.textContent = data.player_status.charAt(0).toUpperCase() + data.player_status.slice(1);
                statusElement.className = 'badge ' + (data.player_status === 'playing' ? 'bg-success' : 'bg-secondary');
            }
            cacheData('video_status', data);
        })
        .catch(function(error) {
            console.error('Failed to update video status:', error);
            const cached = getFromCache('video_status');
            if (cached && document.getElementById('video-status')) {
                document.getElementById('video-status').textContent = cached.player_status || 'Unknown';
            }
        });
    }

    // Match Timer functionality
    let matchTimerInterval = null;
    let matchTimerSeconds = 0;
    let matchTimerRunning = false;

    function initMatchTimer() {
        // Get match interval configuration
        apiRequest('GET', '/match-timer/config')
        .then(function(data) {
            if (data.success && data.match_interval) {
                matchTimerSeconds = data.match_interval * 60; // Convert minutes to seconds
                startMatchTimer();
            } else {
                console.error('Failed to get match timer config:', data);
                // Fallback to 20 minutes
                matchTimerSeconds = 20 * 60;
                startMatchTimer();
            }
        })
        .catch(function(error) {
            console.error('Failed to initialize match timer:', error);
            // Fallback to 20 minutes
            matchTimerSeconds = 20 * 60;
            startMatchTimer();
        });
    }

    function startMatchTimer() {
        if (matchTimerInterval) {
            clearInterval(matchTimerInterval);
        }

        matchTimerRunning = true;
        updateMatchTimerDisplay();

        matchTimerInterval = setInterval(function() {
            if (matchTimerSeconds > 0) {
                matchTimerSeconds--;
                updateMatchTimerDisplay();
            } else {
                // Timer reached 0, start next match
                startNextMatch();
            }
        }, 1000);
    }

    function stopMatchTimer() {
        matchTimerRunning = false;
        if (matchTimerInterval) {
            clearInterval(matchTimerInterval);
            matchTimerInterval = null;
        }
    }

    function resetMatchTimer(seconds) {
        matchTimerSeconds = seconds || (20 * 60); // Default to 20 minutes
        if (!matchTimerRunning) {
            startMatchTimer();
        }
        updateMatchTimerDisplay();
    }

    function updateMatchTimerDisplay() {
        const minutes = Math.floor(matchTimerSeconds / 60);
        const seconds = matchTimerSeconds % 60;
        const timeString = minutes.toString().padStart(2, '0') + ':' + seconds.toString().padStart(2, '0');

        // Update status bar timer
        const statusTimer = document.getElementById('match-timer');
        if (statusTimer) {
            statusTimer.textContent = timeString;
            // Change color when timer is low
            if (matchTimerSeconds <= 60) { // Last minute
                statusTimer.className = 'badge bg-danger text-white';
            } else if (matchTimerSeconds <= 300) { // Last 5 minutes
                statusTimer.className = 'badge bg-warning text-dark';
            } else {
                statusTimer.className = 'badge bg-warning text-dark';
            }
        }

        // Update navbar timer (for cashier dashboard)
        const navbarTimer = document.getElementById('match-timer-display');
        if (navbarTimer) {
            navbarTimer.textContent = timeString;
            navbarTimer.className = matchTimerSeconds <= 60 ? 'text-danger fw-bold' : 'text-warning fw-bold';
        }
    }

    function startNextMatch() {
        console.log('Match timer reached 0, starting next match...');

        apiRequest('POST', '/match-timer/start-match')
        .then(function(data) {
            if (data.success) {
                console.log('Match started successfully:', data);
                showNotification('Match ' + data.match_number + ' started successfully', 'success');

                // Reset timer to configured interval
                apiRequest('GET', '/match-timer/config')
                .then(function(configData) {
                    if (configData.success && configData.match_interval) {
                        resetMatchTimer(configData.match_interval * 60);
                    } else {
                        resetMatchTimer(20 * 60); // Fallback
                    }
                })
                .catch(function(error) {
                    console.error('Failed to get timer config for reset:', error);
                    resetMatchTimer(20 * 60); // Fallback
                });
            } else {
                console.error('Failed to start match:', data.error);
                showNotification('Failed to start match: ' + (data.error || 'Unknown error'), 'error');

                // Stop timer if no matches are available
                if (data.error && data.error.includes('No suitable fixture found')) {
                    stopMatchTimer();
                    updateMatchTimerDisplay();
                    showNotification('No matches available. Timer stopped.', 'info');
                } else {
                    // Reset timer and try again later
                    resetMatchTimer(20 * 60);
                }
            }
        })
        .catch(function(error) {
            console.error('Failed to start next match:', error);
            showNotification('Error starting match: ' + error.message, 'error');

            // Reset timer and continue
            resetMatchTimer(20 * 60);
        });
    }
    
    // Utility functions
    function formatBytes(bytes, decimals) {
        if (bytes === 0) return '0 Bytes';
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    }
    
    function formatTimestamp(timestamp) {
        return new Date(timestamp).toLocaleString();
    }
    
    // Public API
    return {
        init: init,
        apiRequest: apiRequest,
        showNotification: showNotification,
        updateVideoStatus: updateVideoStatus,
        updateSystemStatus: updateSystemStatus,
        formatBytes: formatBytes,
        formatTimestamp: formatTimestamp,
        isOnline: function() { return isOnline; },
        getConfig: function() { return config; },
        // Match timer functions
        initMatchTimer: initMatchTimer,
        startMatchTimer: startMatchTimer,
        stopMatchTimer: stopMatchTimer,
        resetMatchTimer: resetMatchTimer,
        startNextMatch: startNextMatch
    };
})();

// Auto-initialize if config is available
document.addEventListener('DOMContentLoaded', function() {
    const configScript = document.getElementById('dashboard-config');
    if (configScript && typeof Dashboard !== 'undefined') {
        try {
            const config = JSON.parse(configScript.textContent);
            Dashboard.init(config);
        } catch (e) {
            console.error('Failed to parse dashboard config:', e);
        }
    }
});