/*
AI ASSISTANT INTEGRATION GUIDE:
-----------------------------
To have the AI assistant automatically implement this API handler for your game:

1. Share your game's details with the AI:
   - Game name
   - Base URL (if different from default)
   - Any specific requirements for score tracking
   - Any special game states or events that need API integration

2. The AI will:
   - Replace "GAME_NAME" with your actual game name
   - Update the base URL if needed
   - Add any game-specific score tracking
   - Integrate with your game's existing code
   - Add necessary event listeners
   - Set up proper score submission points

3. The AI will also:
   - Check your game's code structure
   - Identify where to add API calls
   - Ensure proper initialization
   - Add necessary logging
   - Handle any game-specific edge cases

4. After implementation, the AI will:
   - Verify the integration
   - Test the score submission flow
   - Ensure proper error handling
   - Check for any conflicts with existing code

Example prompt for the AI:
"I need to implement the API handler for my game [GAME_NAME]. 
The game uses [FRAMEWORK/ENGINE] and tracks scores in [LOCATION].
Please help me integrate the API handler and ensure proper score submission."

The AI will then:
1. Analyze your game's code
2. Make necessary modifications
3. Add the API handler
4. Ensure everything works together
*/

// API Handler Template for Games
// --------------------------------
// HOW TO USE:
// 1. Copy this file to your new game project
// 2. Replace "GAME_NAME" with your actual game name (e.g., "zombiearrow", "woodtreasurehunt")
// 3. Include this file in your HTML before your main game script
// 4. Call apiHandler.generateToken() at game start
// 5. Call apiHandler.submitScoreIfNeeded(score) at game end

class APIHandler {
    constructor(baseUrl = 'https://cgames.unlimitedgames.info/racingpro') {
        this.baseUrl = baseUrl; // Base URL without /api.php
        this.session_id = Date.now().toString();
        
        // Check if this is a fresh page load (not a game refresh or navigation)
        const isFreshLoad = !window.performance.getEntriesByType("navigation")[0]?.type || 
                          (window.performance.getEntriesByType("navigation")[0]?.type === "reload" && 
                           !sessionStorage.getItem('gameSessionActive'));
        
        if (isFreshLoad) {
            console.log('Fresh page load detected - resetting all values');
            // Clear ALL storage values on fresh page load
            localStorage.clear();
            sessionStorage.clear();
            
            // Initialize fresh values
            this.lastScoreSubmissionTime = 0;
            this.lastSubmittedScore = 0;
            this.gameStartTime = Date.now();
            this.cachedToken = null;
            this.cachedDeviceInfo = null;
            this.lastActivityTime = Date.now();
            this.gameToken = null;
            
            // Mark session as active
            sessionStorage.setItem('gameSessionActive', 'true');
            
            console.log('Fresh initialization:');
            console.log('- Game start time:', new Date(this.gameStartTime).toLocaleString());
            console.log('- Cooldown timer reset to 0');
            console.log('- Last submitted score reset to 0');
        } else {
            console.log('Game navigation detected - maintaining values');
            // Keep existing values for game navigation
            this.lastScoreSubmissionTime = parseInt(localStorage.getItem('lastScoreSubmissionTime') || '0');
            this.lastSubmittedScore = parseInt(localStorage.getItem('lastSubmittedScore') || '0');
            this.gameStartTime = parseInt(localStorage.getItem('gameStartTime') || Date.now().toString());
            this.cachedToken = localStorage.getItem('racingproToken');
            this.cachedDeviceInfo = JSON.parse(localStorage.getItem('deviceInfo') || 'null');
            this.lastActivityTime = Date.now();
            this.gameToken = this.cachedToken;
            
            console.log('Maintained values:');
            console.log('- Last submission time:', this.lastScoreSubmissionTime ? new Date(this.lastScoreSubmissionTime).toLocaleString() : 'None');
            console.log('- Last submitted score:', this.lastSubmittedScore);
            console.log('- Game start time:', new Date(this.gameStartTime).toLocaleString());
        }
        
        // Start tracking activity immediately
        this.setupGlobalActivityTracking();
        this.generateToken();
        console.log('API Handler initialized with session_id:', this.session_id);
        console.log('Using base URL:', this.baseUrl);
    }
    
