// Multiplayer Client Manager
class MultiplayerClient {
    constructor(game) {
        this.game = game;
        this.socket = null;
        this.playerId = null;
        this.username = null;
        this.currentGameId = null;
        this.isMultiplayer = false;
        this.activePlayers = [];
        this.pendingChallenges = new Map();
        this.selectedBoardSize = 15; // Default board size for multiplayer
        this.opponent = null; // Track opponent for rematch
        this.opponentId = null;
        this.lastGameResult = null;
    }
    
    
    // Connect to server
    async connect() {
        if (typeof io === 'undefined') {
            this.showMessage('Socket.io library not loaded. Please check your internet connection.', 'error');
            return;
        }

        // Show username modal immediately if not saved
        const savedUsername = await window.gameStorage.getItem('connect5_username');
        if (!savedUsername) {
            this.showUsernameModal();
        } else {
            this.username = savedUsername; // Pre-load username
        }

        // Dynamically construct proxy URLs based on current origin
        const targetUrl = window.location.origin;
        const servers = [
            targetUrl, // Primary (Production/Local)
            'http://localhost:3000' // Failover for local dev
        ];

        let connected = false;
        const loadingEl = document.querySelector('.loading');

        for (const serverUrl of servers) {
            if (connected) break;
            
            try {
                if (loadingEl) loadingEl.textContent = `Connecting to ${serverUrl}...`;
                console.log(`Attempting connection to: ${serverUrl}`);
                await this.tryConnect(serverUrl);
                connected = true;
                console.log(`✅ Successfully connected to: ${serverUrl}`);
                if (loadingEl) loadingEl.textContent = 'Connected! verifying functionality...';
            } catch (error) {
                console.warn(`❌ Failed to connect to ${serverUrl}:`, error);
            }
        }



        if (!connected) {
            this.showMessage('Failed to connect to any multiplayer server. Please try again later.', 'error');
            const loading = document.querySelector('.loading');
            if (loading) loading.textContent = 'Connection failed.';
        }
        
        // Setup board size selector buttons
        document.querySelectorAll('.size-btn-mp').forEach(btn => {
            btn.addEventListener('click', (e) => {
                document.querySelectorAll('.size-btn-mp').forEach(b => b.classList.remove('active'));
                e.target.classList.add('active');
                this.selectedBoardSize = parseInt(e.target.dataset.size);
            });
        });
    }

    tryConnect(url) {
        return new Promise((resolve, reject) => {
            const socketOptions = {
                reconnection: false, // We handle reconnection manually for failover
                timeout: 5000,
                transports: ['websocket', 'polling']
            };

            const tempSocket = io(url, socketOptions);
            
            // Set up ALL listeners BEFORE the connection completes
            // This prevents race conditions
            this.setupSocketListeners(tempSocket);

            const timeout = setTimeout(() => {
                if (!tempSocket.connected) {
                    tempSocket.close();
                    reject(new Error('Connection timed out'));
                }
            }, 5000);

            tempSocket.on('connect', async () => {
                clearTimeout(timeout);
                this.socket = tempSocket;
                console.log('✅ Socket connected, listeners ready');
                
                // Now that listeners are set up, handle auto-registration
                const savedUsername = await window.gameStorage.getItem('connect5_username') || this.username;
                if (savedUsername) {
                    console.log('Auto-registering with saved username:', savedUsername);
                    this.registerPlayer(savedUsername);
                }
                
                resolve();
            });

            tempSocket.on('connect_error', (err) => {
                clearTimeout(timeout);
                tempSocket.close();
                reject(err);
            });
        });
    }

