const express = require('express');
const { v4: uuidv4 } = require('uuid');
const DatabaseManager = require('../database/init');

class GameAPI {
    constructor(db) {
        this.db = db;
        this.router = express.Router();
        this.setupRoutes();
    }

    setupRoutes() {
        // Game management
        this.router.post('/games', this.createGame.bind(this));
        this.router.get('/games/:id', this.getGameState.bind(this));
        this.router.post('/games/:id/join', this.joinGame.bind(this));
        this.router.post('/games/:id/submit-turn', this.submitTurn.bind(this));
        this.router.get('/games/:id/status', this.getGameStatus.bind(this));
        this.router.post('/games/:id/rematch', this.createRematch.bind(this));
        
        // Player management
        this.router.post('/players', this.createPlayer.bind(this));
        this.router.get('/players/:id', this.getPlayer.bind(this));
        
        // Statistics and leaderboard
        this.router.get('/leaderboard', this.getLeaderboard.bind(this));
        this.router.get('/games/:id/history', this.getGameHistory.bind(this));
        this.router.get('/games/:id/replay', this.getGameReplay.bind(this));
        
        // Tournament endpoints (future expansion)
        this.router.get('/tournaments', this.getTournaments.bind(this));
        this.router.post('/tournaments', this.createTournament.bind(this));
        
        // Configuration endpoint
        this.router.get('/config', this.getConfig.bind(this));
    }

    // Create a new game
    async createGame(req, res) {
        try {
            const { playerName, gameMode = 'standard' } = req.body;
            
            if (!playerName || playerName.trim().length === 0) {
                return res.status(400).json({ error: 'Player name is required' });
            }

            // Create or get player
            const playerId = await this.getOrCreatePlayer(playerName.trim());
            
            // Create game
            const gameId = await this.db.createGame(gameMode);
            
            // Generate spawn positions (player 1 spawns first)
            const spawnPositions = this.generateSpawnPositions();
            await this.db.addPlayerToGame(gameId, playerId, 1, spawnPositions.player1.x, spawnPositions.player1.y);

            // Log game creation event
            await this.db.logGameEvent(gameId, 0, 1, 'game_created', playerId, {
                game_mode: gameMode,
                spawn_x: spawnPositions.player1.x,
                spawn_y: spawnPositions.player1.y
            });

            res.json({
                success: true,
                gameId: gameId,
                playerId: playerId,
                playerNumber: 1,
                inviteLink: `${req.protocol}://${req.get('host')}/game/${gameId}`,
                spawnPosition: spawnPositions.player1
            });

        } catch (error) {
            console.error('Error creating game:', error);
            res.status(500).json({ error: 'Failed to create game' });
        }
    }

    // Join an existing game
    async joinGame(req, res) {
        try {
            const { id: gameId } = req.params;
            const { playerName } = req.body;

            if (!playerName || playerName.trim().length === 0) {
                return res.status(400).json({ error: 'Player name is required' });
            }

            // Check if game exists and is waiting for players
            const gameState = await this.db.getGameState(gameId);
            if (!gameState) {
                return res.status(404).json({ error: 'Game not found' });
            }

            if (gameState.game.status !== 'waiting') {
                return res.status(400).json({ error: 'Game is not accepting new players' });
            }

            if (gameState.players.length >= GAME_CONFIG.MAX_PLAYERS) {
                return res.status(400).json({ error: 'Game is full' });
            }

            // Create or get player
            const playerId = await this.getOrCreatePlayer(playerName.trim());
            
            // Check if player is already in the game
            const existingPlayer = gameState.players.find(p => p.player_id === playerId);
            if (existingPlayer) {
                return res.status(400).json({ error: 'You are already in this game' });
            }

            // Add player 2
            const spawnPositions = this.generateSpawnPositions();
            await this.db.addPlayerToGame(gameId, playerId, 2, spawnPositions.player2.x, spawnPositions.player2.y);

            // Update game status to playing
            await this.db.runQuery(`
                UPDATE games 
                SET status = 'playing', started_at = CURRENT_TIMESTAMP 
                WHERE id = ?
            `, [gameId]);

            // Log join event
            await this.db.logGameEvent(gameId, 0, 2, 'player_joined', playerId, {
                player_number: 2,
                spawn_x: spawnPositions.player2.x,
                spawn_y: spawnPositions.player2.y
            });

            res.json({
                success: true,
                gameId: gameId,
                playerId: playerId,
                playerNumber: 2,
                spawnPosition: spawnPositions.player2
            });

        } catch (error) {
            console.error('Error joining game:', error);
            res.status(500).json({ error: 'Failed to join game' });
        }
    }