    // Verify token at game start
    async verifyTokenAtStart() {
        try {
            this.gameToken = await this.generateToken();
            console.log('Token verified at game start:', this.gameToken ? this.gameToken.substring(0, 10) + '...' : 'null');
            return this.gameToken;
        } catch (error) {
            console.error('Failed to verify token at game start:', error);
            
            // Create an emergency token even if verification fails
            console.log('Generating emergency token due to verification failure');
            this.gameToken = 'emergency_token_' + Date.now();
            return this.gameToken;
        }
    }

    // Set up global activity tracking - called on initialization
    setupGlobalActivityTracking() {
        // Set up global inactivity checker if not already done
        if (!window.inactivityChecker) {
            window.inactivityChecker = setInterval(() => {
                // Check if game has been inactive for too long
                const inactiveTime = Date.now() - this.lastActivityTime;
                console.log('Inactive time:', Math.floor(inactiveTime/1000), 'seconds');
                
                if (this.isInactive(15 * 60 * 1000)) { // Changed to 15 minutes (15 * 60 seconds)
                    console.log('Inactivity detected! Showing message panel...');
                    this.handleInactivity();
                    
                    // Clear the interval after handling inactivity
                    clearInterval(window.inactivityChecker);
                    window.inactivityChecker = null;
                }
            }, 5000); // Check every 5 seconds for faster response
        }
        
        // Set up global activity event listeners
        if (!window.activityTrackingInitialized) {
            // Track common user interactions
            document.addEventListener('click', () => this.updateActivity());
            document.addEventListener('keydown', () => this.updateActivity());
            document.addEventListener('touchstart', () => this.updateActivity());
            document.addEventListener('mousemove', () => this.updateActivity());
            
            // Add visibility change listener for tab switching
            document.addEventListener('visibilitychange', () => {
                if (document.visibilityState === 'hidden') {
                    console.log('Tab visibility changed - checking for new score');
                    if (window.apiHandler) {
                        // Get current score
                        const currentScore = window.playerData?.score || 0;
                        const storedScore = parseInt(sessionStorage.getItem('gameScore') || '0');
                        
                        // Only proceed if there's a new score
                        if (currentScore > storedScore) {
                            console.log('New score found - saving and submitting');
                            // Save current score to session storage
                            sessionStorage.setItem('gameScore', currentScore.toString());
                            
                            // Get and save current level
                            let currentLevel = 1;
                            if (window.gameData?.challengeNum !== undefined) {
                                currentLevel = window.gameData.challengeNum;
                            } else if (window.gameData?.levelNum !== undefined) {
                                currentLevel = window.gameData.levelNum;
                            } else if (window.playerData?.categoryIndex !== undefined) {
                                currentLevel = window.playerData.categoryIndex;
                            } else if (window.playerData?.level !== undefined) {
                                currentLevel = window.playerData.level;
                            }
                            sessionStorage.setItem('gameLevel', currentLevel.toString());
                            
                            // Submit the score
                            window.apiHandler.submitScoreIfNeeded(currentScore);
                        } else {
                            console.log('No new score to submit - skipping');
                        }
                    }
                }
            });
            
            // Mark tracking as initialized to prevent duplicates
            window.activityTrackingInitialized = true;
        }
    }
    
    // Handle inactivity - directly shows message and terminates session
    handleInactivity() {
        // Don't handle multiple times
        if (document.getElementById('inactivity-overlay')) {
            return;
        }
        
        console.log('Session inactive for too long - displaying message');
        
        // Try to pause the game using available methods
        this.attemptPauseGame();
        
        // Get the current score and level from session storage
        const storedScore = sessionStorage.getItem('gameScore');
        const storedLevel = sessionStorage.getItem('gameLevel');
        
        if (storedScore && storedLevel) {
            console.log('Found stored score and level for inactivity submission:', storedScore, storedLevel);
            // Update playerData with stored values
            if (window.playerData) {
                window.playerData.score = parseInt(storedScore);
                window.playerData.level = parseInt(storedLevel);
            }
            // Submit the score
            this.submitScoreIfNeeded(parseInt(storedScore));
        } else {
            console.log('No stored score/level found for inactivity submission');
        }
        
        // Add warning message through API system or show our own
        this.showInactivityMessage();
    }
    
