// ========================
// SUDOKU GAME
// ========================

// Difficulty Configuration
const DIFFICULTY_CONFIG = {
    easy: { name: 'Easy', cellsToRemove: [30, 35], hints: 5 },
    medium: { name: 'Medium', cellsToRemove: [40, 45], hints: 3 },
    hard: { name: 'Hard', cellsToRemove: [50, 55], hints: 2 },
    expert: { name: 'Expert', cellsToRemove: [56, 60], hints: 1 }
};

// Level progression order
const LEVEL_ORDER = ['easy', 'medium', 'hard', 'expert'];

// Game State
let gameState = {
    difficulty: 'easy',
    grid: Array(9).fill(null).map(() => Array(9).fill(0)),
    solution: Array(9).fill(null).map(() => Array(9).fill(0)),
    givenCells: new Set(),
    selectedCell: null,
    notesMode: false,
    notes: Array(9).fill(null).map(() => Array(9).fill(null).map(() => new Set())),
    mistakes: 0,
    maxMistakes: 3,
    hintsRemaining: 5,
    timer: null,
    timeElapsed: 0,
    isPlaying: false
};

// Game Progress (Persistent)
let gameProgress = {
    gamesCompleted: 0,
    bestTimes: {
        easy: null,
        medium: null,
        hard: null,
        expert: null
    },
    stats: {
        easy: { completed: 0, bestTime: null, totalMistakes: 0, gamesPlayed: 0 },
        medium: { completed: 0, bestTime: null, totalMistakes: 0, gamesPlayed: 0 },
        hard: { completed: 0, bestTime: null, totalMistakes: 0, gamesPlayed: 0 },
        expert: { completed: 0, bestTime: null, totalMistakes: 0, gamesPlayed: 0 }
    },
    unlockedLevels: ['easy'] // Start with only Easy unlocked
};

// DOM Elements
const elements = {
    hud: document.querySelector('.hud'),
    mainMenuBtn: document.getElementById('main-menu-btn'),
    startScreen: document.getElementById('start-screen'),
    winScreen: document.getElementById('win-screen'),
    gameOverScreen: document.getElementById('game-over-screen'),
    sudokuGrid: document.getElementById('sudoku-grid'),
    controlsPanel: document.getElementById('controls-panel'),
    difficultyDisplay: document.getElementById('difficulty-display'),
    timerDisplay: document.getElementById('timer-display'),
    mistakesDisplay: document.getElementById('mistakes-display'),
    hintsDisplay: document.getElementById('hints-display'),
    gamesCompleted: document.getElementById('games-completed'),
    bestTimeDisplay: document.getElementById('best-time-display'),
    clearBtn: document.getElementById('clear-btn'),
    notesBtn: document.getElementById('notes-btn'),
    hintBtn: document.getElementById('hint-btn'),
    checkBtn: document.getElementById('check-btn'),
    newGameBtn: document.getElementById('new-game-btn'),
    retryBtn: document.getElementById('retry-btn'),
    menuBtnWin: document.getElementById('menu-btn-win'),
    menuBtnLose: document.getElementById('menu-btn-lose'),
    statsScreen: document.getElementById('stats-screen'),
    statsTableBody: document.getElementById('stats-table-body'),
    closeStatsBtn: document.getElementById('close-stats-btn'),
    viewStatsCard: document.getElementById('view-stats-card')
};

// Event Listeners
document.querySelectorAll('.difficulty-card').forEach(btn => {
    btn.addEventListener('click', () => {
        const difficulty = btn.dataset.difficulty;
        // Check if level is unlocked before starting
        if (isLevelUnlocked(difficulty)) {
            startGame(difficulty);
        }
    });
});

// Stats viewer
if (elements.viewStatsCard) {
    elements.viewStatsCard.addEventListener('click', showStats);
    // Add keyboard support
    elements.viewStatsCard.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' || e.key === ' ') {
            showStats();
        }
    });
}

// Close stats
if (elements.closeStatsBtn) {
    elements.closeStatsBtn.addEventListener('click', () => {
        elements.statsScreen.classList.add('hidden');
    });
}

elements.mainMenuBtn.addEventListener('click', backToMenu);
elements.clearBtn.addEventListener('click', clearCell);
elements.notesBtn.addEventListener('click', toggleNotesMode);
elements.hintBtn.addEventListener('click', giveHint);
elements.checkBtn.addEventListener('click', checkSolution);
elements.newGameBtn.addEventListener('click', () => startGame(gameState.difficulty));
elements.retryBtn.addEventListener('click', () => startGame(gameState.difficulty));
elements.menuBtnWin.addEventListener('click', backToMenu);
elements.menuBtnLose.addEventListener('click', backToMenu);