    // Submit turn actions
    async submitTurn(req, res) {
        try {
            const { id: gameId } = req.params;
            const { playerId, actions } = req.body;

            if (!playerId || !actions || !Array.isArray(actions)) {
                return res.status(400).json({ error: 'Invalid turn submission' });
            }

            // Validate game state
            const gameState = await this.db.getGameState(gameId);
            if (!gameState || gameState.game.status !== 'playing') {
                return res.status(400).json({ error: 'Game is not active' });
            }

            // Validate player is in the game
            const player = gameState.players.find(p => p.player_id === playerId);
            if (!player) {
                return res.status(400).json({ error: 'Player not in this game' });
            }

            const currentTurn = gameState.game.current_turn;

            // Check if player has already submitted for this turn
            const existingSubmission = await this.db.getRow(`
                SELECT id FROM turn_submissions 
                WHERE game_id = ? AND player_id = ? AND turn_number = ?
            `, [gameId, playerId, currentTurn]);

            if (existingSubmission) {
                return res.status(400).json({ error: 'Turn already submitted' });
            }

            // Validate actions
            const validation = this.validateActions(actions);
            if (!validation.valid) {
                return res.status(400).json({ error: validation.error });
            }

            // Submit turn
            await this.db.runQuery(`
                INSERT INTO turn_submissions (game_id, player_id, turn_number, actions, moves_used, shot_used)
                VALUES (?, ?, ?, ?, ?, ?)
            `, [gameId, playerId, currentTurn, JSON.stringify(actions), validation.movesUsed, validation.shotUsed]);

            // Check if both players have submitted
            const submissions = await this.db.getAllRows(`
                SELECT player_id FROM turn_submissions 
                WHERE game_id = ? AND turn_number = ?
            `, [gameId, currentTurn]);

            let bothSubmitted = false;
            if (submissions.length === GAME_CONFIG.MAX_PLAYERS) {
                // Execute turn
                await this.executeTurn(gameId, currentTurn);
                bothSubmitted = true;
            }

            res.json({
                success: true,
                turnSubmitted: true,
                bothPlayersSubmitted: bothSubmitted,
                waitingForOpponent: !bothSubmitted
            });

        } catch (error) {
            console.error('Error submitting turn:', error);
            res.status(500).json({ error: 'Failed to submit turn' });
        }
    }

    // Get current game status (for polling)
    async getGameStatus(req, res) {
        try {
            const { id: gameId } = req.params;
            const { playerId } = req.query;

            const gameState = await this.db.getGameState(gameId);
            if (!gameState) {
                return res.status(404).json({ error: 'Game not found' });
            }

            // Get latest events for this turn
            const currentTurn = gameState.game.current_turn;
            const events = await this.db.getAllRows(`
                SELECT * FROM game_events 
                WHERE game_id = ? AND turn_number >= ?
                ORDER BY turn_number DESC, sequence_number DESC
                LIMIT 10
            `, [gameId, Math.max(0, currentTurn - 1)]);

            // Check turn submission status
            let turnStatus = 'waiting_for_submission';
            if (playerId) {
                const mySubmission = await this.db.getRow(`
                    SELECT id FROM turn_submissions 
                    WHERE game_id = ? AND player_id = ? AND turn_number = ?
                `, [gameId, playerId, currentTurn]);

                const allSubmissions = await this.db.getAllRows(`
                    SELECT player_id FROM turn_submissions 
                    WHERE game_id = ? AND turn_number = ?
                `, [gameId, currentTurn]);

                if (mySubmission) {
                    turnStatus = allSubmissions.length === 2 ? 'executed' : 'waiting_for_opponent';
                }
            }

            res.json({
                game: gameState.game,
                players: gameState.players,
                recentEvents: events,
                turnStatus: turnStatus,
                needsUpdate: events.length > 0
            });

        } catch (error) {
            console.error('Error getting game status:', error);
            res.status(500).json({ error: 'Failed to get game status' });
        }
    }