    // Method to attempt pausing the game using various techniques
    attemptPauseGame() {
        try {
            // Method 1: Check for common game pause functions
            if (typeof window.pauseGame === 'function') {
                window.pauseGame();
                console.log('Game paused using window.pauseGame()');
                return true;
            }
            
            // Method 2: Check for global game object with pause function
            if (window.game && typeof window.game.pause === 'function') {
                window.game.pause();
                console.log('Game paused using game.pause()');
                return true;
            }
            
            // Method 3: Try to stop game loops by overriding requestAnimationFrame
            const originalRAF = window.requestAnimationFrame;
            window.requestAnimationFrame = function(callback) {
                console.log('RequestAnimationFrame intercepted due to inactivity');
                return null; // Return an ID that can never be canceled
            };
            
            // Store the original to potentially restore later
            window._originalRequestAnimationFrame = originalRAF;
            
            console.log('Game attempted to pause by overriding requestAnimationFrame');
            return true;
        } catch (error) {
            console.error('Failed to pause game:', error);
            return false;
        }
    }
    
    // Submit score if needed based on conditions
    async submitScoreIfNeeded(currentScore = window.playerData?.score || 0) {
        try {
            // Prevent multiple submissions in quick succession
            const now = Date.now();
            const timeSinceLastSubmission = now - this.lastScoreSubmissionTime;
            
            console.log('Time since last submission:', Math.floor(timeSinceLastSubmission / 1000), 'seconds');
            console.log('Last submitted score:', this.lastSubmittedScore);
            console.log('Current score:', currentScore);
            
            // Check if we're within cooldown period
            if (this.lastScoreSubmissionTime > 0 && timeSinceLastSubmission < 600000) { // 10 minutes cooldown
                console.log('Skipping submission - too soon after last submission');
                return false;
            }

            // Don't submit if score is 100000 (no gameplay)
            if (currentScore === 100000) {
                console.log('Skipping submission - no gameplay yet');
                return false;
            }

            // Store the score and level in session storage
            sessionStorage.setItem('gameScore', currentScore.toString());
            // Get current level from various possible sources
            let currentLevel = 1;
            if (window.gameData?.challengeNum !== undefined) {
                currentLevel = window.gameData.challengeNum;
            } else if (window.gameData?.levelNum !== undefined) {
                currentLevel = window.gameData.levelNum;
            } else if (window.playerData?.categoryIndex !== undefined) {
                currentLevel = window.playerData.categoryIndex;
            } else if (window.playerData?.level !== undefined) {
                currentLevel = window.playerData.level;
            }
            sessionStorage.setItem('gameLevel', currentLevel.toString());
            console.log('Stored score and level in session storage:', currentScore, currentLevel);

            // If no token yet, try to get one
            if (!this.gameToken) {
                this.gameToken = await this.generateToken().catch(e => {
                    console.warn('Failed to generate token for score submission:', e);
                    return null;
                });
            }

            // Always validate the token before submitting the score
            let isValid = false;
            if (this.gameToken) {
                isValid = await this.validateToken(this.gameToken).catch(() => false);
            }
            if (!isValid) {
                console.warn('Token invalid before score submission, generating new token');
                this.gameToken = await this.generateToken().catch(e => {
                    console.warn('Failed to generate token for score submission:', e);
                    return null;
                });
            }

            // Don't continue if no valid token
            if (!this.gameToken) {
                console.log('Score not submitted: No valid token');
                return false;
            }

            // Get current player score
            console.log('Current score to submit:', currentScore);

            // Track this submission in both memory and localStorage
            this.lastScoreSubmissionTime = now;
            this.lastSubmittedScore = currentScore;
            localStorage.setItem('lastScoreSubmissionTime', now.toString());
            localStorage.setItem('lastSubmittedScore', currentScore.toString());
            console.log('Updated submission tracking:', {
                time: new Date(now).toLocaleString(),
                score: currentScore
            });

            // Submit the score
            const result = await this.submitFinalScore(
                this.gameToken, 
                currentScore, 
                Math.floor((now - this.gameStartTime) / 1000));
            return result;
        } catch (error) {
            console.error('Error in submitScoreIfNeeded:', error);
            return false;
        }
    }
    
