/*
2048 Game JavaScript Engine
Developed by: RSK World
Website: https://rskworld.in
Founder: Molla Samser
Designer & Tester: Rima Khatun
Contact: info@rskworld.com, support@rskworld.com, help@rskworld.in
Phone: +91 93305 39277
Address: Nutanhat, Mongolkote, Purba Burdwan, West Bengal, India, 713147

License: Educational use only. © 2025-2026 RSK World. All rights reserved.
For more games and resources: https://rskworld.in/games
Terms: https://rskworld.in/terms.php | Privacy: https://rskworld.in/privacy.php

Description: Complete JavaScript implementation of the 2048 puzzle game with
advanced features including sound effects, achievements, power-ups, responsive design,
and comprehensive error handling.
*/

// 2048 Game with Enhanced Features and Sound
(function() {
    // Global error handling
    window.addEventListener('error', function(event) {
        console.error('Unhandled error:', event.message);
        const errorContainer = document.getElementById('error-container');
        const errorMessage = document.getElementById('error-message');
        
        if (errorContainer && errorMessage) {
            errorContainer.style.display = 'block';
            errorMessage.textContent = `Critical Error: ${event.message} (${event.filename}:${event.lineno})`;
        }
    });

    // Prevent console errors
    ['log', 'warn', 'error'].forEach(function(method) {
        const originalMethod = console[method].bind(console);
        console[method] = function() {
            try {
                originalMethod.apply(console, arguments);
            } catch (error) {
                // Silently handle any console logging errors
            }
        };
    });

    document.addEventListener('DOMContentLoaded', () => {
        // Comprehensive initialization checks
        function checkGameInitialization() {
            const criticalElements = [
                'game-container', 'score', 'level', 'timer', 
                'new-game-btn', 'achievements'
            ];
            
            const missingElements = criticalElements.filter(id => !document.getElementById(id));
            
            if (missingElements.length > 0) {
                console.error('Initialization failed. Missing elements:', missingElements);
                const errorContainer = document.getElementById('error-container');
                const errorMessage = document.getElementById('error-message');
                
                if (errorContainer && errorMessage) {
                    errorContainer.style.display = 'block';
                    errorMessage.textContent = `Game Initialization Error: Missing critical elements: ${missingElements.join(', ')}`;
                }
                return false;
            }
            return true;
        }

        // Safe game initialization
        function safeGameInitialization() {
            try {
                if (!checkGameInitialization()) {
                    return;
                }

                // Wrap game creation in try-catch
                window.game = new Game2048();
                console.log('Game initialized successfully');
            } catch (error) {
                console.error('Game initialization failed:', error);
                const errorContainer = document.getElementById('error-container');
                const errorMessage = document.getElementById('error-message');
                
                if (errorContainer && errorMessage) {
                    errorContainer.style.display = 'block';
                    errorMessage.textContent = `Game Initialization Error: ${error.message}`;
                }
            }
        }

        // Delayed initialization to ensure all resources are loaded
        setTimeout(safeGameInitialization, 100);
    });

    // Comprehensive logging decorator
    function logMethod(target, name, descriptor) {
        const originalMethod = descriptor.value;
        
        descriptor.value = function(...args) {
            try {
                console.log(`Calling method: ${name}`, args);
                const result = originalMethod.apply(this, args);
                console.log(`Method ${name} completed successfully`);
                return result;
            } catch (error) {
                console.error(`Error in method ${name}:`, error);
                // Optional: Add error handling or fallback logic
                throw error;
            }
        };
        
        return descriptor;
    }

    class Game2048 {
        constructor() {
            // Add comprehensive logging and error checking
            console.group('Game2048 Initialization');
            console.time('Initialization Time');

            try {
                this.initializeGameElements();
                this.initializeGameState();
                this.initializeSound();
                this.setupEventListeners();
                this.initializeGame();
                
                console.log('Game2048 initialized successfully');
            } catch (error) {
                console.error('Game2048 initialization failed:', error);
                this.handleInitializationError(error);
            } finally {
                console.timeEnd('Initialization Time');
                console.groupEnd();
            }
        }

        // Separate method for element initialization
        initializeGameElements() {
            // Get game elements with error checking
            this.gameContainer = document.getElementById('game-container');
            this.scoreElement = document.getElementById('score');
            this.levelElement = document.getElementById('level');
            this.newGameBtn = document.getElementById('new-game-btn');
            this.timerElement = document.getElementById('timer');
            this.achievementsContainer = document.getElementById('achievements');
            this.soundToggleBtn = document.getElementById('sound-toggle-btn');
            this.soundIcon = document.getElementById('sound-icon');
            this.volumeControl = document.getElementById('volume-control');
            
            // Add sound toggle event listener
            if (this.soundToggleBtn) {
                this.soundToggleBtn.addEventListener('click', () => this.toggleSound());
            }

            // Add volume control listener if available
            if (this.volumeControl) {
                this.volumeControl.addEventListener('input', (e) => this.adjustVolume(e.target.value));
            }

            const missingElements = [
                this.gameContainer, this.scoreElement, this.levelElement, 
                this.newGameBtn, this.timerElement, this.achievementsContainer
            ].filter(el => !el);

            if (missingElements.length > 0) {
                throw new Error(`Missing critical game elements: ${missingElements.join(', ')}`);
            }
        }

        // Initialize game state
        initializeGameState() {
            // Game state
            this.grid = Array(4).fill().map(() => Array(4).fill(0));
            this.score = 0;
            this.level = 1;
            this.moveCount = 0;
            this.timeElapsed = 0;
            this.timerInterval = null;
            this.gameOver = false;
            
            // Achievements tracking
            this.achievements = {
                largest_tile: 0,
                total_merges: 0,
                levels_completed: 0,
                perfect_moves: 0
            };

            // Undo configuration
            this.undoConfig = {
                maxUses: 3,
                usesLeft: 3,
                cooldownTime: 30000, // 30 seconds cooldown
                lastUndoTime: 0
            };

            // Move history for undo
            this.moveHistory = [];
            this.maxMoveHistory = 5;

            // Power-ups
            this.powerUps = {
                shuffle: { 
                    available: true, 
                    cooldown: 3, 
                    remainingCooldown: 0 
                },
                undo: { 
                    available: true, 
                    usesLeft: 3 
                }
            };

            // Flag to track if power-up buttons are added
            this.powerUpButtonsAdded = false;

            // Score multiplier
            this.scoreMultiplier = 1;
        }

        // Sound initialization method
        initializeSound() {
            // Background music
            this.backgroundMusic = new Audio('sounds/background_music.mp3');
            this.backgroundMusic.loop = true;
            this.backgroundMusic.volume = 0.5;

            // Game sound effects
            this.moveSound = new Audio('sounds/move_sound.mp3');
            this.mergeSound = new Audio('sounds/merge_sound.mp3');
            this.gameOverSound = new Audio('sounds/game_over_sound.mp3');
            this.gameStartSound = new Audio('sounds/game_start_sound.mp3');
            this.gameWinSound = new Audio('sounds/game_win_sound.mp3');

            // Sound state
            this.isSoundEnabled = true;
        }

        // Toggle sound on/off
        toggleSound() {
            this.isSoundEnabled = !this.isSoundEnabled;

            if (this.isSoundEnabled) {
                this.backgroundMusic.play();
                this.soundIcon.classList.remove('fa-volume-mute', 'fa-volume-xmark');
                this.soundIcon.classList.add('fa-volume-high');
                this.soundToggleBtn.classList.remove('muted');
                this.soundToggleBtn.setAttribute('aria-label', 'Sound On');
            } else {
                this.backgroundMusic.pause();
                this.soundIcon.classList.remove('fa-volume-high');
                this.soundIcon.classList.add('fa-volume-mute', 'fa-volume-xmark');
                this.soundToggleBtn.classList.add('muted');
                this.soundToggleBtn.setAttribute('aria-label', 'Sound Off');
            }
        }

        // Play sound effect
        playSound(soundType) {
            if (!this.isSoundEnabled) return;

            switch(soundType) {
                case 'move':
                    this.moveSound.play();
                    break;
                case 'merge':
                    this.mergeSound.play();
                    break;
                case 'gameOver':
                    this.gameOverSound.play();
                    break;
                case 'gameStart':
                    this.gameStartSound.play();
                    break;
                case 'gameWin':
                    this.gameWinSound.play();
                    break;
            }
        }

        // Error handling method
        handleInitializationError(error) {
            const errorContainer = document.getElementById('error-container');
            const errorMessage = document.getElementById('error-message');
            
            if (errorContainer && errorMessage) {
                errorContainer.style.display = 'block';
                errorMessage.textContent = `Game Initialization Error: ${error.message}`;
            }

            // Optional: Send error to logging service
            this.logErrorToService(error);
        }

        // Placeholder for potential error logging service
        logErrorToService(error) {
            // In a real-world scenario, you might send this to a server
            console.error('Logging error to service:', {
                message: error.message,
                stack: error.stack,
                timestamp: new Date().toISOString()
            });
        }

        // Volume adjustment method
        adjustVolume(volume) {
            // Convert percentage to decimal
            const volumeLevel = volume / 100;
            
            // Adjust volume for all sounds
            if (this.backgroundMusic) {
                this.backgroundMusic.volume = volumeLevel * 0.5; // Lower background music volume
            }

            // Adjust volume for other sounds
            const soundArrays = [
                [this.moveSound], 
                [this.mergeSound], 
                [this.gameStartSound, this.gameOverSound, this.gameWinSound]
            ];

            soundArrays.forEach(sounds => {
                sounds.forEach(sound => {
                    if (sound) {
                        sound.volume = volumeLevel;
                    }
                });
            });
        }

        // Method to inject advertisement
        injectAdvertisement(containerId) {
            // Create container for advertisement
            const adContainer = document.getElementById(containerId);
            
            if (adContainer) {
                // Clear any existing content
                adContainer.innerHTML = '';

                // Create advertisement elements
                const adDiv = document.createElement('div');
                adDiv.id = '7SAD15679F7024C91C1';
                adDiv.setAttribute('data-7pub', '7SAD15679F7024C91C1');
                adContainer.appendChild(adDiv);

                // Create script elements
                const adScript1 = document.createElement('script');
                adScript1.src = 'https://code.adclickppc.com/7s-native-ad.js';
                adContainer.appendChild(adScript1);

                const adScript2 = document.createElement('script');
                adScript2.innerHTML = `
                (function() {
                  initNativeAd(['7SAD15679F7024C91C1', 'native',  5])
                }())
                `;
                adContainer.appendChild(adScript2);

                // Optional: Log advertisement injection
                console.log('Advertisement injected into', containerId);
            }
        }

        // Enhanced event listeners with power-up buttons
        setupEventListeners() {
            // Keyboard events
            document.addEventListener('keydown', (e) => {
                switch(e.key) {
                    case 'ArrowUp': this.move('up'); break;
                    case 'ArrowDown': this.move('down'); break;
                    case 'ArrowLeft': this.move('left'); break;
                    case 'ArrowRight': this.move('right'); break;
                }
            });

            // Touch events for mobile
            let touchStartX = 0;
            let touchStartY = 0;

            this.gameContainer.addEventListener('touchstart', (e) => {
                touchStartX = e.touches[0].clientX;
                touchStartY = e.touches[0].clientY;
            });

            this.gameContainer.addEventListener('touchend', (e) => {
                const touchEndX = e.changedTouches[0].clientX;
                const touchEndY = e.changedTouches[0].clientY;

                const diffX = touchEndX - touchStartX;
                const diffY = touchEndY - touchStartY;

                if (Math.abs(diffX) > Math.abs(diffY)) {
                    // Horizontal swipe
                    diffX > 0 ? this.move('right') : this.move('left');
                } else {
                    // Vertical swipe
                    diffY > 0 ? this.move('down') : this.move('up');
                }
            });

            // New game button
            this.newGameBtn.addEventListener('click', () => this.initializeGame());

            // Add power-up buttons only once
            this.addPowerUpButtons();
        }

        // Add power-up buttons to the game (called only once)
        addPowerUpButtons() {
            // Prevent multiple button creations
            if (this.powerUpButtonsAdded) return;

            // Create power-ups container if it doesn't exist
            let powerUpsContainer = document.querySelector('.power-ups-container');
            if (!powerUpsContainer) {
                powerUpsContainer = document.createElement('div');
                powerUpsContainer.classList.add('power-ups-container');
                this.gameContainer.parentNode.insertBefore(powerUpsContainer, this.gameContainer.nextSibling);
            } else {
                // Clear existing buttons to prevent duplication
                powerUpsContainer.innerHTML = '';
            }

            // Create shuffle button
            const shuffleBtn = document.createElement('button');
            shuffleBtn.id = 'shuffle-power-up';
            shuffleBtn.classList.add('btn', 'btn-warning', 'power-up-btn');
            shuffleBtn.textContent = 'Shuffle';
            shuffleBtn.addEventListener('click', () => this.shuffleTiles());

            // Create undo button
            const undoBtn = document.createElement('button');
            undoBtn.id = 'undo-power-up';
            undoBtn.classList.add('btn', 'btn-info', 'power-up-btn');
            undoBtn.textContent = 'Undo';
            undoBtn.addEventListener('click', () => this.undoLastMove());

            // Add buttons to container
            powerUpsContainer.appendChild(shuffleBtn);
            powerUpsContainer.appendChild(undoBtn);

            // Mark buttons as added
            this.powerUpButtonsAdded = true;

            // Initial update of power-up display
            this.updatePowerUpDisplay();
        }

        // Shuffle tiles power-up
        shuffleTiles() {
            if (!this.powerUps.shuffle.available) return;

            // Collect all non-zero tiles
            const activeTiles = [];
            for (let r = 0; r < 4; r++) {
                for (let c = 0; c < 4; c++) {
                    if (this.grid[r][c] !== 0) {
                        activeTiles.push(this.grid[r][c]);
                    }
                }
            }

            // Ensure at least minimum tiles
            while (activeTiles.length < 2) {
                activeTiles.push(2);
            }

            // Shuffle the tiles randomly
            this.grid = Array(4).fill().map(() => Array(4).fill(0));
            
            // Redistribute tiles
            while (activeTiles.length > 0) {
                let placed = false;
                while (!placed) {
                    const r = Math.floor(Math.random() * 4);
                    const c = Math.floor(Math.random() * 4);
                    if (this.grid[r][c] === 0) {
                        this.grid[r][c] = activeTiles.pop();
                        placed = true;
                    }
                }
            }

            // Ensure at least two tiles are on the board
            this.addRandomTile();
            if (this.grid.flat().filter(cell => cell === 0).length > 2) {
                this.addRandomTile();
            }

            // Force re-render the grid
            this.renderGrid();

            // Set cooldown
            this.powerUps.shuffle.available = false;
            this.powerUps.shuffle.remainingCooldown = this.powerUps.shuffle.cooldown;
            this.updatePowerUpDisplay();

            // Ensure game container is visible
            if (this.gameContainer) {
                this.gameContainer.style.opacity = '1';
                this.gameContainer.style.visibility = 'visible';
            }
        }

        // Render grid method (ensure full visibility)
        renderGrid() {
            // Clear existing grid
            this.gameContainer.innerHTML = '';

            // Render new grid
            for (let r = 0; r < 4; r++) {
                for (let c = 0; c < 4; c++) {
                    const tileValue = this.grid[r][c];
                    const tileElement = document.createElement('div');
                    tileElement.classList.add('tile');
                    
                    // Add value-specific class and text
                    if (tileValue !== 0) {
                        tileElement.classList.add(`tile-${tileValue}`);
                        tileElement.textContent = tileValue;
                    }

                    // Add data attributes for position
                    tileElement.dataset.row = r;
                    tileElement.dataset.col = c;

                    this.gameContainer.appendChild(tileElement);
                }
            }

            // Update score
            this.updateScore();

            // Ensure game container is fully visible
            if (this.gameContainer) {
                this.gameContainer.style.opacity = '1';
                this.gameContainer.style.visibility = 'visible';
            }
        }

        // Enhanced move method with achievements
        move(direction) {
            let moved = false;
            const prevGrid = this.grid.map(row => [...row]);
            const prevScore = this.score;

            switch(direction) {
                case 'up':
                    moved = this.moveUp();
                    break;
                case 'down':
                    moved = this.moveDown();
                    break;
                case 'left':
                    moved = this.moveLeft();
                    break;
                case 'right':
                    moved = this.moveRight();
                    break;
            }

            // Track move history for undo
            if (moved) {
                this.moveHistory.unshift({ grid: prevGrid, score: prevScore });
                if (this.moveHistory.length > this.maxMoveHistory) {
                    this.moveHistory.pop();
                }

                this.addRandomTile();
                this.renderGrid();
                this.checkGameStatus();
                this.updateAchievements(direction);
            }
        }

        // Achievements tracking method
        updateAchievements(direction) {
            // Track largest tile
            for (let r = 0; r < 4; r++) {
                for (let c = 0; c < 4; c++) {
                    if (this.grid[r][c] > this.achievements.largest_tile) {
                        this.achievements.largest_tile = this.grid[r][c];
                    }
                }
            }

            // Track total merges and perfect moves
            this.achievements.total_merges++;
            
            // Perfect move: no empty cells after move
            const emptyCells = this.grid.flat().filter(cell => cell === 0).length;
            if (emptyCells === 0) {
                this.achievements.perfect_moves++;
            }

            this.updateAchievementsDisplay();
        }

        // Display achievements
        updateAchievementsDisplay() {
            if (this.achievementsContainer) {
                this.achievementsContainer.innerHTML = `
                    <h3>Achievements</h3>
                    <p>Largest Tile: ${this.achievements.largest_tile}</p>
                    <p>Total Merges: ${this.achievements.total_merges}</p>
                    <p>Perfect Moves: ${this.achievements.perfect_moves}</p>
                `;
            }
        }

        // Undo last move with restrictions
        undoLastMove() {
            const now = Date.now();
            
            // Check if undo uses are available
            if (this.undoConfig.usesLeft <= 0) {
                this.showUndoLimitMessage();
                return false;
            }

            // Check cooldown period
            if (now - this.undoConfig.lastUndoTime < this.undoConfig.cooldownTime) {
                this.showUndoCooldownMessage();
                return false;
            }

            // Proceed with undo if checks pass
            if (this.moveHistory.length === 0) {
                console.warn('No moves to undo');
                return false;
            }

            const lastMove = this.moveHistory.pop();
            this.grid = lastMove.grid;
            this.score = lastMove.score;
            
            // Decrement undo uses
            this.undoConfig.usesLeft--;
            this.undoConfig.lastUndoTime = now;

            // Update game state
            this.updateScore();
            this.renderGrid();
            this.updateUndoDisplay();

            return true;
        }

        // Update power-up display
        updatePowerUpDisplay() {
            const shuffleBtn = document.getElementById('shuffle-power-up');
            const undoBtn = document.getElementById('undo-power-up');

            if (shuffleBtn) {
                shuffleBtn.disabled = !this.powerUps.shuffle.available;
                shuffleBtn.textContent = `Shuffle (${this.powerUps.shuffle.remainingCooldown})`;
            }

            if (undoBtn) {
                undoBtn.disabled = this.undoConfig.usesLeft === 0;
                undoBtn.textContent = `Undo (${this.undoConfig.usesLeft})`;
            }
        }

        // Undo limit message
        showUndoLimitMessage() {
            const messageContainer = document.createElement('div');
            messageContainer.classList.add('game-message', 'undo-limit-message');
            messageContainer.innerHTML = `
                <p>Undo limit reached! You have no more undo moves left.</p>
                <small>Tip: Use undo strategically!</small>
            `;
            
            // Append to game container
            this.gameContainer.appendChild(messageContainer);
            
            // Remove message after 3 seconds
            setTimeout(() => {
                this.gameContainer.removeChild(messageContainer);
            }, 3000);
        }

        // Undo cooldown message
        showUndoCooldownMessage() {
            const remainingCooldown = Math.ceil(
                (this.undoConfig.cooldownTime - (Date.now() - this.undoConfig.lastUndoTime)) / 1000
            );

            const messageContainer = document.createElement('div');
            messageContainer.classList.add('game-message', 'undo-cooldown-message');
            messageContainer.innerHTML = `
                <p>Undo is on cooldown. Please wait ${remainingCooldown} seconds.</p>
            `;
            
            // Append to game container
            this.gameContainer.appendChild(messageContainer);
            
            // Remove message after 3 seconds
            setTimeout(() => {
                this.gameContainer.removeChild(messageContainer);
            }, 3000);
        }

        // Update undo display
        updateUndoDisplay() {
            const undoBtn = document.getElementById('undo-power-up');
            if (undoBtn) {
                undoBtn.textContent = `Undo (${this.undoConfig.usesLeft})`;
                undoBtn.disabled = this.undoConfig.usesLeft <= 0;
            }
        }

        // Reset game state
        initializeGame() {
            try {
                // Stop any existing timer
                this.stopTimer();
                
                // Reset game grid
                this.grid = Array(4).fill().map(() => Array(4).fill(0));
                this.score = 0;
                this.level = 1;
                this.moveCount = 0;
                this.updateScore();
                
                // Add initial tiles
                this.addRandomTile();
                this.addRandomTile();
                
                // Render grid and ensure visibility
                this.renderGrid();
                
                // Reset achievements
                this.achievements = {
                    largest_tile: 0,
                    total_merges: 0,
                    levels_completed: 0,
                    perfect_moves: 0
                };

                // Reset undo configuration
                this.undoConfig.usesLeft = this.undoConfig.maxUses;
                this.undoConfig.lastUndoTime = 0;

                // Reset power-ups
                this.powerUps.shuffle.available = true;
                this.powerUps.shuffle.remainingCooldown = 0;
                this.powerUps.undo.usesLeft = 3;

                // Ensure game container is visible
                if (this.gameContainer) {
                    this.gameContainer.style.opacity = '1';
                    this.gameContainer.style.visibility = 'visible';
                }

                // Update displays
                this.updateAchievementsDisplay();
                this.updatePowerUpDisplay();
                this.startTimer();
                this.playSound('gameStart');
            } catch (error) {
                console.error('Game initialization failed:', error);
                this.handleInitializationError(error);
            }
        }

        moveUp() {
            let moved = false;
            let merged = false;
            for (let c = 0; c < 4; c++) {
                const column = [
                    this.grid[0][c], 
                    this.grid[1][c], 
                    this.grid[2][c], 
                    this.grid[3][c]
                ];
                const newColumn = this.mergeTiles(column);
                
                for (let r = 0; r < 4; r++) {
                    if (this.grid[r][c] !== newColumn[r]) {
                        moved = true;
                    }
                    if (this.grid[r][c] !== newColumn[r] && newColumn[r] !== 0) {
                        merged = true;
                    }
                    this.grid[r][c] = newColumn[r];
                }
            }
            if (moved) {
                this.playSound('move');
            }
            if (merged) {
                this.playSound('merge');
            }
            return moved;
        }

        moveDown() {
            let moved = false;
            let merged = false;
            for (let c = 0; c < 4; c++) {
                const column = [
                    this.grid[3][c], 
                    this.grid[2][c], 
                    this.grid[1][c], 
                    this.grid[0][c]
                ];
                const newColumn = this.mergeTiles(column);
                
                for (let r = 0; r < 4; r++) {
                    if (this.grid[3-r][c] !== newColumn[r]) {
                        moved = true;
                    }
                    if (this.grid[3-r][c] !== newColumn[r] && newColumn[r] !== 0) {
                        merged = true;
                    }
                    this.grid[3-r][c] = newColumn[r];
                }
            }
            if (moved) {
                this.playSound('move');
            }
            if (merged) {
                this.playSound('merge');
            }
            return moved;
        }

        moveLeft() {
            let moved = false;
            let merged = false;
            for (let r = 0; r < 4; r++) {
                const row = this.grid[r];
                const newRow = this.mergeTiles(row);
                
                for (let c = 0; c < 4; c++) {
                    if (this.grid[r][c] !== newRow[c]) {
                        moved = true;
                    }
                    if (this.grid[r][c] !== newRow[c] && newRow[c] !== 0) {
                        merged = true;
                    }
                    this.grid[r][c] = newRow[c];
                }
            }
            if (moved) {
                this.playSound('move');
            }
            if (merged) {
                this.playSound('merge');
            }
            return moved;
        }

        moveRight() {
            let moved = false;
            let merged = false;
            for (let r = 0; r < 4; r++) {
                const row = [
                    this.grid[r][3], 
                    this.grid[r][2], 
                    this.grid[r][1], 
                    this.grid[r][0]
                ];
                const newRow = this.mergeTiles(row);
                
                for (let c = 0; c < 4; c++) {
                    if (this.grid[r][3-c] !== newRow[c]) {
                        moved = true;
                    }
                    if (this.grid[r][3-c] !== newRow[c] && newRow[c] !== 0) {
                        merged = true;
                    }
                    this.grid[r][3-c] = newRow[c];
                }
            }
            if (moved) {
                this.playSound('move');
            }
            if (merged) {
                this.playSound('merge');
            }
            return moved;
        }

        mergeTiles(line) {
            // Remove zeros
            line = line.filter(tile => tile !== 0);
            
            // Merge adjacent equal tiles
            for (let i = 0; i < line.length - 1; i++) {
                if (line[i] === line[i+1]) {
                    line[i] *= 2;
                    this.updateScore(line[i]);
                    line.splice(i+1, 1);
                }
            }
            
            // Pad with zeros
            while (line.length < 4) {
                line.push(0);
            }
            
            return line;
        }

        updateScore(mergedValue = 0) {
            // Increase score based on merged tile value
            if (mergedValue > 0) {
                this.score += mergedValue;
            }

            // Update score display
            if (this.scoreElement) {
                this.scoreElement.textContent = this.score;
            }
        }

        checkGameStatus() {
            // Check if game is over (no more moves possible)
            let gameOver = true;
            
            // Check if there are any empty cells
            for (let r = 0; r < 4; r++) {
                for (let c = 0; c < 4; c++) {
                    if (this.grid[r][c] === 0) {
                        gameOver = false;
                        break;
                    }
                }
                if (!gameOver) break;
            }

            // Check if any adjacent tiles can be merged
            if (gameOver) {
                for (let r = 0; r < 4; r++) {
                    for (let c = 0; c < 3; c++) {
                        if (this.grid[r][c] === this.grid[r][c+1]) {
                            gameOver = false;
                            break;
                        }
                    }
                    if (!gameOver) break;
                }
            }

            if (gameOver) {
                this.showGameOverModal();
            }
        }

        showGameOverModal() {
            // Existing game over logic
            const gameOverModal = new bootstrap.Modal(document.getElementById('gameOverModal'));
            const finalScoreElement = document.getElementById('final-score');
            const newGameAfterAdBtn = document.getElementById('new-game-after-ad');
            
            // Inject advertisement
            this.injectAdvertisement('game-over-ad-container');
            
            // Debugging: Log score and element
            console.log('Final Score:', this.score);
            console.log('Final Score Element:', finalScoreElement);
            
            // Display final score
            if (finalScoreElement) {
                finalScoreElement.textContent = this.score || 0;
                console.log('Set score to:', finalScoreElement.textContent);
            } else {
                console.error('Final score element not found!');
            }

            // Show modal
            gameOverModal.show();

            // Play game over sound
            this.playSound('gameOver');

            // Hide new game button initially
            if (newGameAfterAdBtn) {
                newGameAfterAdBtn.style.display = 'none';
            }

            // Add event listener to show new game button after ad interaction
            const adContainer = document.getElementById('7SAD15679F7024C91C1');
            if (adContainer) {
                // Wait for ad to load or be interacted with
                const adObserver = new MutationObserver((mutations) => {
                    mutations.forEach((mutation) => {
                        if (mutation.type === 'childList' && mutation.addedNodes.length) {
                            // Ad content loaded or changed
                            if (newGameAfterAdBtn) {
                                newGameAfterAdBtn.style.display = 'block';
                            }
                            // Stop observing after ad loads
                            adObserver.disconnect();
                        }
                    });
                });

                // Configure and start the observer
                adObserver.observe(adContainer, { 
                    childList: true, 
                    subtree: true 
                });

                // Fallback: show new game button after 10 seconds
                setTimeout(() => {
                    if (newGameAfterAdBtn) {
                        newGameAfterAdBtn.style.display = 'block';
                    }
                    adObserver.disconnect();
                }, 10000);
            }

            // Event listener for new game after ad
            if (newGameAfterAdBtn) {
                newGameAfterAdBtn.onclick = () => {
                    this.initializeGame();
                    gameOverModal.hide();
                };
            }
        }

        startTimer() {
            // Reset timer
            this.timeElapsed = 0;
            this.timerInterval = null;
            
            // Get timer display element
            const timerElement = document.getElementById('timer');
            
            // Start timer
            this.timerInterval = setInterval(() => {
                this.timeElapsed++;
                
                // Calculate minutes and seconds
                const minutes = Math.floor(this.timeElapsed / 60);
                const seconds = this.timeElapsed % 60;
                
                // Format time with leading zeros
                const formattedTime = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
                
                // Update timer display
                if (timerElement) {
                    timerElement.textContent = formattedTime;
                }
            }, 1000);
        }

        stopTimer() {
            // Clear the interval if it exists
            if (this.timerInterval) {
                clearInterval(this.timerInterval);
                this.timerInterval = null;
            }
        }

        addRandomTile() {
            const emptyCells = [];
            for (let r = 0; r < 4; r++) {
                for (let c = 0; c < 4; c++) {
                    if (this.grid[r][c] === 0) {
                        emptyCells.push({r, c});
                    }
                }
            }

            if (emptyCells.length > 0) {
                const {r, c} = emptyCells[Math.floor(Math.random() * emptyCells.length)];
                // 90% chance of 2, 10% chance of 4
                this.grid[r][c] = Math.random() < 0.9 ? 2 : 4;
            }
        }
    }

    // Expose Game2048 globally for debugging
    window.Game2048 = Game2048;
})();