    setupSocketListeners(socket) {
        if (!socket) return;

        // Safety timeout: If we are connected but don't get a player list or login prompt within 5 seconds, warn the user.
        setTimeout(() => {
            const loading = document.querySelector('.loading');
            if (loading && loading.textContent.includes('Connecting')) {
                 loading.textContent = 'Connection successful, but server response is slow...';
            } else if (loading && loading.textContent === 'Loading players...') {
                 loading.innerHTML = 'Server not responding. <a href="#" onclick="window.multiplayerClient.connect()">Retry</a>';
            }
        }, 5000);
        
        socket.on('disconnect', () => {
            console.log('❌ Disconnected from server');
            this.handleDisconnect();
        });
        
        socket.on('registration_result', (data) => {
            console.log('📥 Received registration_result:', data);
            this.handleRegistration(data);
        });
        
        socket.on('active_players_update', (players) => {
            this.updateActivePlayers(players);
        });
        
        socket.on('challenge_received', (data) => {
            this.showChallengeNotification(data);
        });
        
        socket.on('challenge_result', (data) => {
            this.handleChallengeResult(data);
        });
        
        socket.on('challenge_declined', (data) => {
            this.showMessage(`${data.by} declined your challenge`, 'error');
        });
        
        socket.on('game_started', (data) => {
            this.startMultiplayerGame(data);
        });
        
        socket.on('opponent_move', (data) => {
            this.handleOpponentMove(data);
        });
        
        socket.on('move_result', (data) => {
            this.handleMoveResult(data);
        });
        
        socket.on('game_ended', (data) => {
            this.handleGameEnded(data);
        });
        
        socket.on('rematch_request', (data) => {
            this.handleRematchRequest(data);
        });
        
        socket.on('rematch_accepted', (data) => {
            this.startMultiplayerGame(data);
        });
        
        socket.on('rematch_declined', (data) => {
            this.showMessage(`${data.by} declined the rematch`, 'error');
            document.getElementById('gameOverModal').classList.remove('active');
            this.returnToLobby();
        });
        
        socket.on('opponent_disconnected', (data) => {
            this.showMessage(data.message + '. Waiting for reconnection...', 'warning');
        });

        socket.on('opponent_reconnected', (data) => {
            this.showMessage(data.message, 'success');
        });
        
        // Send heartbeat every 30 seconds
        setInterval(() => {
            if (this.socket && this.socket.connected) {
                this.socket.emit('heartbeat');
            }
        }, 30000);
    }
    
    // Show username input modal
    showUsernameModal() {
        const modal = document.getElementById('usernameModal');
        if (modal) {
            modal.classList.add('active');
        }
    }
    
    // Register player
    async registerPlayer(username) {
        this.username = username;
        await window.gameStorage.setItem('connect5_username', username);
        
        // Hide username modal immediately for better UX
        const modal = document.getElementById('usernameModal');
        if (modal) {
            modal.classList.remove('active');
        }

        // Show loading state
        const loading = document.querySelector('.loading');
        if (loading) {
            loading.textContent = 'Registering...';
        }

        if (!this.socket || !this.socket.connected) {
            console.log('Socket not ready yet, username saved and will be sent on connect.');
            if (loading) {
                loading.textContent = 'Connecting to server...';
            }
            return;
        }
        
        console.log('Emitting register_player for:', username);
        this.socket.emit('register_player', { username });
    }
    
    // Handle registration response
    async handleRegistration(data) {
        if (data.success) {
            this.playerId = data.player.id;
            this.username = data.player.username;
            await window.gameStorage.setItem('connect5_username', this.username);
            console.log('Username saved to IndexedDB');
            
            // Hide username modal (if visible)
            const modal = document.getElementById('usernameModal');
            if (modal) {
                modal.classList.remove('active');
            }
            
            // Show multiplayer panel
            const multiplayerPanel = document.getElementById('multiplayerPanel');
            if (multiplayerPanel) {
                multiplayerPanel.style.display = 'block';
            }
            
            // Update player stats display
            document.getElementById('playerUsername').textContent = this.username;
            document.getElementById('playerWins').textContent = data.player.stats.wins;
            document.getElementById('playerLosses').textContent = data.player.stats.losses;
            document.getElementById('playerDraws').textContent = data.player.stats.draws;
            
            this.showMessage(`Welcome back, ${this.username}!`, 'success');
            
            // Request active players
            this.socket.emit('request_active_players');

            // Check for active game restoration
            if (data.activeGame) {
                console.log(' restoring active game:', data.activeGame);
                this.startMultiplayerGame(data.activeGame);
            }
        } else {
            // Registration failed - clear saved username and show modal
            localStorage.removeItem('connect5_username');
            this.showMessage(data.error, 'error');
            this.showUsernameModal();
        }
    }
    
