require('dotenv').config();
const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
const path = require('path');

app.use(express.static(path.join(__dirname, '../public')));

// Room State
const rooms = {};
const RECONNECT_GRACE_PERIOD = 10000; // 10 seconds
const disconnectedPlayers = new Map(); // Track recently disconnected players
const roomTimeouts = new Map(); // Track room cleanup timeouts

function createInitialGameState() {
    const state = {
        board: Array(5).fill().map(() => Array(5).fill(null)),
        turn: 'goat',
        goatsPlaced: 0,
        goatsCaptured: 0,
        gameActive: false,
        winner: null,
        lastMove: null
    };
    // Place Tigers
    state.board[0][0] = 'tiger';
    state.board[0][4] = 'tiger';
    state.board[4][0] = 'tiger';
    state.board[4][4] = 'tiger';
    return state;
}

// Export a function that accepts the IO instance and namespace
module.exports = function(ioInstance, appInstance, roomsDB, appEmitter) {
    // If roomsDB is not passed (standalone mode), try to require it
    if (!roomsDB) {
        try {
            roomsDB = require('../../../admin/server/rooms-db');
        } catch (e) {
            console.warn('Bagh Chal: Could not load roomsDB for standalone mode');
        }
    }

    // Function to load rooms from DB
    const loadRooms = () => {
        if (!roomsDB) return;
        
        try {
            // Fetch ALL rooms to distinguish between 'inactive' and 'deleted'
            const dbRooms = roomsDB.getRoomsByGame('bagh-chal');
            const dbRoomIds = new Set();

            // 1. Update/Add rooms
            dbRooms.forEach(room => {
                const roomId = `room_${room.id}`;
                dbRoomIds.add(roomId);
                
                if (room.status === 'active' || room.status === 'archived') {
                    // ACTIVE or ARCHIVED ROOMS: Load into memory
                    
                    if (rooms[roomId]) {
                        // Update existing room properties
                        rooms[roomId].name = room.name;
                        rooms[roomId].password = room.password || null;
                        rooms[roomId].type = room.type;
                        rooms[roomId].isProtected = !!room.password;
                        
                        // Handle Archival State
                        if (room.status === 'archived') {
                            if (!rooms[roomId].isArchived) {
                                rooms[roomId].isArchived = true;
                                // Notify players of archival
                                if (ioInstance) {
                                    ioInstance.to(roomId).emit('chat_message', {
                                        id: Date.now() + '_sys',
                                        sender: 'System',
                                        role: 'system',
                                        text: '⚠️ This room has been archived by the admin. You may finish your current game, but no new players can join.',
                                        timestamp: Date.now(),
                                        seenBy: []
                                    });
                                }
                            }
                        } else {
                            // Reactivate if it was archived
                            rooms[roomId].isArchived = false;
                        }
                    } else {
                        // Create new room
                        rooms[roomId] = {
                            id: roomId,
                            name: room.name,
                            password: room.password || null,
                            type: room.type,
                            isProtected: !!room.password,
                            players: { tiger: null, goat: null },
                            gameState: createInitialGameState(),
                            isActive: false,
                            chatHistory: [],
                            isArchived: room.status === 'archived'
                        };
                    }
                } else {
                    // INACTIVE ROOMS: "Just make inactive" (Remove immediately)
                    if (rooms[roomId]) {
                        // Notify players before deleting
                        if (ioInstance) {
                            ioInstance.to(roomId).emit('chat_message', {
                                id: Date.now() + '_sys',
                                sender: 'System',
                                role: 'system',
                                text: '⚠️ This room has been deactivated by the admin.',
                                timestamp: Date.now(),
                                seenBy: []
                            });
                        }
                        delete rooms[roomId];
                    }
                }
            });

            // 2. Handle Deleted Rooms (Rooms in memory but NOT in DB)
            // These are HARD DELETES -> Remove immediately
            Object.keys(rooms).forEach(roomId => {
                if (!dbRoomIds.has(roomId)) {
                    delete rooms[roomId];
                }
            });

            console.log(`Bagh Chal: Reloaded rooms. Total: ${Object.keys(rooms).length}`);
            
            // Broadcast new room list to all connected clients
            if (ioInstance) {
                ioInstance.emit('room_list', getRoomList());
            }

        } catch (error) {
            console.error('Bagh Chal: Error loading rooms from database:', error);
        }
    };

    // Initial Load
    if (roomsDB) {
        loadRooms();
        
        // Listen for updates
        if (appEmitter) {
            appEmitter.on('room_update', ({ gameType }) => {
                if (gameType === 'bagh-chal' || !gameType) {
                    console.log('Bagh Chal: Received room update event, reloading...');
                    loadRooms();
                }
            });
        }
    } else {
        // Fallback to .env configuration
        let roomCount = 0;
        for (let i = 1; i <= 100; i++) { // Check up to 100 rooms
            if (process.env[`BAGH_CHAL_ROOM_${i}_NAME`]) {
                roomCount = i;
            } else if (i > roomCount + 5) { // Stop if we find 5 consecutive missing entries
                break;
            }
        }

        // Initialize rooms found in .env
        for (let i = 1; i <= roomCount; i++) {
            const envName = process.env[`BAGH_CHAL_ROOM_${i}_NAME`];
            const envPass = process.env[`BAGH_CHAL_ROOM_${i}_PASS`];
            const envType = process.env[`BAGH_CHAL_ROOM_${i}_TYPE`] || 'private'; // Default to private
            
            // Validate room type
            const roomType = (envType === 'public' || envType === 'private') ? envType : 'private';
            
            if (envName) { // Only create room if name is defined
                rooms[`room_${i}`] = {
                    id: `room_${i}`,
                    name: envName,
                    password: envPass || null, // Pre-set password if in .env
                    type: roomType, // 'public' or 'private'
                    isProtected: !!envPass, // Flag to know if password is fixed
                    players: { tiger: null, goat: null }, // socket.id
                    gameState: createInitialGameState(),
                    isActive: false,
                    chatHistory: [] // Store chat messages
                };
            }
        }
        console.log(`Bagh Chal: Initialized ${Object.keys(rooms).length} rooms from .env`);
    }

    const router = express.Router();
    
    // If appInstance is provided (production mode), use it to serve static files
    if (appInstance) {
        router.use(express.static(path.join(__dirname, '../public')));
        appInstance.use('/games/bagh-chal', router);
    }

    // Use the provided IO instance or the local one
    const ioToUse = ioInstance || io;
    
    // Define connection handler
    const onConnection = (socket) => {
        console.log('User connected to Bagh Chal:', socket.id);
    
        // Send room list on connect
        socket.emit('room_list', getRoomList());
    
        socket.on('get_rooms', () => {
            socket.emit('room_list', getRoomList());
        });
    
        socket.on('get_players', ({ roomId }) => {
            const room = rooms[roomId];
            if (room) {
                socket.emit('player_update', getPublicPlayers(room));
            }
        });
    
        socket.on('join_room', ({ roomId, password, role, playerName }) => {
            const room = rooms[roomId];
            if (!room) return socket.emit('error', 'Room not found');
            
            // Prevent joining archived rooms
            if (room.isArchived) {
                return socket.emit('error', 'This room has been closed by the admin.');
            }
    
            // Check if this is a reconnecting player
            const disconnectKey = `${roomId}:${role}:${playerName}`;
            const disconnectedInfo = disconnectedPlayers.get(disconnectKey);
            
            console.log(`[JOIN] Player ${playerName} (${role}) joining ${roomId}. DisconnectKey: ${disconnectKey}`);
            console.log(`[JOIN] DisconnectedInfo found? ${!!disconnectedInfo}`);

            if (disconnectedInfo) {
                console.log(`[JOIN] Reconnecting...`);
                disconnectedPlayers.delete(disconnectKey);
                
                // Clear any pending player-specific timeout
                if (disconnectedInfo.timeout) {
                    console.log(`[JOIN] Clearing player timeout`);
                    clearTimeout(disconnectedInfo.timeout);
                }
                
                // Clear the room-level cleanup timeout since a player is reconnecting
                if (roomTimeouts.has(roomId)) {
                    console.log(`Clearing room cleanup timeout for ${roomId} - player reconnecting`);
                    clearTimeout(roomTimeouts.get(roomId));
                    roomTimeouts.delete(roomId);
                }
                
                // Verify password matches what they had before
                if (disconnectedInfo.password !== password) {
                    console.log(`PASSWORD MISMATCH! Saved: "${disconnectedInfo.password}", Provided: "${password}"`);
                    return socket.emit('error', 'Incorrect password');
                }
                console.log('Password verified, allowing reconnection');
            } else {
                // Normal join flow - validate password
                if (room.isProtected) {
                    // Room has a fixed password from .env
                    if (room.password !== password) {
                        return socket.emit('error', 'Incorrect password');
                    }
                    room.isActive = true; // Always active if protected/configured
                } else {
                    // Dynamic password logic (for non-configured rooms)
                    if (room.isActive) {
                        if (room.password && room.password !== password) {
                            return socket.emit('error', 'Incorrect password');
                        }
                    } else {
                        // First player sets the password
                        if (Object.values(room.players).every(p => p === null)) {
                            room.password = password;
                            room.isActive = true;
                        } else if (room.password !== password) {
                             return socket.emit('error', 'Incorrect password');
                        }
                    }
                }
    
                // Check Role Availability
                if (room.players[role]) {
                    // CRITICAL FIX: If player exists but it's the SAME player (name matches) 
                    // and just hasn't been fully disconnected yet (race condition), allow rejoin.
                    if (room.players[role].name === playerName) {
                        console.log(`[JOIN] Player ${playerName} (${role}) found in room but status is ${room.players[role].status}. Treating as immediate reconnect.`);
                        
                        // Force disconnect the old socket if it's different
                        if (room.players[role].id !== socket.id) {
                            // Ideally we should disconnect the old socket, but we don't have easy access to it here without looking it up.
                            // But we can just overwrite the player slot.
                            console.log(`[JOIN] Overwriting old socket ${room.players[role].id} with new ${socket.id}`);
                        }
                        // Proceed to join (overwrite)
                    } else {
                        return socket.emit('error', `Role ${role} is already taken`);
                    }
                }
    
                // Check Name Uniqueness (if not the same player we just handled above)
                const existingPlayer = Object.values(room.players).find(p => p && p.name === playerName && p !== room.players[role]);
                if (existingPlayer) {
                    return socket.emit('error', `Name "${playerName}" is already taken in this room`);
                }
            }
    
            // Join Room
            socket.join(roomId);
            room.players[role] = { 
                id: socket.id, 
                name: playerName, 
                status: 'online',
                joinedAt: Date.now()
            };
            
            // Notify user
            socket.emit('joined_room', { 
                roomId, 
                role, 
                gameState: room.gameState,
                players: getPublicPlayers(room),
                chatHistory: room.chatHistory || [] // Send chat history
            });
    
            // Notify others in room
            ioToUse.to(roomId).emit('player_update', getPublicPlayers(room));
            ioToUse.emit('room_list', getRoomList()); // Update lobby
            
            // Start Game if full
            if (room.players.tiger && room.players.goat) {
                // Generate unique numeric match ID (timestamp + random suffix)
                room.currentMatchId = Date.now() * 1000 + Math.floor(Math.random() * 1000);
                
                room.gameState.gameActive = true;
                ioToUse.to(roomId).emit('game_start', {
                    gameState: room.gameState,
                    matchId: room.currentMatchId
                });
            }
        });
    
        socket.on('player_status', ({ roomId, status }) => {
            const room = rooms[roomId];
            if (!room) return;
    
            const role = getPlayerRole(room, socket.id);
            if (role && room.players[role]) {
                room.players[role].status = status;
                // Broadcast status update
                ioToUse.to(roomId).emit('player_status_update', {
                    players: getPublicPlayers(room)
                });
            }
        });
    
        socket.on('make_move', ({ roomId, move }) => {
            const room = rooms[roomId];
            if (!room) return;
            
            const playerRole = getPlayerRole(room, socket.id);
            if (!playerRole || room.gameState.turn !== playerRole) return;
            
            // Apply Move Logic (Same as before)
            applyMove(room.gameState, move, playerRole);
            
            ioToUse.to(roomId).emit('update_game', { gameState: room.gameState });
            
            if (room.gameState.winner) {
                ioToUse.to(roomId).emit('game_over', { winner: room.gameState.winner });
            }
        });
    
        socket.on('restart_game', ({ roomId }) => {
            const room = rooms[roomId];
            if (!room) return;
            
            // Generate new unique numeric match ID for restarted game
            room.currentMatchId = Date.now() * 1000 + Math.floor(Math.random() * 1000);
            
            // Reset Game State but keep players
            room.gameState = createInitialGameState();
            room.gameState.gameActive = true;
            room.chatHistory = []; // Clear chat history
            ioToUse.to(roomId).emit('game_start', {
                gameState: room.gameState,
                matchId: room.currentMatchId
            });
            ioToUse.to(roomId).emit('chat_cleared'); // Notify clients to clear chat
        });
    
        socket.on('leave_room', ({ roomId }) => {
            handleLeave(socket, roomId, ioToUse);
        });
    
        socket.on('chat_message', ({ roomId, message }) => {
            const room = rooms[roomId];
            if (!room) return;
            
            const role = getPlayerRole(room, socket.id);
            if (!role) return;
            
            const player = room.players[role];
            
            // Create message object
            const chatMessage = {
                id: Date.now() + '_' + role, // Unique ID
                sender: player.name,
                role: role,
                text: message,
                timestamp: Date.now(),
                seenBy: [role] // Sender has seen it
            };
            
            // Store in room history (limit to 50 messages)
            if (!room.chatHistory) room.chatHistory = [];
            room.chatHistory.push(chatMessage);
            if (room.chatHistory.length > 50) {
                room.chatHistory.shift(); // Remove oldest message
            }
            
            // Broadcast to room
            ioToUse.to(roomId).emit('chat_message', chatMessage);
        });
    
        socket.on('mark_messages_seen', ({ roomId }) => {
            const room = rooms[roomId];
            if (!room) return;
            
            const role = getPlayerRole(room, socket.id);
            if (!role) return;
            
            // Mark all messages as seen by this role
            if (room.chatHistory) {
                const seenMessageIds = [];
                room.chatHistory.forEach(msg => {
                    if (!msg.seenBy.includes(role)) {
                        msg.seenBy.push(role);
                        seenMessageIds.push(msg.id);
                    }
                });
                
                // Notify others in room that messages were seen
                if (seenMessageIds.length > 0) {
                    socket.to(roomId).emit('messages_seen', {
                        seenBy: role,
                        messageIds: seenMessageIds
                    });
                }
            }
        });
    
        socket.on('disconnect', () => {
            // Find which room user was in
            for (const roomId in rooms) {
                const room = rooms[roomId];
                if (room.players.tiger?.id === socket.id || room.players.goat?.id === socket.id) {
                    handleLeave(socket, roomId, ioToUse);
                }
            }
        });
    };

    // Attach connection handler
    ioToUse.on('connection', onConnection);
    
    return router;
};