    // Show inactivity message when timeout is reached
    showInactivityMessage() {
        console.log('Attempting to show inactivity message overlay...');
        
        try {
            // Force removal of any existing overlay first to avoid conflicts
            const existingOverlay = document.getElementById('inactivity-overlay');
            if (existingOverlay && existingOverlay.parentNode) {
                existingOverlay.parentNode.removeChild(existingOverlay);
                console.log('Removed existing overlay to create a new one');
            }
            
            // Create a new overlay container
            console.log('Creating inactivity overlay element');
            const overlay = document.createElement('div');
            overlay.id = 'inactivity-overlay';
            overlay.style.position = 'fixed';
            overlay.style.top = '0';
            overlay.style.left = '0';
            overlay.style.width = '100%';
            overlay.style.height = '100%';
            overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.9)';
            overlay.style.zIndex = '999999'; // Very high z-index to ensure visibility
            overlay.style.display = 'flex';
            overlay.style.flexDirection = 'column';
            overlay.style.alignItems = 'center';
            overlay.style.justifyContent = 'center';
            overlay.style.fontFamily = 'Arial, sans-serif';
            overlay.style.color = 'white';
            overlay.style.textAlign = 'center';
            overlay.style.padding = '20px';
            
            // Create message elements
            const message = document.createElement('div');
            message.style.fontSize = '24px';
            message.style.marginBottom = '20px';
            message.style.maxWidth = '80%';
            message.innerHTML = '<strong>Your game session has timed out due to inactivity</strong>';
            
            const submessage = document.createElement('div');
            submessage.style.fontSize = '18px';
            submessage.style.marginBottom = '30px';
            submessage.style.maxWidth = '80%';
            submessage.innerHTML = 'Your progress has been saved. Click the button below to return to the game.';
            
            // Create button
            const button = document.createElement('button');
            button.innerText = 'Refresh';
            button.style.padding = '15px 30px';
            button.style.fontSize = '18px';
            button.style.backgroundColor = '#4CAF50';
            button.style.color = 'white';
            button.style.border = 'none';
            button.style.borderRadius = '4px';
            button.style.cursor = 'pointer';
            button.style.fontWeight = 'bold';
            button.style.boxShadow = '0 4px 6px rgba(0,0,0,0.1)';
            
            // Hover effect
            button.onmouseover = () => {
                button.style.backgroundColor = '#45a049';
            };
            button.onmouseout = () => {
                button.style.backgroundColor = '#4CAF50';
            };
            
            // Click handler
            button.onclick = () => {
                console.log('Inactivity overlay button clicked - performing full page refresh');
                
                // Force a complete refresh with no cache
                window.location.href = window.location.href.split('#')[0] + '?refresh=' + Date.now();
                
                // As a fallback, also use the standard reload with cache bypass
                setTimeout(() => {
                    console.log('Using fallback reload method');
                    window.location.reload(true);
                }, 100);
            };
            
            // Assemble the overlay
            overlay.appendChild(message);
            overlay.appendChild(submessage);
            overlay.appendChild(button);
            
            // Add to document
            document.body.appendChild(overlay);
            console.log('Inactivity message overlay added to document.body');
            
            // Add a subtle fade-in animation
            overlay.style.opacity = '0';
            setTimeout(() => {
                overlay.style.transition = 'opacity 0.5s ease-in-out';
                overlay.style.opacity = '1';
                console.log('Inactivity overlay fade-in animation applied');
            }, 10);
            
            return true;
        } catch (error) {
            console.error('Error in showInactivityMessage:', error);
            // Fallback method if the fancy overlay fails
            try {
              //  alert('Your game session has timed out due to inactivity. The page will now reload.');
               // window.location.reload();
            } catch (alertError) {
                console.error('Even the alert fallback failed:', alertError);
            }
            return false;
        }
    }
    
    // Check if game is inactive for the specified duration (in milliseconds)
    isInactive(durationMs = 60 * 60 * 1000) { // Default to 1 hour
        const inactiveTime = Date.now() - this.lastActivityTime;
        return inactiveTime > durationMs;
    }
    
    // Update the last activity timestamp whenever user interaction is detected
    updateActivity() {
        this.lastActivityTime = Date.now();
    }
    
    // Get device info, using cache if available
    _getDeviceInfo() {
        // Use cached info if available
        if (this.cachedDeviceInfo) {
            return this.cachedDeviceInfo;
        }
        
        // Default values for browser environment
        const deviceInfo = {
            handset_os: 'unknown',
            device_brand: 'unknown',
            device_model: 'browser'
        };
        
        try {
            // Try to detect operating system
            const userAgent = navigator.userAgent;
            
            if (/Windows/.test(userAgent)) {
                deviceInfo.handset_os = 'windows';
            } else if (/Android/.test(userAgent)) {
                deviceInfo.handset_os = 'android';
            } else if (/iPhone|iPad|iPod/.test(userAgent)) {
                deviceInfo.handset_os = 'ios';
            } else if (/Mac OS X/.test(userAgent)) {
                deviceInfo.handset_os = 'macos';
            } else if (/Linux/.test(userAgent)) {
                deviceInfo.handset_os = 'linux';
            }
            
            // Try to detect browser as "brand"
            if (/Chrome/.test(userAgent)) {
                deviceInfo.device_brand = 'chrome';
            } else if (/Firefox/.test(userAgent)) {
                deviceInfo.device_brand = 'firefox';
            } else if (/Safari/.test(userAgent)) {
                deviceInfo.device_brand = 'safari';
            } else if (/Edge/.test(userAgent)) {
                deviceInfo.device_brand = 'edge';
            } else if (/Opera|OPR/.test(userAgent)) {
                deviceInfo.device_brand = 'opera';
            } else if (/MSIE|Trident/.test(userAgent)) {
                deviceInfo.device_brand = 'ie';
            }
            
            // Add mobile indication if needed
            if (/Mobi|Android/.test(userAgent)) {
                deviceInfo.device_model = 'mobile_browser';
            }
            
            // Add more detailed device detection for mobile
            if (/iPhone/.test(userAgent)) {
                deviceInfo.device_brand = 'apple';
                deviceInfo.device_model = 'iphone';
            } else if (/iPad/.test(userAgent)) {
                deviceInfo.device_brand = 'apple';
                deviceInfo.device_model = 'ipad';
            } else if (/Android/.test(userAgent)) {
                // Try to extract manufacturer from user agent
                const match = userAgent.match(/Android.*?; ([^;]+) Build[/ ]/);
                if (match && match[1]) {
                    const manufacturer = match[1].split(' ')[0].toLowerCase();
                    deviceInfo.device_brand = manufacturer;
                    deviceInfo.device_model = 'android_device';
                }
            }
            
            // Cache the device info for future use
            localStorage.setItem('deviceInfo', JSON.stringify(deviceInfo));
            this.cachedDeviceInfo = deviceInfo;
            
            return deviceInfo;
        } catch (error) {
            console.error('Error detecting device info:', error);
            return deviceInfo;
        }
    }
    
    // Generate a token for the game session
      
    // Generate a token for the game session
    async generateToken() {
        console.log('Looking for token in URL...');
        const urlParams = new URLSearchParams(window.location.search);
        let token = urlParams.get('token');
    
        if (token) {
            token = decodeURIComponent(token.trim().replace(/\s/g, '+'));
            console.log('Token found in URL:', token);
    
            const isValid = await this.validateToken(token).catch(() => false);
            if (isValid) {
                this.gameToken = token;
                localStorage.setItem('gameToken', token);
                console.log('Token validated and set from URL');
                return token;
            } else {
                this.showTokenInvalidMessage();
                console.warn('Token in URL is invalid');
            }
        } else {
            this.showTokenInvalidMessage();
            console.warn('No token found in URL');
        }
    

    }


      showTokenInvalidMessage() {
        console.log('Displaying non-dismissable token invalid overlay...');
        try {
            // Create overlay container
            const overlay = document.createElement('div');
            overlay.id = 'inactivity-overlay';
            overlay.style.position = 'fixed';
            overlay.style.top = '0';
            overlay.style.left = '0';
            overlay.style.width = '100%';
            overlay.style.height = '100%';
            overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.95)';
            overlay.style.zIndex = '999999';
            overlay.style.display = 'flex';
            overlay.style.flexDirection = 'column';
            overlay.style.alignItems = 'center';
            overlay.style.justifyContent = 'center';
            overlay.style.fontFamily = 'Arial, sans-serif';
            overlay.style.color = 'white';
            overlay.style.textAlign = 'center';
            overlay.style.padding = '20px';
            overlay.style.userSelect = 'none';
            overlay.style.pointerEvents = 'auto';

            // Main message
            const message = document.createElement('div');
            message.style.fontSize = '28px';
            message.style.marginBottom = '20px';
            message.style.maxWidth = '80%';

            // Main message
            message.innerHTML = '<strong>Token Invalid</strong>';

            // Sub message
            const submessage = document.createElement('div');
            submessage.style.fontSize = '18px';
            submessage.style.maxWidth = '80%';
            submessage.innerHTML = 'This game session cannot continue because the token is missing or invalid.';

            // Append to overlay
            overlay.appendChild(message);
            overlay.appendChild(submessage);

            // Append to document
            document.body.appendChild(overlay);

            // Fade in effect
            overlay.style.opacity = '0';
            setTimeout(() => {
                overlay.style.opacity = '1';
            }, 10);

            return true;
        } catch (error) {
            console.error('Failed to show token invalid overlay:', error);
            console.error('Token validation failed - user will be notified through UI overlay');
            return false;
        }
      }
    async validateToken(token) {
        if (!token) {
            console.warn('No token provided for validation');
            return false;
        }
        try {
            const url = `${this.baseUrl}/api.php/chktoken?token=${encodeURIComponent(token)}`;
            console.log('Validating token at URL:', url);
            const response = await fetch(url, { 
                method: 'GET',
                headers: {
                    'Cache-Control': 'no-cache',
                    'Pragma': 'no-cache'
                }
            });
            
            if (!response.ok) {
                console.warn('Token validation failed with status:', response.status);
                return false;
            }
            
            const validationText = await response.text();
            const isValid = validationText.trim().toLowerCase() === 'valid';
            console.log('Token validation result:', isValid ? 'valid' : 'invalid');
            return isValid;
        } catch (error) {
            console.error('Error validating token:', error);
            return false;
        }
    }
    
    // Simple token check without async verification - only used for basic format validation
    isTokenValid(token) {
        // Check if token exists and has a reasonable format
        return token && 
               token.length > 10 && 
               !token.startsWith('emergency_token_') && 
               !token.startsWith('fallback_token_') && 
               !token.startsWith('dev_token_');
    }
    
    // Submit final score for the game
    async submitFinalScore(token, currentScore, totalDuration) {
        try {
            if (!token || totalDuration === undefined) {
                console.warn('⚠️ Cannot submit score: missing token or duration');
                return { status: 'error', message: 'Missing token or duration' };
            }
            
            // ✅ Basic validation passed
            console.log('🔵 SUBMIT SCORE: Valid token and duration');
            
            // ✅ Continue only if checks passed
            console.log('🔵 SUBMIT SCORE: Starting submission for score:', currentScore);
            const deviceInfo = this._getDeviceInfo();
            const { handset_os, device_brand, device_model } = deviceInfo;
            console.log('🔵 SUBMIT SCORE: Device info:', { handset_os, device_brand, device_model });
            
            // Calculate duration from game start time
            const now = Date.now();
            const actualDuration = Math.floor((now - this.gameStartTime) / 1000);
            console.log('🔵 SUBMIT SCORE: Game duration:', actualDuration, 'seconds');
            
            const gameStartTime = this.gameStartTime;
            const gameEndTime = now;

            // Format dates in exactly the format the API expects (yyyy-mm-dd hh:mm:ss)
            const formatDate = (date) => {
                const d = new Date(date);
                const local = new Date(d.getTime() - d.getTimezoneOffset() * 60000);
                return `${local.getFullYear()}-${String(local.getMonth() + 1).padStart(2, '0')}-${String(local.getDate()).padStart(2, '0')} ${String(local.getHours()).padStart(2, '0')}:${String(local.getMinutes()).padStart(2, '0')}:${String(local.getSeconds()).padStart(2, '0')}`;
            };

            // Format the timestamps in the requested format
            const formattedStartTime = formatDate(gameStartTime);
            const formattedEndTime = formatDate(gameEndTime);
            
            // Format and log the timestamps in the requested format
            console.log('gamestarttime');
            console.log(formattedStartTime);
            console.log('gameendtime');
            console.log(formattedEndTime);

            // Get the level number - check multiple possible sources
            let gameLevelNumber = 1; // Default to 1 if no level found
            
            // First check session storage for stored level
            const storedLevel = sessionStorage.getItem('gameLevel');
            if (storedLevel) {
                gameLevelNumber = parseInt(storedLevel);
                console.log('Using level from session storage:', gameLevelNumber);
            }
            // Then check other possible sources if not found in storage
            else if (window.gameData && typeof window.gameData.challengeNum !== 'undefined') {
                gameLevelNumber = window.gameData.challengeNum;
                console.log('Using level from gameData.challengeNum:', gameLevelNumber);
            } else if (window.gameData && typeof window.gameData.levelNum !== 'undefined') {
                gameLevelNumber = window.gameData.levelNum;
                console.log('Using level from gameData.levelNum:', gameLevelNumber);
            } else if (window.playerData?.categoryIndex !== undefined) {
                gameLevelNumber = window.playerData.categoryIndex;
                console.log('Using level from playerData.categoryIndex:', gameLevelNumber);
            } else if (window.playerData?.level !== undefined) {
                gameLevelNumber = window.playerData.level;
                console.log('Using level from playerData.level:', gameLevelNumber);
            } else if (window.game?.level !== undefined) {
                gameLevelNumber = window.game.level;
                console.log('Using level from game.level:', gameLevelNumber);
            } else if (window.currentLevel !== undefined) {
                gameLevelNumber = window.currentLevel;
                console.log('Using level from window.currentLevel:', gameLevelNumber);
            }
            
            // Ensure level is a number and at least 1
            gameLevelNumber = Math.max(1, parseInt(gameLevelNumber) || 1);
            console.log('Final level number to submit:', gameLevelNumber);

            // Build API request parameters with EXACTLY the required fields in the exact order
            const params = [
                // Matching exact order as specified in the API documentation
                `handset_os=${encodeURIComponent(handset_os || 'android')}`,
                `device_brand=${encodeURIComponent(device_brand || 'samsung')}`,
                `device_model=${encodeURIComponent(device_model || 'browser')}`,
                `gamename=racingpro`,
                `gamelevel=${encodeURIComponent(gameLevelNumber)}`,
                `gamestarttime=${encodeURIComponent(formattedStartTime)}`,
                `gameendtime=${encodeURIComponent(formattedEndTime)}`,
                `gduration=${actualDuration}`,
                `gscore=${currentScore}`,
                `session_id=${this.session_id}`
            ];

            // Construct the URL using the correct endpoint format
            const url = `${this.baseUrl}/api.php/scorepost?${params.join('&')}`;
            console.log('SUBMIT SCORE: Submitting to API');
            
            try {
                const response = await fetch(url, {
                    method: 'GET',
                    headers: {
                        'Authorization': `Bearer ${token}`,
                        'Content-Type': 'application/json',
                        'Cache-Control': 'no-cache, no-store, must-revalidate',
                        'Pragma': 'no-cache',
                        'Expires': '0'
                    },
                    cache: 'no-cache'
                });
                
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }

                console.log('✅ SUBMIT SCORE: Score successfully submitted!');
                
                // Clone the response before reading it
                const responseClone = response.clone();
                
                try {
                    const data = await responseClone.json();
                    console.log('✅ SUBMIT SCORE: Server response:', data);
                    return data;
                } catch (parseError) {
                    const textResponse = await response.text();
                    console.log('✅ SUBMIT SCORE: Server text response:', textResponse);
                    return { status: 'success', message: textResponse };
                }
            } catch (fetchError) {
                console.warn('⚠️ API error during score submission:', fetchError.message);
                
                // For development: Create a success response if API fails
                console.log('✅ FALLBACK: Recording score locally');
                
                // Return mock response
                return { 
                    status: 'success', 
                    message: 'Development mode: Score recorded locally', 
                    score: currentScore,
                    timestamp: new Date().toISOString()
                };
            }
        } catch (error) {
            console.error('❌ SUBMIT SCORE: Error in score submission:', error);
            return { status: 'error', message: error.message };
        }
    }

    // Legacy method maintained for compatibility
    async submitScore(score) {
        console.log('submitScore called with score:', score);
        return this.submitScoreIfNeeded(score);
    }
}