    // Update active players list
    updateActivePlayers(players) {
        this.activePlayers = players.filter(p => p.username !== this.username);
        
        const container = document.getElementById('activePlayersList');
        if (!container) return;
        
        if (this.activePlayers.length === 0) {
            container.innerHTML = '<div class="no-players">No other players online</div>';
            return;
        }
        
        container.innerHTML = this.activePlayers.map(player => `
            <div class="player-item">
                <div class="player-info">
                    <span class="player-name">${player.username}</span>
                    <span class="player-stats">${player.total_wins}W - ${player.total_losses}L - ${player.total_draws}D</span>
                </div>
                <button class="challenge-btn" onclick="multiplayerClient.sendChallenge('${player.username}')">
                    Challenge
                </button>
            </div>
        `).join('');
    }
    
    // Send challenge
    sendChallenge(targetUsername) {
        this.socket.emit('send_challenge', { 
            targetUsername, 
            boardSize: this.selectedBoardSize 
        });
        this.showMessage(`Challenge sent to ${targetUsername} (${this.selectedBoardSize}×${this.selectedBoardSize})`, 'info');
    }
    
    // Handle challenge result
    handleChallengeResult(data) {
        if (!data.success) {
            this.showMessage(data.error, 'error');
        }
    }
    
    // Show challenge notification
    showChallengeNotification(data) {
        this.pendingChallenges.set(data.challengeId, data);
        
        const notification = document.createElement('div');
        notification.className = 'challenge-notification';
        notification.innerHTML = `
            <div class="challenge-content">
                <h3>Challenge Received!</h3>
                <p><strong>${data.from}</strong> wants to play</p>
                <p>Board size: ${data.boardSize}×${data.boardSize}</p>
                <div class="challenge-actions">
                    <button class="accept-btn" onclick="multiplayerClient.acceptChallenge('${data.challengeId}')">
                        Accept
                    </button>
                    <button class="decline-btn" onclick="multiplayerClient.declineChallenge('${data.challengeId}')">
                        Decline
                    </button>
                </div>
            </div>
        `;
        
        document.body.appendChild(notification);
        setTimeout(() => notification.classList.add('active'), 10);
    }
    
    // Accept challenge
    acceptChallenge(challengeId) {
        this.socket.emit('accept_challenge', { challengeId });
        this.pendingChallenges.delete(challengeId);
        
        // Remove notification
        const notifications = document.querySelectorAll('.challenge-notification');
        notifications.forEach(n => n.remove());
    }
    
    // Decline challenge
    declineChallenge(challengeId) {
        this.socket.emit('decline_challenge', { challengeId });
        this.pendingChallenges.delete(challengeId);
        
        // Remove notification
        const notifications = document.querySelectorAll('.challenge-notification');
        notifications.forEach(n => n.remove());
    }
    
    // Start multiplayer game
    startMultiplayerGame(data) {
        console.log('🎮 Starting multiplayer game:', data);
        this.isMultiplayer = true;
        this.currentGameId = data.gameId;
        this.mySymbol = data.yourSymbol;
        this.opponent = data.opponent;
        this.opponentId = data.opponentId; // Store for rematch
        this.myTurn = data.yourTurn;
        
        // Show surrender button
        const surrenderBtn = document.getElementById('surrenderBtn');
        if (surrenderBtn) {
            surrenderBtn.style.display = 'flex';
        }
        
        // Update UI - hide multiplayer lobby, show game board
        document.getElementById('multiplayerPanel').style.display = 'none';
        document.getElementById('gameControls').style.display = 'grid';
        document.querySelector('.board-wrapper').style.display = 'flex';
        // Status bar is part of gameControls
        
        // Set board size
        document.querySelectorAll('.size-btn').forEach(btn => {
            btn.classList.toggle('active', parseInt(btn.dataset.size) === data.boardSize);
        });
        
        // Reset game board
        this.game.boardSize = data.boardSize;
        this.game.currentPlayer = this.mySymbol;  // Set to our symbol
        this.game.gameActive = true;
        this.game.initializeBoard();
        
        // Update player identity display (Right Side)
        const identitySection = document.getElementById('playerIdentitySection');
        const identityMarker = document.getElementById('playerIdentity');
        
        if (identitySection && identityMarker) {
            identitySection.style.display = 'flex';
            identityMarker.textContent = this.mySymbol;
            
            // Set color for identity marker
            if (this.mySymbol === 'O') {
                identityMarker.style.color = 'hsl(195, 70%, 55%)';
                identityMarker.parentElement.style.borderColor = 'hsl(195, 70%, 55%)';
            } else {
                identityMarker.style.color = 'hsl(270, 70%, 60%)';
                identityMarker.parentElement.style.borderColor = 'hsl(270, 70%, 60%)';
            }
        }
        
        // Ensure Turn label is correct (Left Side)
        const turnLabel = document.getElementById('turnLabel');
        if (turnLabel) turnLabel.textContent = 'Current Turn:';

        // Set initial color for Current Turn display (will be updated by game.js but good to init)
        const currentPlayerDisplay = document.getElementById('currentPlayer');
        
        // Update status text (Left Side generic message)
        const statusMessage = document.getElementById('statusMessage');

        if (this.myTurn) {
            statusMessage.textContent = `VS ${this.opponent} | YOUR TURN`;
            statusMessage.className = 'status-text-small success';
        } else {
            statusMessage.textContent = `VS ${this.opponent} | Waiting for opponent`;
            statusMessage.className = 'status-text-small info';
        }
        
        console.log(`✅ Game started! You are ${this.mySymbol}, ${this.myTurn ? 'your turn' : 'waiting'}`);

    // Restore board state if provided (reconnection)
    if (data.board) {
        this.game.board = data.board;
        // Re-render board
        const cells = this.game.boardElement.children;
        for (let r = 0; r < data.boardSize; r++) {
            for (let c = 0; c < data.boardSize; c++) {
                const symbol = data.board[r][c];
                if (symbol) {
                    const index = r * data.boardSize + c;
                    const cell = cells[index];
                    if (cell) {
                        cell.classList.add('occupied', symbol.toLowerCase());
                        cell.textContent = ''; // CSS handles the X/O appearance
                    }
                }
            }
        }
        
        // Update current player for game logic
        if (data.currentTurnSymbol) {
            this.game.currentPlayer = data.currentTurnSymbol;
            const currentPlayerDisplay = document.getElementById('currentPlayer');
            if (currentPlayerDisplay) {
                currentPlayerDisplay.textContent = this.game.currentPlayer;
            }
        }
    }
    }
    
