// API Handler for Classic Inverse Game
// --------------------------------
// Handles token generation, score submission, and activity tracking

class APIHandler {
    // Customize base URL for Classic Inverse Game
    constructor(baseUrl = 'https://cgames.unlimitedgames.info/classicinverse') {
        console.log('🔵 Classic Inverse API Handler Initialized', { baseUrl });
        this.baseUrl = baseUrl; // Base URL without /api.php
        this.session_id = Date.now().toString();
        this.cachedToken = localStorage.getItem('gameToken');
        this.cachedDeviceInfo = localStorage.getItem('deviceInfo') ? JSON.parse(localStorage.getItem('deviceInfo')) : null;
        this.scoreSubmitted = false; // Flag to track if score has been submitted
        this.gameStartTime = Date.now(); // When the game session started
        this.lastActivityTime = Date.now(); // Initialize with current time
        this.lastScoreSubmissionTime = 0; // Track when the last score was submitted
        this.lastSubmittedScore = 0; // Track the last score value that was submitted
        this.gameToken = null; // Will store the verified token
        this.gameName = 'classicinverse';
        
        // Start tracking activity immediately
        this.setupGlobalActivityTracking();
        
        console.log('🎮 Classic Inverse API Handler initialized', {
            session_id: this.session_id,
            baseUrl: this.baseUrl,
            gameName: this.gameName
        });
    }
    
    // Get device information
    _getDeviceInfo() {
        // Use cached device info if available
        if (this.cachedDeviceInfo) {
            return this.cachedDeviceInfo;
        }
        
        const userAgent = navigator.userAgent.toLowerCase();
        
        let handset_os = 'unknown';
        let device_brand = 'unknown';
        let device_model = 'browser';
        
        // Detect OS
        if (userAgent.includes('android')) {
            handset_os = 'android';
            device_brand = userAgent.includes('samsung') ? 'samsung' : 
                           userAgent.includes('huawei') ? 'huawei' : 
                           userAgent.includes('xiaomi') ? 'xiaomi' : 'android';
        } else if (userAgent.includes('iphone') || userAgent.includes('ipad')) {
            handset_os = 'ios';
            device_brand = 'apple';
            device_model = userAgent.includes('iphone') ? 'iPhone' : 'iPad';
        } else if (userAgent.includes('windows')) {
            handset_os = 'windows';
        } else if (userAgent.includes('mac')) {
            handset_os = 'macos';
        }
        
        const deviceInfo = { 
            handset_os, 
            device_brand, 
            device_model 
        };
        
        // Cache device info
        this.cachedDeviceInfo = deviceInfo;
        localStorage.setItem('deviceInfo', JSON.stringify(deviceInfo));
        
        return deviceInfo;
    }
    
    // Generate token for the game session
    async generateToken() {
        try {
            // Check cached token first
            if (this.cachedToken) {
                const isValid = await this.validateToken(this.cachedToken);
                if (isValid) {
                    this.gameToken = this.cachedToken;
                    return this.cachedToken;
                }
            }
            
            // Generate new token
            const deviceInfo = this._getDeviceInfo();
            const timestamp = Date.now();
            
            const url = `${this.baseUrl}/api.php/protoken?` + [
                `msisdn=9800000000`,
                `_country=US`,
                `_operator=${deviceInfo.device_brand}`,
                `handset_os=${encodeURIComponent(deviceInfo.handset_os)}`,
                `device_brand=${encodeURIComponent(deviceInfo.device_brand)}`,
                `device_model=${encodeURIComponent(deviceInfo.device_model)}`,
                `session_id=${this.session_id}`,
                `timestamp=${timestamp}`
            ].join('&');
            
            const response = await fetch(url, {
                method: 'GET',
                headers: { 'Accept': 'text/plain' },
                cache: 'no-cache'
            });
            
            if (!response.ok) {
                throw new Error(`Token request failed: ${response.status}`);
            }
            
            const token = (await response.text()).trim();
            
            // Cache and store token
            localStorage.setItem('gameToken', token);
            this.cachedToken = token;
            this.gameToken = token;
            
            return token;
        } catch (error) {
            console.error('Token generation error:', error);
            
            // Fallback token generation
            const fallbackToken = 'dev_token_' + Date.now();
            this.gameToken = fallbackToken;
            return fallbackToken;
        }
    }
    