// Standalone execution
if (require.main === module) {
    app.use(express.static(path.join(__dirname, '../public')));
    const PORT = process.env.PORT || 3002; // Default to 3002 for standalone
    server.listen(PORT, () => {
      console.log(`Bagh Chal server listening on *:${PORT}`);
    });
    
    // Initialize standalone socket logic
    module.exports(io);
}

// Updated handleLeave to accept io instance
function handleLeave(socket, roomId, ioInstance) {
    console.log(`[LEAVE] handleLeave called for socket ${socket.id} in room ${roomId}`);
    const room = rooms[roomId];
    if (!room) {
        console.log(`[LEAVE] Room ${roomId} not found`);
        return;
    }

    const role = getPlayerRole(room, socket.id);
    console.log(`[LEAVE] Player role: ${role}`);
    
    if (role) {
        const playerInfo = room.players[role];
        
        // Store disconnected player info for reconnection grace period
        const disconnectKey = `${roomId}:${role}:${playerInfo.name}`;
        console.log(`[LEAVE] Player ${playerInfo.name} (${role}) disconnecting. Key: ${disconnectKey}`);
        
        // Create timeout to remove player from room if they don't return
        const playerTimeoutId = setTimeout(() => {
            console.log(`[TIMEOUT] Player grace period expired for ${playerInfo.name} (${role})`);
            
            // Check if still disconnected (and room still exists)
            if (rooms[roomId] && rooms[roomId].players[role] && rooms[roomId].players[role].status === 'disconnected') {
                 console.log(`[TIMEOUT] Removing player ${role} from room`);
                 rooms[roomId].players[role] = null; // Remove from room
                 disconnectedPlayers.delete(disconnectKey); // Remove from reconnect map
                 
                 // Notify others
                 ioInstance.to(roomId).emit('player_update', getPublicPlayers(rooms[roomId]));
                 ioInstance.emit('room_list', getRoomList());
            }
        }, RECONNECT_GRACE_PERIOD);

        disconnectedPlayers.set(disconnectKey, {
            roomId,
            role,
            name: playerInfo.name,
            password: room.password,
            gameState: room.gameState,
            timeout: playerTimeoutId // Store timeout to clear on reconnect
        });
        console.log(`[LEAVE] Set disconnectedPlayers entry for ${disconnectKey}`);
        
        // room.players[role] = null; // Remove player - OLD
        room.players[role].status = 'disconnected'; // Mark as disconnected - NEW
        socket.leave(roomId);
        
        // Check if both players are now disconnected
        const tigerGone = !room.players.tiger || room.players.tiger.status === 'disconnected';
        const goatGone = !room.players.goat || room.players.goat.status === 'disconnected';
        const bothPlayersGone = tigerGone && goatGone;
        
        // Notify others that player disconnected
        ioInstance.to(roomId).emit('player_update', getPublicPlayers(room));
        ioInstance.emit('room_list', getRoomList());
        
        if (bothPlayersGone) {
            // Both players disconnected - start room cleanup timeout
            // Clear any existing timeout first
            if (roomTimeouts.has(roomId)) {
                clearTimeout(roomTimeouts.get(roomId));
            }
            
            console.log(`Both players disconnected from ${roomId}. Starting ${RECONNECT_GRACE_PERIOD}ms grace period...`);
            
            const roomTimeoutId = setTimeout(() => {
                console.log(`Grace period expired for ${roomId}. Checking if room is still empty...`);
                
                // Double-check room is still empty (in case someone reconnected)
                const tigerStillGone = !room.players.tiger || room.players.tiger.status === 'disconnected';
                const goatStillGone = !room.players.goat || room.players.goat.status === 'disconnected';
                
                if (tigerStillGone && goatStillGone) {
                    console.log(`Room ${roomId} still empty. Resetting...`);
                    
                    // Clean up all disconnected players for this room
                    for (const key of disconnectedPlayers.keys()) {
                        if (key.startsWith(`${roomId}:`)) {
                            disconnectedPlayers.delete(key);
                        }
                    }
                    
                    // Explicitly remove players now that grace period is over
                    room.players.tiger = null;
                    room.players.goat = null;
                    
                    // If room is archived and empty, delete it permanently
                    if (room.isArchived) {
                        delete rooms[roomId];
                        ioInstance.emit('room_list', getRoomList());
                        roomTimeouts.delete(roomId);
                        return;
                    }

                    // Only reset password if it wasn't pre-set
                    if (!room.isProtected) {
                        room.password = null;
                        room.isActive = false;
                    }
                    room.gameState = createInitialGameState();
                    room.chatHistory = []; // Clear chat history
                    ioInstance.emit('room_list', getRoomList());
                } else {
                    console.log(`Room ${roomId} has players again. Skipping reset.`);
                }
                
                roomTimeouts.delete(roomId);
            }, RECONNECT_GRACE_PERIOD);
            
            roomTimeouts.set(roomId, roomTimeoutId);
        } else {
            // Only one player left - just notify them
            console.log(`One player (${role}) left ${roomId}. Other player still present.`);
        }
        
        if (room.players.tiger || room.players.goat) {
            // Notify remaining player
            ioInstance.to(roomId).emit('player_left', { role });
            // Also update player info to show opponent left (or waiting)
             ioInstance.to(roomId).emit('player_update', getPublicPlayers(room));
        }
        
        ioInstance.emit('room_list', getRoomList());
    }
}