// Number pad buttons
document.querySelectorAll('.number-btn').forEach(btn => {
    btn.addEventListener('click', () => inputNumber(parseInt(btn.dataset.number)));
});

// Keyboard controls
document.addEventListener('keydown', handleKeyPress);

// Save state when leaving page or switching tabs
document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'hidden') {
        saveGameState();
    }
});

window.addEventListener('beforeunload', () => {
    saveGameState();
});

// ========================
// LEVEL LOCKING SYSTEM
// ========================

function getNextLevel(currentLevel) {
    const currentIndex = LEVEL_ORDER.indexOf(currentLevel);
    if (currentIndex === -1 || currentIndex >= LEVEL_ORDER.length - 1) {
        return null; // No next level
    }
    return LEVEL_ORDER[currentIndex + 1];
}

function unlockNextLevel(currentLevel) {
    const nextLevel = getNextLevel(currentLevel);
    if (nextLevel && !gameProgress.unlockedLevels.includes(nextLevel)) {
        gameProgress.unlockedLevels.push(nextLevel);
        saveProgress();
        return nextLevel;
    }
    return null;
}

function isLevelUnlocked(level) {
    return gameProgress.unlockedLevels.includes(level);
}

function updateDifficultyCardsUI() {
    document.querySelectorAll('.difficulty-card').forEach(card => {
        const difficulty = card.dataset.difficulty;
        const isUnlocked = isLevelUnlocked(difficulty);
        
        if (isUnlocked) {
            card.classList.remove('locked');
            // Remove lock overlay if exists
            const lockOverlay = card.querySelector('.lock-overlay');
            if (lockOverlay) {
                lockOverlay.remove();
            }
        } else {
            card.classList.add('locked');
            // Add lock overlay if not exists
            if (!card.querySelector('.lock-overlay')) {
                const lockOverlay = document.createElement('div');
                lockOverlay.className = 'lock-overlay';
                lockOverlay.innerHTML = '<i class="fas fa-lock"></i>';
                card.appendChild(lockOverlay);
            }
        }
    });
}

// ========================
// SUDOKU SOLVER & GENERATOR
// ========================

function isValid(grid, row, col, num) {
    // Check row
    for (let x = 0; x < 9; x++) {
        if (grid[row][x] === num) return false;
    }
    
    // Check column
    for (let x = 0; x < 9; x++) {
        if (grid[x][col] === num) return false;
    }
    
    // Check 3x3 box
    const startRow = row - (row % 3);
    const startCol = col - (col % 3);
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            if (grid[i + startRow][j + startCol] === num) return false;
        }
    }
    
    return true;
}

function solveSudoku(grid) {
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (grid[row][col] === 0) {
                for (let num = 1; num <= 9; num++) {
                    if (isValid(grid, row, col, num)) {
                        grid[row][col] = num;
                        
                        if (solveSudoku(grid)) {
                            return true;
                        }
                        
                        grid[row][col] = 0;
                    }
                }
                return false;
            }
        }
    }
    return true;
}

function generateSolvedGrid() {
    const grid = Array(9).fill(null).map(() => Array(9).fill(0));
    
    // Fill diagonal 3x3 boxes first
    for (let box = 0; box < 9; box += 3) {
        fillBox(grid, box, box);
    }
    
    // Solve the rest
    solveSudoku(grid);
    
    return grid;
}

function fillBox(grid, row, col) {
    const nums = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    shuffleArray(nums);
    
    let idx = 0;
    for (let i = 0; i < 3; i++) {
        for (let j = 0; j < 3; j++) {
            grid[row + i][col + j] = nums[idx++];
        }
    }
}

function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
}

function generatePuzzle(difficulty) {
    const solvedGrid = generateSolvedGrid();
    const puzzle = solvedGrid.map(row => [...row]);
    
    const config = DIFFICULTY_CONFIG[difficulty];
    const cellsToRemove = config.cellsToRemove[0] + 
        Math.floor(Math.random() * (config.cellsToRemove[1] - config.cellsToRemove[0] + 1));
    
    let removed = 0;
    const attempts = cellsToRemove * 3; // Max attempts to avoid infinite loop
    let attemptCount = 0;
    
    while (removed < cellsToRemove && attemptCount < attempts) {
        const row = Math.floor(Math.random() * 9);
        const col = Math.floor(Math.random() * 9);
        
        if (puzzle[row][col] !== 0) {
            puzzle[row][col] = 0;
            removed++;
        }
        attemptCount++;
    }
    
    return { puzzle, solution: solvedGrid };
}