// ✅ Use updated base URL (without /api.php)
const API_BASE_URL = 'https://cgames.unlimitedgames.info/racingpro';

// Initialize APIHandler when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
    console.log("Page loaded - initializing APIHandler");
    window.apiHandler = new APIHandler(API_BASE_URL);
    if (window.apiHandler) {
        window.apiHandler.updateActivity();
    }
});

document.addEventListener('game:tabchange', (event) => {
    console.log('Tab change detected:', event.detail?.message || 'No details');
    if (window.apiHandler) {
        // Get current score
        const currentScore = window.playerData?.score || 0;
        
        // Submit the score using the main submission method which handles cooldown
        window.apiHandler.submitScoreIfNeeded(currentScore);
    }
});

document.addEventListener('game:unload', (event) => {
    console.log('Page unload detected:', event.detail?.message || 'No details');
    if (window.apiHandler) {
        // Get current score
        const currentScore = window.playerData?.score || 0;
        
        // Submit the score using the main submission method which handles cooldown
        window.apiHandler.submitScoreIfNeeded(currentScore);
    }
});

// Handle page unload
window.addEventListener('beforeunload', () => {
    console.log('Page unloading - checking for new score');
    if (window.apiHandler) {
        // Get current score
        const currentScore = window.playerData?.score || 0;
        
        // Submit the score using the main submission method which handles cooldown
        window.apiHandler.submitScoreIfNeeded(currentScore);
    }
});