function getRoomList() {
    return Object.values(rooms)
        .filter(r => !r.isArchived) // Hide archived rooms from lobby
        .map(r => {
        // Check if room is actually active (has at least one player)
        // This ensures accurate status even during grace period
        const hasPlayers = r.players.tiger || r.players.goat;
        
        const roomData = {
            id: r.id,
            name: r.name,
            type: r.type, // 'public' or 'private'
            players: {
                tiger: r.players.tiger ? { name: r.players.tiger.name, joinedAt: r.players.tiger.joinedAt, status: r.players.tiger.status } : null,
                goat: r.players.goat ? { name: r.players.goat.name, joinedAt: r.players.goat.joinedAt, status: r.players.goat.status } : null
            },
            isActive: hasPlayers && r.isActive  // Only active if has players AND flag is true
        };
        
        // Include password only for public rooms
        if (r.type === 'public') {
            roomData.password = r.password;
        }
        
        return roomData;
    });
}

function getPublicPlayers(room) {
    return {
        tiger: room.players.tiger ? { name: room.players.tiger.name, status: room.players.tiger.status } : null,
        goat: room.players.goat ? { name: room.players.goat.name, status: room.players.goat.status } : null
    };
}

function getPlayerRole(room, socketId) {
    if (room.players.tiger?.id === socketId) return 'tiger';
    if (room.players.goat?.id === socketId) return 'goat';
    return null;
}