    // Get complete game state
    async getGameState(req, res) {
        try {
            const { id: gameId } = req.params;
            const gameState = await this.db.getGameState(gameId);
            
            if (!gameState) {
                return res.status(404).json({ error: 'Game not found' });
            }

            res.json(gameState);
        } catch (error) {
            console.error('Error getting game state:', error);
            res.status(500).json({ error: 'Failed to get game state' });
        }
    }

    // Create or get existing player
    async getOrCreatePlayer(username) {
        // Check if player exists
        const existingPlayer = await this.db.getRow(
            'SELECT id FROM players WHERE username = ?', 
            [username]
        );

        if (existingPlayer) {
            // Update last active
            await this.db.runQuery(
                'UPDATE players SET last_active = CURRENT_TIMESTAMP WHERE id = ?',
                [existingPlayer.id]
            );
            return existingPlayer.id;
        }

        // Create new player
        return await this.db.createPlayer(username);
    }

    // Generate spawn positions with minimum distance
    generateSpawnPositions() {
        const GAME_CONFIG = require('../game-config');
        const minDistance = GAME_CONFIG.SPAWN_BUFFER;
        const gridWidth = GAME_CONFIG.GRID_WIDTH;
        const gridHeight = GAME_CONFIG.GRID_HEIGHT;

        // Simple spawn logic: corners with buffer
        const player1 = {
            x: minDistance,
            y: minDistance
        };

        const player2 = {
            x: gridWidth - minDistance - 1,
            y: gridHeight - minDistance - 1
        };

        return { player1, player2 };
    }

    // Validate turn actions
    validateActions(actions) {
        const GAME_CONFIG = require('../game-config');
        let movesUsed = 0;
        let shotUsed = false;

        for (const action of actions) {
            if (!action.type || !action.direction) {
                return { valid: false, error: 'Invalid action format' };
            }

            if (!['north', 'south', 'east', 'west'].includes(action.direction)) {
                return { valid: false, error: 'Invalid direction' };
            }

            if (action.type === 'move') {
                movesUsed++;
                if (movesUsed > GAME_CONFIG.MOVES_PER_TURN) {
                    return { valid: false, error: 'Too many moves' };
                }
            } else if (action.type === 'shoot') {
                if (shotUsed) {
                    return { valid: false, error: 'Only one shot per turn allowed' };
                }
                shotUsed = true;
            } else {
                return { valid: false, error: 'Invalid action type' };
            }
        }

        return { valid: true, movesUsed, shotUsed };
    }