    // Validate token with server
    async validateToken(token) {
        try {
            // Check token age
            const tokenStorageKey = `token_timestamp_${token}`;
            const tokenTimestamp = localStorage.getItem(tokenStorageKey);
            const currentTime = Date.now();
            
            // If token is older than 1 hour (3600000 milliseconds), invalidate
            if (tokenTimestamp && (currentTime - parseInt(tokenTimestamp) > 3600000)) {
                console.warn('🕒 Token expired after 1 hour');
                return false;
            }
            
            const validateUrl = `${this.baseUrl}/api.php/chktoken?token=${encodeURIComponent(token)}`;
            
            const response = await fetch(validateUrl, {
                method: 'GET'
            });
            
            const validationText = await response.text();
            const isValid = validationText.trim().toLowerCase() === 'valid';
            
            if (isValid) {
                // Update or set token timestamp
                localStorage.setItem(tokenStorageKey, currentTime.toString());
            }
            
            return isValid;
        } catch (error) {
            console.error('Token validation error:', error);
            return false;
        }
    }
    
    // Submit final score
    async submitFinalScore(token, currentScore, totalDuration) {
        // Token Validation and Regeneration
        try {
            // 1. Check if token is valid
            const isTokenValid = await this.validateToken(token);
            
            if (!isTokenValid) {
                console.warn('⚠️ Current token invalid. Generating new token...');
                
                // Regenerate token
                token = await this.generateToken();
                
                console.log('🔵 New token generated:', token ? token.substring(0, 10) + '...' : 'Failed');
            }
        } catch (tokenError) {
            console.error('🔴 Token validation error:', tokenError);
            // Fallback to generating a new token
            token = await this.generateToken();
        }
        // Comprehensive Validation and Preprocessing
        try {
            // 1. Prevent Multiple Submissions
            if (this.scoreSubmitted) {
                console.warn('⚠️ Score has already been submitted for this session');
                return { status: 'skipped', message: 'Score already submitted for this session' };
            }

            // 2. Validate Token
            if (!token || token.trim() === '') {
                console.error('🔴 Invalid or missing token');
                throw new Error('Missing required parameter: token');
            }

            // 3. Preprocess and Validate Score
            if (typeof currentScore === 'string') {
                currentScore = parseFloat(currentScore);
            }

            if (typeof currentScore !== 'number' || isNaN(currentScore)) {
                console.error('🔴 Invalid score', { currentScore, type: typeof currentScore });
                
                // Fallback score sources
                if (window.gameData?.score !== undefined) {
                    console.log('🔵 Using window.gameData.score as fallback');
                    currentScore = window.gameData.score;
                } else if (window.playerData?.score !== undefined) {
                    console.log('🔵 Using window.playerData.score as fallback');
                    currentScore = window.playerData.score;
                } else {
                    throw new Error('Missing or invalid required parameter: currentScore');
                }
            }

            // 4. Validate Duration
            if (typeof totalDuration !== 'number' || isNaN(totalDuration)) {
                console.error('🔴 Invalid duration', { totalDuration });
                throw new Error('Missing or invalid required parameter: totalDuration');
            }

            // 5. Abuse Prevention Checks
            if (totalDuration < 5) {
                console.warn('⚠️ Suspicious: Game finished too quickly');
                throw new Error('Suspicious: Game finished too quickly');
            }
            if (totalDuration > 3600) {
                console.warn('⚠️ Suspicious: Game duration too long');
                throw new Error('Suspicious: Game duration too long');
            }

            // 6. Additional Value Checks
            if (currentScore < 0) {
                console.error('🔴 Score cannot be negative', { currentScore });
                throw new Error('Invalid score value: score cannot be negative');
            }

            if (totalDuration < 0) {
                console.error('🔴 Duration cannot be negative', { totalDuration });
                throw new Error('Invalid duration value: duration cannot be negative');
            }

            // 7. Detailed Logging
            const gameLevel = window.gameData?.level || window.playerData?.level || 1;
            const deviceInfo = this._getDeviceInfo();
            const { handset_os, device_brand, device_model } = deviceInfo;

            console.log('🎮 SUPERFIGURES Score Submission', {
                gameLevel,
                score: currentScore,
                duration: totalDuration,
                deviceInfo: { handset_os, device_brand, device_model }
            });

            // 8. Prepare Score Submission
            const gameStartTime = this.gameStartTime || (Date.now() - totalDuration * 1000);
            const gameEndTime = Date.now();
            
            // Format dates
            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')}`;
            };
            
            const formattedStartTime = formatDate(gameStartTime);
            const formattedEndTime = formatDate(gameEndTime);
            
            // Prepare API parameters
            const params = [
                `handset_os=${encodeURIComponent(deviceInfo.handset_os || 'android')}`,
                `device_brand=${encodeURIComponent(deviceInfo.device_brand || 'samsung')}`,
                `device_model=${encodeURIComponent(deviceInfo.device_model || 'browser')}`,
                `gamename=superfigures`,
                `gamelevel=${window.gameData?.level || '1'}`,
                `gamestarttime=${encodeURIComponent(formattedStartTime)}`,
                `gameendtime=${encodeURIComponent(formattedEndTime)}`,
                `gduration=${totalDuration}`,
                `gscore=${currentScore}`,
                `session_id=${this.session_id}`
            ];
            
            // Log diagnostic information
            console.log('🔵 API Request Details:');
            console.log('Base URL:', this.baseUrl);
            console.log('Full Params:', params);
            
            // Construct URL
            const url = `${this.baseUrl}/api.php/scorepost?${params.join('&')}`;
            console.log('Full URL:', url);
            
            // Submit score
            console.log('Attempting to submit score...');
            try {
                const response = await fetch(url, {
                    method: 'GET',
                    headers: {
                        'Authorization': `Bearer ${token}`,
                        'Content-Type': 'application/json',
                        'Cache-Control': 'no-cache, no-store, must-revalidate'
                    }
                });
                
                console.log('Response Status:', response.status);
                console.log('Response Headers:', Object.fromEntries(response.headers.entries()));
                
                const responseText = await response.text();
                console.log('Response Text:', responseText);
                
                if (!response.ok) {
                    console.error('❌ Score submission HTTP error', {
                        status: response.status,
                        responseText: responseText
                    });
                    throw new Error(`HTTP error! status: ${response.status}, text: ${responseText}`);
                }
                
                // Handle 'nok' response explicitly
                if (responseText.trim().toLowerCase() === 'nok') {
                    console.warn('⚠️ Score submission returned NOK');
                    return { status: 'error', message: 'Score submission failed' };
                }
                
                this.scoreSubmitted = true;

                // Update cached token if a new one was generated
                if (this.gameToken !== token) {
                    this.cachedToken = token;
                    localStorage.setItem('gameToken', token);
                }

                return responseText;
            } catch (error) {
                console.error('🔴 Score Submission Error:', error);
                throw error;
            }
            
            // Check response
            // if (!response.ok) {
            //     throw new Error(`Score submission failed: ${response.status}`);
            // }
            
            // Mark score as submitted
            
            // Return response
            // const responseText = await response.text();
            // return { 
            //     status: responseText.trim().toLowerCase() === 'ok' ? 'success' : 'error', 
            //     message: responseText 
            // };
        } catch (error) {
            console.error('Score submission error:', error);
            return { status: 'error', message: error.message };
        }
    }
    
    // Setup global activity tracking
    setupGlobalActivityTracking() {
        // Inactivity checker
        if (!window.inactivityChecker) {
            window.inactivityChecker = setInterval(() => {
                if (this.isInactive(60 * 60 * 1000)) { // 1 hour timeout
                    this.handleInactivity();
                    this.submitScoreIfNeeded();
                }
            }, 5000);
        }
        
        // Activity event listeners
        if (!window.activityTrackingInitialized) {
            ['click', 'keydown', 'touchstart', 'mousemove'].forEach(event => {
                document.addEventListener(event, () => this.updateActivity());
            });
            
            document.addEventListener('visibilitychange', () => {
                if (document.visibilityState === 'hidden') {
                    this.submitScoreIfNeeded();
                }
            });
            
            window.activityTrackingInitialized = true;
        }
    }
    
    // Check if session is inactive
    isInactive(timeoutMs = 60 * 60 * 1000) {
        return (Date.now() - this.lastActivityTime) > timeoutMs;
    }
    
    // Update last activity time
    updateActivity() {
        this.lastActivityTime = Date.now();
    }
    
    // Handle inactivity
    handleInactivity() {
        if (document.getElementById('inactivity-overlay')) return;
        
        console.log('🕒 Session inactive - preparing to submit final score');
        
        // Attempt to submit final score before showing inactivity overlay
        try {
            const totalDuration = Math.floor((Date.now() - this.gameStartTime) / 1000);
            
            // Use the same score submission logic as game end
            this.submitFinalScore(
                this.gameToken || this.cachedToken || localStorage.getItem('gameToken') || 'default_token', 
                Math.max(0, window.playerData?.score || window.gameData?.score || 0), 
                Math.max(0, totalDuration || 0)
            ).then(result => {
                console.log('🎉 Score submitted during inactivity:', result);
            }).catch(error => {
                console.error('🔴 Score submission error during inactivity:', error);
            });
        } catch (error) {
            console.error('🔴 Error preparing score submission during inactivity:', error);
        }
        
        // Create inactivity overlay
        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.85)';
        overlay.style.color = 'white';
        overlay.style.display = 'flex';
        overlay.style.flexDirection = 'column';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';
        overlay.style.fontFamily = "'Arial', sans-serif";
        overlay.style.zIndex = '9999';
        overlay.style.textAlign = 'center';
        overlay.style.padding = '20px';
        overlay.style.boxSizing = 'border-box';

        const iconContainer = document.createElement('div');
        iconContainer.innerHTML = '⏰';
        iconContainer.style.fontSize = '64px';
        iconContainer.style.marginBottom = '20px';

        const message = document.createElement('h2');
        message.textContent = 'Game Session Inactive';
        message.style.fontSize = '24px';
        message.style.marginBottom = '15px';

        const subMessage = document.createElement('p');
        subMessage.textContent = 'You have been inactive for too long. Please refresh to continue your game.';
        subMessage.style.fontSize = '16px';
        subMessage.style.color = '#ddd';
        subMessage.style.marginBottom = '30px';

        const button = document.createElement('button');
        button.textContent = 'Refresh Game';
        button.style.backgroundColor = '#4CAF50';
        button.style.color = 'white';
        button.style.border = 'none';
        button.style.padding = '12px 24px';
        button.style.borderRadius = '5px';
        button.style.fontSize = '16px';
        button.style.cursor = 'pointer';
        button.style.transition = 'background-color 0.3s ease';

        button.addEventListener('mouseover', () => {
            button.style.backgroundColor = '#45a049';
        });
        button.addEventListener('mouseout', () => {
            button.style.backgroundColor = '#4CAF50';
        });

        button.addEventListener('click', () => {
            window.location.reload();
        });

        overlay.appendChild(iconContainer);
        overlay.appendChild(message);
        overlay.appendChild(subMessage);
        overlay.appendChild(button);
        overlay.style.display = 'flex';
        overlay.style.flexDirection = 'column';
        overlay.style.justifyContent = 'center';
        overlay.style.alignItems = 'center';
        overlay.style.zIndex = '9999';
        button.onclick = () => window.location.reload();
        
        // Add all elements to overlay in correct order
        overlay.appendChild(iconContainer);
        overlay.appendChild(message);
        overlay.appendChild(subMessage);
        overlay.appendChild(button);
        
        // Append to document body with highest z-index
        document.body.appendChild(overlay);
        console.log('Inactivity overlay has been added to the page');
    }
    
    // Submit score if needed
    async submitScoreIfNeeded(currentScore = window.playerData?.score || 0) {
        try {
            const now = Date.now();
            const timeSinceLastSubmit = now - this.lastScoreSubmissionTime;
            
            if (timeSinceLastSubmit >= 10 * 60 * 1000 || currentScore !== this.lastSubmittedScore) {
                if (!this.gameToken) {
                    await this.generateToken();
                }
                
                await this.submitFinalScore(
                    this.gameToken, 
                    currentScore, 
                    Math.floor((now - this.gameStartTime) / 1000)
                );
                
                this.lastSubmittedScore = currentScore;
                this.lastScoreSubmissionTime = now;
                
                return true;
            }
            
            return false;
        } catch (error) {
            console.error('Error in submitScoreIfNeeded:', error);
            return false;
        }
    }
}

// Initialize API Handler immediately
window.apiHandler = new APIHandler('https://cgames.unlimitedgames.info/classicinverse');

// Ensure token is generated on page load
document.addEventListener('DOMContentLoaded', async () => {
    if (window.apiHandler) {
        await window.apiHandler.generateToken();
    }
});