function hasValidMoves(gameState, role) {
    const board = gameState.board;
    
    // Find all pieces of the specified role
    const pieces = [];
    for (let r = 0; r < 5; r++) {
        for (let c = 0; c < 5; c++) {
            if (board[r][c] === role) {
                pieces.push({ r, c });
            }
        }
    }
    
    // Check if any piece has a valid move
    for (const piece of pieces) {
        const { r, c } = piece;
        
        // Check all possible directions (orthogonal and diagonal)
        const directions = [
            [-1, 0], [1, 0], [0, -1], [0, 1],  // Orthogonal
            [-1, -1], [-1, 1], [1, -1], [1, 1]  // Diagonal
        ];
        
        for (const [dr, dc] of directions) {
            const newR = r + dr;
            const newC = c + dc;
            
            // Check bounds
            if (newR < 0 || newR >= 5 || newC < 0 || newC >= 5) continue;
            
            // Check if diagonal move is allowed (only on center/corner spots)
            const isDiagonal = Math.abs(dr) === 1 && Math.abs(dc) === 1;
            const canMoveDiagonal = (r + c) % 2 === 0;
            if (isDiagonal && !canMoveDiagonal) continue;
            
            // Check if spot is empty (simple move)
            if (!board[newR][newC]) {
                return true;
            }
            
            // For tigers, also check jump moves
            if (role === 'tiger') {
                const jumpR = r + 2 * dr;
                const jumpC = c + 2 * dc;
                
                // Check bounds for jump
                if (jumpR < 0 || jumpR >= 5 || jumpC < 0 || jumpC >= 5) continue;
                
                // Check if can jump diagonally
                if (isDiagonal && !canMoveDiagonal) continue;
                
                // Check if there's a goat to jump over and landing spot is empty
                if (board[newR][newC] === 'goat' && !board[jumpR][jumpC]) {
                    return true;
                }
            }
        }
    }
    
    return false;
}