    // Execute turn when both players have submitted
    async executeTurn(gameId, turnNumber) {
        console.log(`Executing turn ${turnNumber} for game ${gameId}`);
        
        try {
            // Get current game state
            const gameState = await this.db.getGameState(gameId);
            if (!gameState || gameState.game.status !== 'playing') {
                console.error('Cannot execute turn: game not in playing state');
                return;
            }

            // Get both players' submitted actions for this turn
            const submissions = await this.db.getAllRows(`
                SELECT player_id, actions, moves_used, shot_used 
                FROM turn_submissions 
                WHERE game_id = ? AND turn_number = ?
                ORDER BY submitted_at ASC
            `, [gameId, turnNumber]);

            if (submissions.length !== 2) {
                console.error(`Expected 2 submissions, got ${submissions.length}`);
                return;
            }

            // Parse actions for both players
            const playerActions = {};
            submissions.forEach(submission => {
                playerActions[submission.player_id] = JSON.parse(submission.actions);
            });

            // Get current player positions
            const players = {};
            gameState.players.forEach(player => {
                players[player.player_id] = {
                    id: player.player_id,
                    number: player.player_number,
                    x: player.current_x,
                    y: player.current_y,
                    alive: Boolean(player.is_alive)
                };
            });

            // Execute actions sequentially - shots can fire during movement
            console.log('Executing actions sequentially for all players');
            const executionResults = await this.executeSequentialActions(gameId, turnNumber, playerActions, players);

            // Update player positions in database
            for (const playerId in players) {
                const player = players[playerId];
                await this.db.runQuery(`
                    UPDATE game_players 
                    SET current_x = ?, current_y = ?, is_alive = ?
                    WHERE game_id = ? AND player_id = ?
                `, [player.x, player.y, player.alive ? 1 : 0, gameId, playerId]);
            }

            // Check for game end condition
            const alivePlayers = Object.values(players).filter(p => p.alive);
            if (alivePlayers.length <= 1) {
                // Game ends
                const winner = alivePlayers.length === 1 ? alivePlayers[0] : null;
                await this.endGame(gameId, winner, 'combat');
                console.log(`Game ${gameId} ended. Winner: ${winner ? winner.id : 'none'}`);
            } else {
                // Advance to next turn
                await this.db.runQuery(`
                    UPDATE games 
                    SET current_turn = current_turn + 1, last_action_at = CURRENT_TIMESTAMP 
                    WHERE id = ?
                `, [gameId]);
                console.log(`Turn ${turnNumber} completed, advanced to turn ${turnNumber + 1}`);
            }

        } catch (error) {
            console.error(`Error executing turn ${turnNumber} for game ${gameId}:`, error);
        }
    }