    // Make move in multiplayer game
    makeMove(row, col) {
        if (!this.isMultiplayer || !this.myTurn) return false;
        
        this.socket.emit('make_move', {
            gameId: this.currentGameId,
            row: row,
            col: col
        });
        
        return true;
    }
    
    // Handle move result from server
    handleMoveResult(data) {
        if (data.success) {
            this.myTurn = false;
            
            if (!data.gameOver) {
                const statusMessage = document.getElementById('statusMessage');
                if (statusMessage) {
                    statusMessage.textContent = `Playing against ${this.opponent} - Waiting for opponent...`;
                    statusMessage.className = 'status-text-small info';
                }
            }
        } else {
            this.showMessage(data.error, 'error');
        }
    }
    
    // Handle opponent move
    handleOpponentMove(data) {
        // Place opponent's piece on board
        this.game.currentPlayer = data.symbol;
        
        // Update turn indicator immediately to show X or O
        const currentPlayerDisplay = document.getElementById('currentPlayer');
        if (currentPlayerDisplay) {
            currentPlayerDisplay.textContent = data.symbol;
        }

        const cellIndex = data.row * this.game.boardSize + data.col;
        const cell = this.game.boardElement.children[cellIndex];
        
        if (cell) {
            cell.classList.add('occupied', data.symbol.toLowerCase());
            this.game.board[data.row][data.col] = data.symbol;
        }
        
        // It's now my turn
        this.myTurn = true;
        this.game.currentPlayer = this.mySymbol;
        
        const statusMessage = document.getElementById('statusMessage');
        if (statusMessage) {
             statusMessage.textContent = `Playing against ${this.opponent} - Your turn`;
             statusMessage.className = 'status-text-small success';
        }
    }
    