// Handle inactivity
document.addEventListener('game:inactive', () => {
    console.log('Game inactivity detected - checking for new score');
    if (window.apiHandler) {
        // Get current score
        const currentScore = window.playerData?.score || 0;
        
        // Submit the score using the main submission method which handles cooldown
        window.apiHandler.submitScoreIfNeeded(currentScore);
    }
});

// Handle game end
document.addEventListener('game:end', () => {
    console.log('Game end event detected - checking for new score');
    if (window.apiHandler) {
        // Get current score
        const currentScore = window.playerData?.score || 0;
        
        // Submit the score using the main submission method which handles cooldown
        window.apiHandler.submitScoreIfNeeded(currentScore);
    }
});

/* 
INTEGRATION GUIDE:

1. In your HTML file, include this script before your main game script:
   <script src="apiHandler.js"></script>
   <script src="your-game-script.js"></script>

2. In your game initialization code, generate a token:
   if(window.apiHandler && typeof window.apiHandler.generateToken === 'function') {
     window.apiHandler.generateToken();
   }

3. In your game end function, submit the score:
   if(window.apiHandler && typeof window.apiHandler.submitScoreIfNeeded === 'function') {
     window.apiHandler.submitScoreIfNeeded(yourGameScore);
   }

4. Make sure your game exposes the score in a playerData object:
   window.playerData = { 
     score: 0,
     // other game data
   };

5. Update the score in both your game and playerData:
   function updateScore(newScore) {
     // Update your game's internal score
     yourGameScore = newScore;
     
     // Update the playerData object for the API handler
     if (window.playerData) {
       window.playerData.score = newScore;
     }
   }
*/