    // Execute all actions sequentially - allowing shots during movement
    async executeSequentialActions(gameId, turnNumber, playerActions, players) {
        // Determine the maximum number of actions any player has
        const maxActions = Math.max(...Object.values(playerActions).map(actions => actions.length));
        
        // Execute actions step by step for all players simultaneously
        for (let actionIndex = 0; actionIndex < maxActions; actionIndex++) {
            console.log(`Executing action step ${actionIndex + 1} of ${maxActions}`);
            
            // Store original positions before any actions at this step
            const originalPositions = {};
            for (const playerId in players) {
                originalPositions[playerId] = { x: players[playerId].x, y: players[playerId].y };
            }
            
            // STEP 1: Process all shots first (from original positions before movement)
            for (const playerId in playerActions) {
                const actions = playerActions[playerId];
                const player = players[playerId];
                
                if (!player.alive || actionIndex >= actions.length) continue;
                
                const action = actions[actionIndex];
                
                if (action.type === 'shoot') {
                    // Shot fires from original position (before any movement this step)
                    const shooterX = originalPositions[playerId].x;
                    const shooterY = originalPositions[playerId].y;
                    const bulletPath = this.calculateBulletPath({ x: shooterX, y: shooterY }, action.direction);
                    
                    // Log shot fired event with bullet path
                    await this.db.logGameEvent(gameId, turnNumber, player.number, 'shot_fired', playerId, {
                        action_index: actionIndex,
                        shooter_x: shooterX,
                        shooter_y: shooterY,
                        direction: action.direction,
                        bullet_path: bulletPath
                    });
                    
                    // Check if shot hits any player at their original positions (before movement)
                    const hitTarget = this.checkInstantShotHit({ x: shooterX, y: shooterY, id: playerId }, action.direction, originalPositions, actionIndex, playerActions);
                    
                    if (hitTarget) {
                        // Player hit! Find the actual player object and mark as dead
                        const actualTarget = players[hitTarget.playerId];
                        actualTarget.alive = false;
                        
                        // Log hit event
                        await this.db.logGameEvent(gameId, turnNumber, player.number, 'player_hit', actualTarget.id, {
                            action_index: actionIndex,
                            shooter_id: player.id,
                            target_id: actualTarget.id,
                            target_x: hitTarget.x,
                            target_y: hitTarget.y,
                            shot_direction: action.direction,
                            bullet_path: bulletPath
                        });
                        
                        console.log(`Player ${player.id} hit player ${actualTarget.id} at action step ${actionIndex + 1}!`);
                    } else {
                        console.log(`Player ${player.id} shot ${action.direction} from (${shooterX},${shooterY}) - no hit`);
                    }
                }
            }
            
            // STEP 2: Process all movements (after shots have been resolved)
            for (const playerId in playerActions) {
                const actions = playerActions[playerId];
                const player = players[playerId];
                
                if (!player.alive || actionIndex >= actions.length) continue;
                
                const action = actions[actionIndex];
                
                if (action.type === 'move') {
                    const oldX = player.x;
                    const oldY = player.y;
                    const newPosition = this.calculateNewPosition(player.x, player.y, action.direction);
                    
                    // Validate movement (bounds check)
                    if (this.isValidPosition(newPosition.x, newPosition.y)) {
                        player.x = newPosition.x;
                        player.y = newPosition.y;
                        
                        // Log movement event
                        await this.db.logGameEvent(gameId, turnNumber, player.number, 'player_moved', playerId, {
                            action_index: actionIndex,
                            from_x: oldX,
                            from_y: oldY,
                            to_x: player.x,
                            to_y: player.y,
                            direction: action.direction
                        });
                        
                        console.log(`Player ${player.id} moved from (${oldX},${oldY}) to (${player.x},${player.y})`);
                    }
                }
            }
        }
        
        return { success: true };
    }

    // Helper function to calculate new position based on direction
    calculateNewPosition(x, y, direction) {
        const offset = this.getDirectionOffset(direction);
        return {
            x: x + offset.x,
            y: y + offset.y
        };
    }

    // Helper function to get direction offset
    getDirectionOffset(direction) {
        const GAME_CONFIG = require('../game-config');
        const directionKey = direction.toUpperCase();
        const offset = GAME_CONFIG.DIRECTION_OFFSETS[directionKey];
        
        if (offset) {
            // Convert row/col format to x/y format for server use
            return { x: offset.col, y: offset.row };
        }
        return { x: 0, y: 0 };
    }

    // Check if position is within game bounds
    isValidPosition(x, y) {
        const GAME_CONFIG = require('../game-config');
        return x >= 0 && x < GAME_CONFIG.GRID_WIDTH && 
               y >= 0 && y < GAME_CONFIG.GRID_HEIGHT;
    }

    // Calculate complete bullet path for visualization
    calculateBulletPath(shooter, direction) {
        const path = [];
        const offset = this.getDirectionOffset(direction);
        let currentX = shooter.x + offset.x;
        let currentY = shooter.y + offset.y;
        
        // Follow bullet path until it goes out of bounds
        while (this.isValidPosition(currentX, currentY)) {
            path.push({ x: currentX, y: currentY });
            currentX += offset.x;
            currentY += offset.y;
        }
        
        return path;
    }