// ========================
// GAME FUNCTIONS
// ========================

function startGame(difficulty) {
    // Check if we have a valid saved game within grace period for this difficulty
    const activeGame = localStorage.getItem('sudoku_game_state');
    if (activeGame) {
        try {
            const savedState = JSON.parse(activeGame);
            const GRACE_PERIOD_MS = 10000;
            const now = Date.now();
            const savedTime = savedState.timestamp || 0;
            
            // If within grace period AND same difficulty, restore it
            if (now - savedTime <= GRACE_PERIOD_MS && savedState.difficulty === difficulty) {
                console.log('Restoring game from grace period');
                loadGameState(); // This will handle the restoration
                return;
            }
        } catch (e) {
            console.error('Error checking saved game:', e);
        }
    }

    // Otherwise start fresh
    gameState.difficulty = difficulty;
    gameState.mistakes = 0;
    gameState.timeElapsed = 0;
    gameState.isPlaying = true;
    gameState.notesMode = false;
    gameState.selectedCell = null;
    gameState.hintsRemaining = DIFFICULTY_CONFIG[difficulty].hints;
    
    // Track game start for analytics
    if (typeof trackGameStart === 'function') {
        trackGameStart('sudoku');
    }
    gameState.notes = Array(9).fill(null).map(() => Array(9).fill(null).map(() => new Set()));
    
    // Generate puzzle
    const { puzzle, solution } = generatePuzzle(difficulty);
    gameState.grid = puzzle.map(row => [...row]);
    gameState.solution = solution;
    
    // Track given cells
    gameState.givenCells = new Set();
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (puzzle[row][col] !== 0) {
                gameState.givenCells.add(`${row}-${col}`);
            }
        }
    }
    
    updateUI();
    showScreen('game');
    renderGrid();
    startTimer();
    saveGameState();
    
    // Remove any existing grace period notification
    const notification = document.querySelector('.grace-period-notification');
    if (notification) notification.remove();
}

function renderGrid() {
    elements.sudokuGrid.innerHTML = '';
    
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            const cell = document.createElement('div');
            cell.className = 'sudoku-cell';
            cell.dataset.row = row;
            cell.dataset.col = col;
            
            const cellKey = `${row}-${col}`;
            const value = gameState.grid[row][col];
            
            if (gameState.givenCells.has(cellKey)) {
                cell.classList.add('given');
                cell.textContent = value;
            } else if (value !== 0) {
                cell.textContent = value;
                // Check if correct
                if (value === gameState.solution[row][col]) {
                    cell.classList.add('correct');
                } else {
                    cell.classList.add('incorrect');
                }
            } else if (gameState.notesMode && gameState.notes[row][col].size > 0) {
                // Show notes
                const notesDiv = document.createElement('div');
                notesDiv.className = 'notes';
                for (let i = 1; i <= 9; i++) {
                    const span = document.createElement('span');
                    if (gameState.notes[row][col].has(i)) {
                        span.textContent = i;
                    }
                    notesDiv.appendChild(span);
                }
                cell.appendChild(notesDiv);
            }
            
            if (gameState.selectedCell && 
                gameState.selectedCell.row === row && 
                gameState.selectedCell.col === col) {
                cell.classList.add('selected');
            }
            
            // Highlight same row, column, and box
            if (gameState.selectedCell) {
                const selRow = gameState.selectedCell.row;
                const selCol = gameState.selectedCell.col;
                
                if (row === selRow || col === selCol) {
                    cell.classList.add('highlighted');
                }
                
                // Same 3x3 box
                if (Math.floor(row / 3) === Math.floor(selRow / 3) &&
                    Math.floor(col / 3) === Math.floor(selCol / 3)) {
                    cell.classList.add('highlighted');
                }
            }
            
            cell.addEventListener('click', () => selectCell(row, col));
            
            elements.sudokuGrid.appendChild(cell);
        }
    }
}

function selectCell(row, col) {
    const cellKey = `${row}-${col}`;
    
    // Don't select given cells
    if (gameState.givenCells.has(cellKey)) {
        return;
    }
    
    gameState.selectedCell = { row, col };
    renderGrid();
}