    // Handle game ended
    handleGameEnded(data) {
        this.isMultiplayer = false;
        this.currentGameId = null;
        
        let message = '';
        if (data.reason === 'win') {
            message = '🎉 You won!';
        } else if (data.reason === 'loss') {
            message = '😔 You lost!';
        } else if (data.reason === 'draw') {
            message = '🤝 It\'s a draw!';
        } else if (data.reason === 'opponent_abandoned') {
            message = '🏆 You won! Opponent disconnected';
        }
        
        // Update stats
        if (data.stats) {
            document.getElementById('playerWins').textContent = data.stats.wins;
            document.getElementById('playerLosses').textContent = data.stats.losses;
            document.getElementById('playerDraws').textContent = data.stats.draws;
        }
        
        // Hide surrender button
        const surrenderBtn = document.getElementById('surrenderBtn');
        if (surrenderBtn) {
            surrenderBtn.style.display = 'none';
        }
        
        // Show game-over modal with stats
        const modal = document.getElementById('gameOverModal');
        const icon = document.getElementById('gameOverIcon');
        const title = document.getElementById('gameOverTitle');
        const subtitle = document.getElementById('gameOverMessage');
        
        if (modal && icon && title && subtitle) {
            // Set icon and title based on result
            if (data.reason === 'win' || data.reason === 'opponent_abandoned') {
                icon.textContent = '🏆';
                title.textContent = 'Victory!';
                subtitle.textContent = data.reason === 'opponent_abandoned' ? 'Opponent disconnected' : 'Great game!';
            } else if (data.reason === 'loss' || data.reason === 'surrender') {
                icon.textContent = '😔';
                title.textContent = 'Defeat';
                subtitle.textContent = data.reason === 'surrender' ? 'You surrendered' : 'Better luck next time!';
            } else {
                icon.textContent = '🤝';
                title.textContent = "It's a Draw!";
                subtitle.textContent = 'Well played!';
            }
            
            // Update stats in modal
            if (data.stats) {
                document.getElementById('gameOverWins').textContent = data.stats.wins;
                document.getElementById('gameOverLosses').textContent = data.stats.losses;
                document.getElementById('gameOverDraws').textContent = data.stats.draws;
            }
            
            // Show modal
            modal.classList.add('active');
        }
    }
    
    // Handle disconnect
    handleDisconnect() {
        this.showMessage('Disconnected from server. Reconnecting...', 'error');
        
        // Try to reconnect
        setTimeout(() => {
            if (!this.socket || !this.socket.connected) {
                this.connect();
            }
        }, 2000);
    }
    
    // Return to lobby
    returnToLobby() {
        this.isMultiplayer = false;
        this.currentGameId = null;
        document.getElementById('multiplayerPanel').style.display = 'block';
        document.getElementById('gameControls').style.display = 'block'; // Or grid/none depending on logic, but block/grid usually toggled by logic
        
        // Hide identity section in local play
        const identitySection = document.getElementById('playerIdentitySection');
        if (identitySection) identitySection.style.display = 'none';

        this.socket.emit('request_active_players');
    }
    
    // Show message to user
    showMessage(text, type = 'info') {
        const messageEl = document.getElementById('statusMessage');
        if (messageEl) {
            messageEl.textContent = text;
            messageEl.className = `status-text-small ${type}`;
        }
    }
    
    // Handle rematch request from opponent
    handleRematchRequest(data) {
        const notification = document.createElement('div');
        notification.className = 'challenge-notification';
        notification.innerHTML = `
            <div class="challenge-content">
                <h3>Rematch Request!</h3>
                <p><strong>${data.from}</strong> wants a rematch</p>
                <p>Board size: ${data.boardSize}×${data.boardSize}</p>
                <div class="challenge-actions">
                    <button class="accept-btn" onclick="acceptRematchFromNotification('${data.rematchId}')">
                        Accept
                    </button>
                    <button class="decline-btn" onclick="declineRematchFromNotification('${data.rematchId}')">
                        Decline
                    </button>
                </div>
            </div>
        `;
        
        document.body.appendChild(notification);
        setTimeout(() => notification.classList.add('active'), 10);
    }
}

// Global helper functions for rematch from notifications
function acceptRematchFromNotification(rematchId) {
    if (window.multiplayerClient && window.multiplayerClient.socket) {
        window.multiplayerClient.socket.emit('accept_rematch', { rematchId });
        
        // Hide game over modal if visible
        const modal = document.getElementById('gameOverModal');
        if (modal) {
            modal.classList.remove('active');
        }
        
        // Remove notification
        const notifications = document.querySelectorAll('.challenge-notification');
        notifications.forEach(n => n.remove());
    }
}

function declineRematchFromNotification(rematchId) {
    if (window.multiplayerClient && window.multiplayerClient.socket) {
        window.multiplayerClient.socket.emit('decline_rematch', { rematchId });
        
        // Remove notification
        const notifications = document.querySelectorAll('.challenge-notification');
        notifications.forEach(n => n.remove());
    }
}

// Initialize multiplayer client (will be used by game.js)
// Initialize multiplayer client (will be used by game.js)
window.multiplayerClient = null;