    // Check if an instant shot hits any player at their current positions
    checkInstantShotHit(shooter, direction, positions, currentActionIndex, playerActions) {
        console.log(`Checking shot from shooter ${shooter.id} at (${shooter.x},${shooter.y}) direction ${direction}`);
        
        const offset = this.getDirectionOffset(direction);
        let bulletX = shooter.x + offset.x;
        let bulletY = shooter.y + offset.y;
        
        // Follow bullet path and check for hits
        while (this.isValidPosition(bulletX, bulletY)) {
            console.log(`Bullet checking position (${bulletX},${bulletY})`);
            
            // Check if any player is at this position (excluding the shooter)
            for (const playerId in positions) {
                const targetPosition = positions[playerId];
                if (playerId !== shooter.id && 
                    targetPosition.x === bulletX && 
                    targetPosition.y === bulletY) {
                    console.log(`HIT! Player ${playerId} at (${targetPosition.x},${targetPosition.y})`);
                    return { ...targetPosition, playerId: playerId };
                }
            }
            
            // Continue bullet path
            bulletX += offset.x;
            bulletY += offset.y;
        }
        
        console.log('Shot missed - no players hit');
        return null; // No hit
    }

    // Check if a shot hits any player (legacy function - kept for compatibility)
    checkShotHit(shooter, direction, players) {
        const offset = this.getDirectionOffset(direction);
        let currentX = shooter.x + offset.x;
        let currentY = shooter.y + offset.y;
        
        // Follow bullet path until it hits something or goes out of bounds
        while (this.isValidPosition(currentX, currentY)) {
            // Check if any player is at this position
            for (const playerId in players) {
                const player = players[playerId];
                if (player.alive && 
                    player.id !== shooter.id && 
                    player.x === currentX && 
                    player.y === currentY) {
                    return player;
                }
            }
            
            // Continue bullet path
            currentX += offset.x;
            currentY += offset.y;
        }
        
        return null; // No hit
    }

    // End the game
    async endGame(gameId, winner, reason) {
        await this.db.runQuery(`
            UPDATE games 
            SET status = 'finished', 
                winner_id = ?, 
                end_reason = ?,
                finished_at = CURRENT_TIMESTAMP,
                last_action_at = CURRENT_TIMESTAMP 
            WHERE id = ?
        `, [winner ? winner.id : null, reason, gameId]);

        // Log game end event
        await this.db.logGameEvent(gameId, 0, 0, 'game_ended', winner ? winner.id : null, {
            reason: reason,
            winner_player_number: winner ? winner.number : null
        });
    }

    // Additional endpoints for features
    async createPlayer(req, res) {
        try {
            const { username, email } = req.body;
            const playerId = await this.db.createPlayer(username, email);
            res.json({ success: true, playerId });
        } catch (error) {
            res.status(500).json({ error: 'Failed to create player' });
        }
    }

    async getPlayer(req, res) {
        try {
            const player = await this.db.getRow('SELECT * FROM players WHERE id = ?', [req.params.id]);
            if (!player) {
                return res.status(404).json({ error: 'Player not found' });
            }
            res.json(player);
        } catch (error) {
            res.status(500).json({ error: 'Failed to get player' });
        }
    }

    async getLeaderboard(req, res) {
        try {
            const limit = parseInt(req.query.limit) || 10;
            const leaderboard = await this.db.getLeaderboard(limit);
            res.json(leaderboard);
        } catch (error) {
            res.status(500).json({ error: 'Failed to get leaderboard' });
        }
    }

    async getGameHistory(req, res) {
        try {
            const history = await this.db.getGameHistory(req.params.id);
            res.json(history);
        } catch (error) {
            res.status(500).json({ error: 'Failed to get game history' });
        }
    }

    async getGameReplay(req, res) {
        try {
            const gameState = await this.db.getGameState(req.params.id);
            const history = await this.db.getGameHistory(req.params.id);
            res.json({ game: gameState, events: history });
        } catch (error) {
            res.status(500).json({ error: 'Failed to get game replay' });
        }
    }

    async getTournaments(req, res) {
        try {
            const tournaments = await this.db.getAllRows('SELECT * FROM tournaments ORDER BY created_at DESC');
            res.json(tournaments);
        } catch (error) {
            res.status(500).json({ error: 'Failed to get tournaments' });
        }
    }

    async createTournament(req, res) {
        // Tournament creation logic (future feature)
        res.status(501).json({ error: 'Tournament creation not yet implemented' });
    }