function inputNumber(num) {
    if (!gameState.selectedCell || !gameState.isPlaying) return;
    
    const { row, col } = gameState.selectedCell;
    const cellKey = `${row}-${col}`;
    
    // Don't modify given cells
    if (gameState.givenCells.has(cellKey)) return;
    
    if (gameState.notesMode) {
        // Toggle note
        if (gameState.notes[row][col].has(num)) {
            gameState.notes[row][col].delete(num);
        } else {
            gameState.notes[row][col].add(num);
        }
    } else {
        // Clear notes for this cell
        gameState.notes[row][col].clear();
        
        // Input number
        gameState.grid[row][col] = num;
        
        // Check if correct
        if (num !== gameState.solution[row][col]) {
            gameState.mistakes++;
            updateUI();
            
            if (gameState.mistakes >= gameState.maxMistakes) {
                gameOver();
                return;
            }
        }
        
        // Check if puzzle is complete
        if (isPuzzleComplete()) {
            winGame();
            return;
        }
    }
    
    renderGrid();
    saveGameState();
}

function clearCell() {
    if (!gameState.selectedCell || !gameState.isPlaying) return;
    
    const { row, col } = gameState.selectedCell;
    const cellKey = `${row}-${col}`;
    
    if (gameState.givenCells.has(cellKey)) return;
    
    gameState.grid[row][col] = 0;
    gameState.notes[row][col].clear();
    renderGrid();
    saveGameState();
}

function toggleNotesMode() {
    gameState.notesMode = !gameState.notesMode;
    elements.notesBtn.classList.toggle('active', gameState.notesMode);
    renderGrid();
}

function giveHint() {
    if (!gameState.isPlaying || gameState.hintsRemaining <= 0) return;
    
    // Find empty cells
    const emptyCells = [];
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            const cellKey = `${row}-${col}`;
            if (!gameState.givenCells.has(cellKey) && gameState.grid[row][col] === 0) {
                emptyCells.push({ row, col });
            }
        }
    }
    
    if (emptyCells.length === 0) return;
    
    // Pick random empty cell
    const randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
    const { row, col } = randomCell;
    
    gameState.grid[row][col] = gameState.solution[row][col];
    gameState.notes[row][col].clear();
    gameState.hintsRemaining--;
    
    updateUI();
    renderGrid();
    saveGameState();
    
    if (gameState.hintsRemaining === 0) {
        elements.hintBtn.disabled = true;
    }
    
    // Check if puzzle is complete
    if (isPuzzleComplete()) {
        winGame();
    }
}

function checkSolution() {
    if (!gameState.isPlaying) return;
    
    let hasErrors = false;
    
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            const cellKey = `${row}-${col}`;
            if (!gameState.givenCells.has(cellKey) && gameState.grid[row][col] !== 0) {
                if (gameState.grid[row][col] !== gameState.solution[row][col]) {
                    hasErrors = true;
                }
            }
        }
    }
    
    if (hasErrors) {
        showNotification('❌ Some numbers are incorrect. Keep trying!', 'error');
    } else if (isPuzzleComplete()) {
        winGame();
    } else {
        showNotification('✅ So far so good! Keep going!', 'success');
    }
}

// ========================
// NOTIFICATION SYSTEM
// ========================

function showNotification(message, type = 'info') {
    // Remove existing notification if any
    const existing = document.querySelector('.game-notification');
    if (existing) {
        existing.remove();
    }
    
    // Create notification
    const notification = document.createElement('div');
    notification.className = `game-notification ${type}`;
    notification.textContent = message;
    
    document.body.appendChild(notification);
    
    // Trigger animation
    setTimeout(() => notification.classList.add('show'), 10);
    
    // Auto dismiss after 3 seconds
    setTimeout(() => {
        notification.classList.remove('show');
        setTimeout(() => notification.remove(), 300);
    }, 3000);
}

function isPuzzleComplete() {
    for (let row = 0; row < 9; row++) {
        for (let col = 0; col < 9; col++) {
            if (gameState.grid[row][col] === 0) return false;
            if (gameState.grid[row][col] !== gameState.solution[row][col]) return false;
        }
    }
    return true;
}