function applyMove(gameState, move, playerRole) {
    const { type, from, to, r, c } = move;

    if (type === 'place' && playerRole === 'goat') {
        if (gameState.goatsPlaced >= 20 || gameState.board[r][c]) return;
        gameState.board[r][c] = 'goat';
        gameState.goatsPlaced++;
        gameState.turn = 'tiger';
        gameState.lastMove = { type: 'place', to: { r, c } };
    } 
    else if (type === 'move') {
        const piece = gameState.board[from.r][from.c];
        if (piece !== playerRole) return;
        
        gameState.board[to.r][to.c] = piece;
        gameState.board[from.r][from.c] = null;
        
        // Capture Logic
        if (playerRole === 'tiger') {
            const dr = Math.abs(from.r - to.r);
            const dc = Math.abs(from.c - to.c);
            if (dr === 2 || dc === 2) {
                const midR = (from.r + to.r) / 2;
                const midC = (from.c + to.c) / 2;
                
                // Validate capture
                if (gameState.board[midR][midC] === 'goat') {
                    gameState.board[midR][midC] = null;
                    gameState.goatsCaptured++;
                    console.log(`Goat captured! Total: ${gameState.goatsCaptured}`);
                }
            }
        }
        
        gameState.turn = playerRole === 'goat' ? 'tiger' : 'goat';
        gameState.lastMove = { type: 'move', from, to };
    }
    
    // Win Conditions
    if (gameState.goatsCaptured >= 5) {
        gameState.winner = 'tiger';
        gameState.gameActive = false;
    }
    
    // Check if tigers are trapped (goat win condition)
    // Check after every goat's move (placement or movement)
    if (playerRole === 'goat') {
        if (!hasValidMoves(gameState, 'tiger')) {
            gameState.winner = 'goat';
            gameState.gameActive = false;
            console.log('Tigers have no valid moves! Goats win!');
        }
    }
}