    // Get game configuration
    async getConfig(req, res) {
        try {
            const GAME_CONFIG = require('../game-config');
            res.json({
                success: true,
                config: GAME_CONFIG
            });
        } catch (error) {
            console.error('Error getting config:', error);
            res.status(500).json({ error: 'Failed to get configuration' });
        }
    }

    // Create a rematch with the same players
    async createRematch(req, res) {
        try {
            const { id: oldGameId } = req.params;
            const { playerId, playerName } = req.body;

            if (!playerId || !playerName) {
                return res.status(400).json({ error: 'Player ID and name are required' });
            }

            // Get the original game to find both players
            const originalGame = await this.db.getGameState(oldGameId);
            if (!originalGame || originalGame.game.status !== 'finished') {
                return res.status(400).json({ error: 'Can only rematch finished games' });
            }

            // Verify the requesting player was in the original game
            const requestingPlayer = originalGame.players.find(p => p.player_id === playerId);
            if (!requestingPlayer) {
                return res.status(400).json({ error: 'Player was not in the original game' });
            }

            // Find the opponent
            const opponent = originalGame.players.find(p => p.player_id !== playerId);
            if (!opponent) {
                return res.status(400).json({ error: 'Could not find opponent from original game' });
            }

            // Create new game
            const newGameId = await this.db.createGame('standard');
            
            // Generate spawn positions for new game
            const spawnPositions = this.generateSpawnPositions();
            
            // Add the requesting player as player 1
            await this.db.addPlayerToGame(newGameId, playerId, 1, spawnPositions.player1.x, spawnPositions.player1.y);

            // Log game creation event
            await this.db.logGameEvent(newGameId, 0, 1, 'rematch_created', playerId, {
                original_game_id: oldGameId,
                opponent_id: opponent.player_id,
                spawn_x: spawnPositions.player1.x,
                spawn_y: spawnPositions.player1.y
            });

            // Check if the opponent is currently active (has recent activity)
            const opponentActiveCheck = await this.db.getRow(`
                SELECT last_active FROM players 
                WHERE id = ? AND last_active > datetime('now', '-10 minutes')
            `, [opponent.player_id]);

            let gameStatus = 'waiting';
            let inviteLink = `${req.protocol}://${req.get('host')}/game/${newGameId}`;

            // If opponent is recently active, try to auto-add them
            if (opponentActiveCheck) {
                try {
                    // Add opponent as player 2
                    await this.db.addPlayerToGame(newGameId, opponent.player_id, 2, spawnPositions.player2.x, spawnPositions.player2.y);
                    
                    // Update game status to playing
                    await this.db.runQuery(`
                        UPDATE games 
                        SET status = 'playing', started_at = CURRENT_TIMESTAMP 
                        WHERE id = ?
                    `, [newGameId]);

                    // Log opponent auto-join
                    await this.db.logGameEvent(newGameId, 0, 2, 'rematch_auto_joined', opponent.player_id, {
                        spawn_x: spawnPositions.player2.x,
                        spawn_y: spawnPositions.player2.y
                    });

                    gameStatus = 'playing';
                } catch (error) {
                    console.log('Could not auto-add opponent, will wait for manual join:', error.message);
                }
            }

            res.json({
                success: true,
                newGameId: newGameId,
                playerId: playerId,
                playerNumber: 1, // The requesting player becomes Player 1 in the rematch
                status: gameStatus,
                inviteLink: inviteLink,
                opponentName: opponent.username,
                spawnPosition: spawnPositions.player1,
                message: gameStatus === 'playing' 
                    ? 'Rematch started! Both players ready.'
                    : 'Rematch created. Share the link with your opponent.'
            });

        } catch (error) {
            console.error('Error creating rematch:', error);
            res.status(500).json({ error: 'Failed to create rematch' });
        }
    }
}

module.exports = GameAPI;