function handleKeyPress(e) {
    if (!gameState.isPlaying) return;
    
    // Number keys 1-9
    if (e.key >= '1' && e.key <= '9') {
        inputNumber(parseInt(e.key));
    }
    
    // Delete/Backspace to clear
    if (e.key === 'Delete' || e.key === 'Backspace') {
        clearCell();
    }
    
    // Arrow keys for navigation
    if (gameState.selectedCell && ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
        e.preventDefault();
        let { row, col } = gameState.selectedCell;
        
        switch(e.key) {
            case 'ArrowUp': row = Math.max(0, row - 1); break;
            case 'ArrowDown': row = Math.min(8, row + 1); break;
            case 'ArrowLeft': col = Math.max(0, col - 1); break;
            case 'ArrowRight': col = Math.min(8, col + 1); break;
        }
        
        selectCell(row, col);
    }
    
    // N for notes mode
    if (e.key.toLowerCase() === 'n') {
        toggleNotesMode();
    }
    
    // H for hint
    if (e.key.toLowerCase() === 'h') {
        giveHint();
    }
}

// ========================
// TIMER
// ========================

function startTimer() {
    if (gameState.timer) {
        clearInterval(gameState.timer);
    }
    
    gameState.timer = setInterval(() => {
        gameState.timeElapsed++;
        updateTimerDisplay();
        saveGameState();
    }, 1000);
}

function stopTimer() {
    if (gameState.timer) {
        clearInterval(gameState.timer);
        gameState.timer = null;
    }
}

function updateTimerDisplay() {
    const minutes = Math.floor(gameState.timeElapsed / 60);
    const seconds = gameState.timeElapsed % 60;
    elements.timerDisplay.textContent = 
        `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}

function formatTime(seconds) {
    const minutes = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}

// ========================
// WIN/LOSE
// ========================

function winGame() {
    gameState.isPlaying = false;
    stopTimer();
    
    // Track game end for analytics
    const duration = gameState.timeElapsed * 1000;
    if (typeof trackGameEnd === 'function') {
        trackGameEnd('sudoku', duration, {
            metrics: {
                difficulty: gameState.difficulty,
                mistakes: gameState.mistakes,
                hintsUsed: DIFFICULTY_CONFIG[gameState.difficulty].hints - gameState.hintsRemaining,
                result: 'win'
            }
        });
    }
    
    // Update stats
    gameProgress.gamesCompleted++;
    
    const currentTime = gameState.timeElapsed;
    const difficulty = gameState.difficulty;
    
    if (!gameProgress.bestTimes[difficulty] || currentTime < gameProgress.bestTimes[difficulty]) {
        gameProgress.bestTimes[difficulty] = currentTime;
    }
    
    // Update detailed stats
    updateStats(difficulty, true, currentTime, gameState.mistakes);
    
    // Unlock next level
    const nextLevel = unlockNextLevel(difficulty);
    
    saveProgress();
    
    // Update difficulty cards UI to show newly unlocked level
    updateDifficultyCardsUI();
    
    // Update win screen
    document.getElementById('win-time').textContent = formatTime(gameState.timeElapsed);
    document.getElementById('win-mistakes').textContent = gameState.mistakes;
    document.getElementById('win-difficulty').textContent = DIFFICULTY_CONFIG[difficulty].name;
    
    showScreen('win');
    clearGameState();
}

function gameOver() {
    gameState.isPlaying = false;
    stopTimer();
    
    // Track game end for analytics (even on game over)
    const duration = gameState.timeElapsed * 1000;
    if (typeof trackGameEnd === 'function') {
        trackGameEnd('sudoku', duration, {
            metrics: {
                difficulty: gameState.difficulty,
                mistakes: gameState.mistakes,
                hintsUsed: DIFFICULTY_CONFIG[gameState.difficulty].hints - gameState.hintsRemaining,
                result: 'loss'
            }
        });
    }
    
    // Update stats (game not completed)
    updateStats(gameState.difficulty, false, gameState.timeElapsed, gameState.mistakes);
    
    // Update lose screen
    document.getElementById('lose-time').textContent = formatTime(gameState.timeElapsed);
    document.getElementById('lose-mistakes').textContent = gameState.mistakes;
    
    showScreen('game-over');
    clearGameState();
}

function backToMenu() {
    // Only save if game was active AND player has made some moves
    if (gameState.isPlaying) {
        // Check if player has made any moves (filled any non-given cells)
        let playerMoves = 0;
        for (let row = 0; row < 9; row++) {
            for (let col = 0; col < 9; col++) {
                const cellKey = `${row}-${col}`;
                if (!gameState.givenCells.has(cellKey) && gameState.grid[row][col] !== 0) {
                    playerMoves++;
                }
            }
        }
        
        // Only save if player has made at least one move
        if (playerMoves > 0) {
            // Explicitly save with timestamp for grace period
            const state = {
                difficulty: gameState.difficulty,
                grid: gameState.grid,
                solution: gameState.solution,
                givenCells: Array.from(gameState.givenCells),
                notes: gameState.notes.map(row => row.map(cell => Array.from(cell))),
                mistakes: gameState.mistakes,
                hintsRemaining: gameState.hintsRemaining,
                timeElapsed: gameState.timeElapsed,
                notesMode: gameState.notesMode,
                timestamp: Date.now()
            };
            localStorage.setItem('sudoku_game_state', JSON.stringify(state));
        } else {
            // No moves made, clear any existing state
            localStorage.removeItem('sudoku_game_state');
        }
    }
    
    // Mark game as inactive
    stopTimer();
    gameState.isPlaying = false;
    showScreen('start');
}

// ========================
// UI HELPERS
// ========================

function updateUI() {
    elements.difficultyDisplay.textContent = DIFFICULTY_CONFIG[gameState.difficulty].name;
    elements.mistakesDisplay.textContent = `${gameState.mistakes}/${gameState.maxMistakes}`;
    elements.hintsDisplay.textContent = gameState.hintsRemaining;
    updateTimerDisplay();
}

function showScreen(screen) {
    // Hide all screens
    elements.startScreen.classList.add('hidden');
    elements.winScreen.classList.add('hidden');
    elements.gameOverScreen.classList.add('hidden');
    
    const gameScreen = document.getElementById('game-screen');
    
    switch(screen) {
        case 'start':
            renderStartScreen();
            elements.startScreen.classList.remove('hidden');
            if (gameScreen) gameScreen.classList.add('hidden');
            updateDifficultyCardsUI();
            break;
        case 'game':
            if (gameScreen) {
                gameScreen.classList.remove('hidden');
                // Trigger layout recalculation
                if (window.gameLayout) {
                    requestAnimationFrame(() => {
                        requestAnimationFrame(() => {
                            window.gameLayout.performLayout();
                        });
                    });
                }
            }
            elements.hintBtn.disabled = false;
            elements.notesBtn.classList.remove('active');
            break;
        case 'win':
            elements.winScreen.classList.remove('hidden');
            if (gameScreen) gameScreen.classList.add('hidden');
            break;
        case 'game-over':
            elements.gameOverScreen.classList.remove('hidden');
            if (gameScreen) gameScreen.classList.add('hidden');
            break;
    }
}

function renderStartScreen() {
    // Load fresh stats from API
    loadGameStats();
    
    elements.gamesCompleted.textContent = gameProgress.gamesCompleted;
    
    // Show best time across all difficulties
    const allTimes = Object.values(gameProgress.bestTimes).filter(t => t !== null);
    if (allTimes.length > 0) {
        const bestOverall = Math.min(...allTimes);
        elements.bestTimeDisplay.textContent = formatTime(bestOverall);
    } else {
        elements.bestTimeDisplay.textContent = '--:--';
    }
}

// ========================
// STATE PERSISTENCE
// ========================

function saveGameState() {
    if (!gameState.isPlaying) return;
    
    const state = {
        difficulty: gameState.difficulty,
        grid: gameState.grid,
        solution: gameState.solution,
        givenCells: Array.from(gameState.givenCells),
        notes: gameState.notes.map(row => row.map(cell => Array.from(cell))),
        mistakes: gameState.mistakes,
        hintsRemaining: gameState.hintsRemaining,
        timeElapsed: gameState.timeElapsed,
        notesMode: gameState.notesMode,
        timestamp: Date.now() // Add timestamp for grace period
    };
    
    localStorage.setItem('sudoku_game_state', JSON.stringify(state));
}

function loadGameState() {
    const saved = localStorage.getItem('sudoku_game_state');
    if (!saved) return false;
    
    try {
        const state = JSON.parse(saved);
        
        // Check grace period (10 seconds)
        const GRACE_PERIOD_MS = 10000;
        const now = Date.now();
        const savedTime = state.timestamp || 0;
        const timeDiff = now - savedTime;
        
        if (timeDiff > GRACE_PERIOD_MS) {
            // Grace period expired, clear state
            console.log('Game state expired (grace period exceeded)');
            localStorage.removeItem('sudoku_game_state');
            return false;
        }
        
        gameState.difficulty = state.difficulty;
        gameState.grid = state.grid;
        gameState.solution = state.solution;
        gameState.givenCells = new Set(state.givenCells);
        gameState.notes = state.notes.map(row => row.map(cell => new Set(cell)));
        gameState.mistakes = state.mistakes;
        gameState.hintsRemaining = state.hintsRemaining;
        gameState.timeElapsed = state.timeElapsed;
        gameState.notesMode = state.notesMode;
        gameState.isPlaying = true;
        
        updateUI();
        showScreen('game');
        renderGrid();
        startTimer();
        
        return true;
    } catch (e) {
        console.error('Failed to load game state:', e);
        return false;
    }
}

function clearGameState() {
    localStorage.removeItem('sudoku_game_state');
}

function saveProgress() {
    localStorage.setItem('sudoku_progress', JSON.stringify(gameProgress));
}

async function loadGameStats() {
    try {
        const response = await fetch('/api/sessions/game-stats/sudoku');
        if (response.ok) {
            const data = await response.json();
            
            // Update games completed display (wins = completed games)
            if (elements.gamesCompleted) {
                elements.gamesCompleted.textContent = data.totalWins || 0;
            }
        }
    } catch (error) {
        console.error('Error loading game stats:', error);
    }
}

function loadProgress() {
    const saved = localStorage.getItem('sudoku_progress');
    if (saved) {
        try {
            const progress = JSON.parse(saved);
            gameProgress = progress;
        } catch (e) {
            console.error('Failed to load progress:', e);
        }
    }
}

function saveProgress() {
    localStorage.setItem('sudoku_progress', JSON.stringify(gameProgress));
}

function updateStats(difficulty, completed, time, mistakes) {
    if (!gameProgress.stats[difficulty]) {
        gameProgress.stats[difficulty] = { completed: 0, bestTime: null, totalMistakes: 0, gamesPlayed: 0 };
    }
    
    const stats = gameProgress.stats[difficulty];
    stats.gamesPlayed++;
    stats.totalMistakes += mistakes;
    
    if (completed) {
        stats.completed++;
        
        // Update best time
        if (stats.bestTime === null || time < stats.bestTime) {
            stats.bestTime = time;
        }
    }
    
    saveProgress();
}

function showStats() {
    // Fetch fresh stats from API and display
    fetch('/api/sessions/game-stats/sudoku')
        .then(response => response.json())
        .then(data => {
            elements.statsTableBody.innerHTML = '';
            
            // Use detailed stats from API if available, otherwise fall back to localStorage
            const statsToDisplay = data.detailedStats && Object.keys(data.detailedStats).length > 0 
                ? data.detailedStats 
                : gameProgress.stats;
            
            // Define difficulty order for consistent display
            const difficultyOrder = ['easy', 'medium', 'hard', 'expert'];
            
            difficultyOrder.forEach(difficulty => {
                const stats = statsToDisplay[difficulty];
                if (!stats) return; // Skip if no data
                
                const row = document.createElement('tr');
                const difficultyName = difficulty.charAt(0).toUpperCase() + difficulty.slice(1);
                const avgMistakes = stats.gamesPlayed > 0 ? ((stats.totalMistakes || 0) / stats.gamesPlayed).toFixed(1) : '-';
                
                row.innerHTML = `
                    <td>${difficultyName}</td>
                    <td class="stat-highlight">${stats.completions || stats.completed || 0}</td>
                    <td>${formatTime(stats.bestTime)}</td>
                    <td>${avgMistakes}</td>
                `;
                elements.statsTableBody.appendChild(row);
            });
            
            elements.statsScreen.classList.remove('hidden');
        })
        .catch(error => {
            console.error('Error fetching stats:', error);
            // Fall back to localStorage stats
            displayLocalStats();
        });
}

function displayLocalStats() {
    elements.statsTableBody.innerHTML = '';
    
    Object.entries(gameProgress.stats).forEach(([level, data]) => {
        const row = document.createElement('tr');
        const levelName = level.charAt(0).toUpperCase() + level.slice(1);
        const avgMistakes = data.gamesPlayed > 0 ? (data.totalMistakes / data.gamesPlayed).toFixed(1) : '-';
        
        row.innerHTML = `
            <td>${levelName}</td>
            <td class="stat-highlight">${data.completed}</td>
            <td>${formatTime(data.bestTime)}</td>
            <td>${avgMistakes}</td>
        `;
        elements.statsTableBody.appendChild(row);
    });
    
    elements.statsScreen.classList.remove('hidden');
}

function formatTime(seconds) {
    if (seconds === null) return '-';
    const mins = Math.floor(seconds / 60).toString().padStart(2, '0');
    const secs = (seconds % 60).toString().padStart(2, '0');
    return `${mins}:${secs}`;
}

// ========================
// GRACE PERIOD SYSTEM
// ========================

let gracePeriodInterval = null;

function startGracePeriodChecker() {
    if (gracePeriodInterval) clearInterval(gracePeriodInterval);
    
    // Check every second
    gracePeriodInterval = setInterval(checkGracePeriod, 1000);
    
    // Also check immediately
    checkGracePeriod();
}

function checkGracePeriod() {
    // If game is active in current session, don't show notification
    if (gameState.isPlaying && !document.hidden) {
        const notification = document.querySelector('.grace-period-notification');
        if (notification) notification.remove();
        return;
    }

    const activeGame = localStorage.getItem('sudoku_game_state');
    if (!activeGame) {
        const notification = document.querySelector('.grace-period-notification');
        if (notification) notification.remove();
        return;
    }

    try {
        const savedState = JSON.parse(activeGame);
        const GRACE_PERIOD_MS = 10000;
        const now = Date.now();
        const savedTime = savedState.timestamp || 0;
        const timeDiff = now - savedTime;
        const remainingTime = Math.ceil((GRACE_PERIOD_MS - timeDiff) / 1000);

        // If expired
        if (remainingTime <= 0) {
            localStorage.removeItem('sudoku_game_state');
            const notification = document.querySelector('.grace-period-notification');
            if (notification) notification.remove();
            return;
        }

        // If we are in the menu (game not active in memory) OR page is hidden
        // But we have an active game in storage that is valid
        if (!gameState.isPlaying || document.hidden) {
            showGracePeriodNotification(remainingTime, savedState.difficulty);
        }
    } catch (e) {
        console.error('Error checking grace period:', e);
    }
}

function showGracePeriodNotification(remainingTime, difficulty) {
    let notification = document.querySelector('.grace-period-notification');
    const GRACE_PERIOD_MS = 10000;
    const progressPercent = (remainingTime / (GRACE_PERIOD_MS / 1000)) * 100;
    
    const difficultyName = DIFFICULTY_CONFIG[difficulty]?.name || difficulty;
    
    if (!notification) {
        notification = document.createElement('div');
        notification.className = 'game-notification grace-period-notification show';
        notification.innerHTML = `
            <div class="notification-icon"><i class="fas fa-clock"></i></div>
            <div class="notification-content">
                <div class="notification-title">Game Session Active</div>
                <div class="notification-message">Resuming ${difficultyName} puzzle...</div>
            </div>
            <div class="notification-timer">${remainingTime}s</div>
            <div class="notification-progress-bar" style="width: ${progressPercent}%"></div>
        `;
        
        notification.addEventListener('click', () => {
            // Resume game by loading state
            if (loadGameState()) {
                notification.remove();
            }
        });
        
        document.body.appendChild(notification);
    } else {
        // Update existing notification
        const timer = notification.querySelector('.notification-timer');
        if (timer) timer.textContent = `${remainingTime}s`;
        
        const progressBar = notification.querySelector('.notification-progress-bar');
        if (progressBar) progressBar.style.width = `${progressPercent}%`;
    }
}

// Back to Portal
const backToPortalBtn = document.getElementById('back-to-portal-btn');
if (backToPortalBtn) {
    backToPortalBtn.addEventListener('click', () => {
        window.location.href = '/';
    });
}

// Initialize Responsive Layout Module
let gameLayout = null;
if (window.ResponsiveGameLayout) {
    gameLayout = new ResponsiveGameLayout({
        gameScreenId: 'game-screen',
        topBarSelector: '.game-top-bar',
        bottomBarSelector: '.control-panel',
        boardWrapperSelector: '.game-board-wrapper',
        boardId: 'sudoku-grid',
        hasTopLeftBar: true,
        hasBottomRightBar: true,
        boardSizeMode: 'square',
        gap: 24
    });
    window.gameLayout = gameLayout;
}

loadProgress();
loadGameStats(); // Load stats from API

// Start grace period checker
startGracePeriodChecker();

// Try to resume game or show start screen
if (!loadGameState()) {
    showScreen('start');
}
