// Multiplayer Grid Battle Game Client
// Integrates with SQLite backend via REST API

// Game configuration - loaded from server
let GAME_CONFIG = null;

// Multiplayer game state
let multiplayerState = null;

// Initialize game state after config is loaded
function initializeGameState() {
    multiplayerState = {
        // Connection info
        gameId: null,
        playerId: null,
        playerNumber: null,
        playerName: null,
        
        // Game state
        gameStatus: 'disconnected', // disconnected, waiting, playing, finished
        currentTurn: GAME_CONFIG.INITIAL_TURN,
        turnStatus: 'waiting_for_submission', // waiting_for_submission, waiting_for_opponent, executed
        
        // Grid and players
        grid: [],
        players: {},
        
        // Turn management
        turnActions: [],
        movesRemaining: GAME_CONFIG.MOVES_PER_TURN,
        shotAvailable: true,
        ghostPreviews: [],
        
        // Polling
        pollTimer: null,
        lastPollTime: 0,
        
        // Game end handling
        pendingGameEnd: null,
        finalTurnAnimated: false
    };
}

// DOM elements
const gameGrid = document.getElementById('game-grid');
const statusText = document.getElementById('status-text');
const playerName = document.getElementById('player-name');
const movesRemaining = document.getElementById('moves-remaining');
const shotAvailable = document.getElementById('shot-available');
const actionsQueued = document.getElementById('actions-queued');
const submitButton = document.getElementById('submit-turn');
const undoButton = document.getElementById('undo-action');

// Initialize when page loads
document.addEventListener('DOMContentLoaded', async function() {
    await loadGameConfig();
    initializeGameState();
    initializeMultiplayerGame();
    setupEventListeners();
});

// Load game configuration from server
async function loadGameConfig() {
    try {
        console.log('Loading game configuration from server...');
        const response = await fetch('/api/config');
        const result = await response.json();
        
        if (result.success) {
            GAME_CONFIG = result.config;
            console.log('Game configuration loaded:', GAME_CONFIG);
        } else {
            throw new Error('Failed to load config from server');
        }
    } catch (error) {
        console.error('Error loading config, using fallback:', error);
        // Fallback configuration if server config fails
        GAME_CONFIG = {
            GRID_WIDTH: 10,
            GRID_HEIGHT: 10,
            MOVES_PER_TURN: 4,
            SHOTS_PER_TURN: 1,
            CELL_SIZE_PX: 30,
            POLLING_INTERVAL: 1500,
            PLAYER_ONE_NUMBER: 1,
            PLAYER_TWO_NUMBER: 2,
            MAX_PLAYERS: 2,
            INITIAL_TURN: 1,
            GAME_END_DELAY: 2000,
            MOVEMENT_ANIMATION_DELAY: 200,
            ERROR_FLASH_DURATION: 500,
            COPY_FEEDBACK_DELAY: 2000,
            DIRECTION_OFFSETS: {
                NORTH: { row: -1, col: 0 },
                SOUTH: { row: 1, col: 0 },
                EAST: { row: 0, col: 1 },
                WEST: { row: 0, col: -1 }
            }
        };
    }
}

async function initializeMultiplayerGame() {
    console.log('Initializing Multiplayer Grid Battle Game...');
    
    // Initialize UI first (grid needs to exist before adding players)
    initializeGrid();
    renderGrid();
    updateGameStatus('Ready to start');
    updateMovesDisplay();
    updateActionButtons();
    
    // Check if we're joining an existing game via URL
    const urlPath = window.location.pathname;
    console.log('Current URL path:', urlPath);
    const gameIdMatch = urlPath.match(/\/game\/([a-f0-9-]+)/);
    
    if (gameIdMatch) {
        // Joining existing game
        console.log('Detected game ID in URL:', gameIdMatch[1]);
        multiplayerState.gameId = gameIdMatch[1];
        await showJoinGameInterface();
    } else {
        // Creating new game
        console.log('No game ID in URL, creating new game');
        await showCreateGameInterface();
    }
}

async function showCreateGameInterface() {
    const playerNameInput = prompt('Enter your name to create a new game:');
    if (!playerNameInput || playerNameInput.trim().length === 0) {
        updateGameStatus('Name required to create game');
        return;
    }
    
    multiplayerState.playerName = playerNameInput.trim();
    updatePlayerInfo(multiplayerState.playerName);
    
    try {
        updateGameStatus('Creating game...');
        console.log('Sending API request to create game for:', multiplayerState.playerName);
        
        const response = await fetch('/api/games', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ playerName: multiplayerState.playerName })
        });
        
        console.log('API response status:', response.status);
        const result = await response.json();
        console.log('API response data:', result);
        
        if (result.success) {
            multiplayerState.gameId = result.gameId;
            multiplayerState.playerId = result.playerId;
            multiplayerState.playerNumber = result.playerNumber;
            multiplayerState.gameStatus = 'waiting';
            
            // Add player 1 to grid
            addPlayerToGrid(result.playerNumber, result.spawnPosition.x, result.spawnPosition.y);
            
            // Store player 1 data for movement validation
            multiplayerState.players[result.playerNumber] = {
                id: result.playerId,
                name: multiplayerState.playerName,
                x: result.spawnPosition.x,
                y: result.spawnPosition.y
            };
            
            // Show invite link
            showInviteLink(result.inviteLink);
            
            // Start polling for player 2
            startGamePolling();
            
            updateGameStatus('Waiting for player 2 to join...');
            
        } else {
            throw new Error(result.error || 'Failed to create game');
        }
        
    } catch (error) {
        console.error('Error creating game:', error);
        console.error('Error details:', error.stack);
        updateGameStatus('Failed to create game: ' + error.message);
        
        // Also show alert for debugging
        alert('Error creating game: ' + error.message + '\nCheck console for details.');
    }
}

async function showJoinGameInterface() {
    const playerNameInput = prompt('Enter your name to join the game:');
    if (!playerNameInput || playerNameInput.trim().length === 0) {
        updateGameStatus('Name required to join game');
        return;
    }
    
    multiplayerState.playerName = playerNameInput.trim();
    updatePlayerInfo(multiplayerState.playerName);
    
    try {
        updateGameStatus('Joining game...');
        
        const response = await fetch(`/api/games/${multiplayerState.gameId}/join`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ playerName: multiplayerState.playerName })
        });
        
        const result = await response.json();
        
        if (result.success) {
            multiplayerState.playerId = result.playerId;
            multiplayerState.playerNumber = result.playerNumber;
            multiplayerState.gameStatus = 'playing';
            
            // Load full game state
            await loadGameState();
            
            // Start polling for game updates
            startGamePolling();
            
            updateGameStatus('Game started! Plan your moves.');
            updateActionButtons(); // Enable buttons for Player 2
            
        } else {
            throw new Error(result.error || 'Failed to join game');
        }
        
    } catch (error) {
        console.error('Error joining game:', error);
        updateGameStatus('Failed to join game: ' + error.message);
    }
}

async function loadGameState() {
    try {
        const response = await fetch(`/api/games/${multiplayerState.gameId}`);
        const gameState = await response.json();
        
        if (gameState.game && gameState.players) {
            // Update game info
            multiplayerState.currentTurn = gameState.game.current_turn;
            multiplayerState.gameStatus = gameState.game.status;
            
            // Clear existing players
            clearPlayersFromGrid();
            
            // Add all players to grid
            gameState.players.forEach(player => {
                if (player.is_alive) {
                    addPlayerToGrid(player.player_number, player.current_x, player.current_y);
                } else {
                    // Show dead player
                    showPlayerDeath(player.current_x, player.current_y);
                }
                
                multiplayerState.players[player.player_number] = {
                    id: player.player_id,
                    name: player.username,
                    x: player.current_x,
                    y: player.current_y,
                    alive: Boolean(player.is_alive)
                };
            });
            
            renderGrid();
        }
        
    } catch (error) {
        console.error('Error loading game state:', error);
    }
}

function showInviteLink(inviteLink) {
    console.log('showInviteLink called with:', inviteLink);
    
    // Create a temporary modal-like display
    const linkDisplay = document.createElement('div');
    linkDisplay.style.cssText = `
        position: fixed; top: 20px; left: 50%; transform: translateX(-50%);
        background: #2a2a2a; border: 2px solid #00ff00; border-radius: 8px;
        padding: 20px; z-index: 1000; max-width: 500px;
        color: white; text-align: center;
    `;
    
    linkDisplay.innerHTML = `
        <h3>Game Created!</h3>
        <p>Share this link with your opponent:</p>
        <input type="text" value="${inviteLink}" readonly style="
            width: 100%; padding: 10px; margin: 10px 0; 
            background: #333; color: white; border: 1px solid #555;
            border-radius: 4px; text-align: center;
        ">
        <button id="copy-link-btn" style="
            background: #0066ff; color: white; border: none; 
            padding: 10px 20px; border-radius: 4px; cursor: pointer;
        ">Copy Link</button>
        <button onclick="this.parentElement.remove()" style="
            background: #666; color: white; border: none; 
            padding: 10px 20px; border-radius: 4px; cursor: pointer; margin-left: 10px;
        ">Close</button>
    `;
    
    // Add event listener for copy button
    const copyBtn = linkDisplay.querySelector('#copy-link-btn');
    copyBtn.addEventListener('click', async () => {
        try {
            await navigator.clipboard.writeText(inviteLink);
            copyBtn.textContent = 'Copied!';
            setTimeout(() => {
                copyBtn.textContent = 'Copy Link';
            }, 2000);
        } catch (error) {
            console.error('Failed to copy link:', error);
            // Fallback: select the text for manual copying
            const input = linkDisplay.querySelector('input');
            input.select();
            input.setSelectionRange(0, 99999); // For mobile devices
            copyBtn.textContent = 'Selected - Press Ctrl+C';
        }
    });
    
    document.body.appendChild(linkDisplay);
}

function startGamePolling() {
    if (multiplayerState.pollTimer) {
        clearInterval(multiplayerState.pollTimer);
    }
    
    multiplayerState.pollTimer = setInterval(async () => {
        await pollGameStatus();
    }, GAME_CONFIG.POLLING_INTERVAL);
    
    console.log('Started polling for game updates');
}

async function pollGameStatus() {
    try {
        const response = await fetch(`/api/games/${multiplayerState.gameId}/status?playerId=${multiplayerState.playerId}`);
        const status = await response.json();
        
        if (status.needsUpdate || status.game.current_turn !== multiplayerState.currentTurn) {
            await handleGameUpdate(status);
        }
        
    } catch (error) {
        console.error('Polling error:', error);
    }
}

async function handleGameUpdate(status) {
    const previousStatus = multiplayerState.gameStatus;
    const previousTurn = multiplayerState.currentTurn;
    
    // Update local state
    multiplayerState.gameStatus = status.game.status;
    multiplayerState.currentTurn = status.game.current_turn;
    multiplayerState.turnStatus = status.turnStatus;
    
    // Handle status changes
    if (previousStatus === 'waiting' && status.game.status === 'playing') {
        updateGameStatus('Player 2 joined! Game started.');
        await loadGameState();
        updateActionButtons(); // Re-enable buttons now that game is playing
    }
    
    if (previousTurn !== status.game.current_turn || 
        (status.game.status === 'finished' && !multiplayerState.finalTurnAnimated)) {
        
        // New turn started OR game ended - show what happened in previous turn
        const animationTurn = status.game.status === 'finished' ? status.game.current_turn : previousTurn;
        
        if (status.game.status === 'finished') {
            multiplayerState.finalTurnAnimated = true;
        }
        
        await showTurnResults(status.recentEvents, animationTurn);
        
        // Only reset turn state and load if game is still playing
        if (status.game.status === 'playing') {
            resetTurnState();
            await loadGameState();
            updateGameStatus(`Turn ${status.game.current_turn} - Plan your moves`);
        } else {
            // Game ended - load final state but don't reset turn state
            await loadGameState();
        }
    }
    
    // Update turn status display
    if (status.turnStatus === 'waiting_for_opponent') {
        updateGameStatus('Waiting for opponent to submit turn...');
    } else if (status.turnStatus === 'executed') {
        updateGameStatus('Turn executed! Plan your next moves.');
    }
    
    // Handle game end
    if (status.game.status === 'finished') {
        handleGameEnd(status.game);
    }
}

function handleGameEnd(game) {
    console.log('Game ended detected, but deferring end screen until animations complete');
    
    clearInterval(multiplayerState.pollTimer);
    
    // Disable controls
    document.querySelectorAll('.move-btn, .shoot-btn').forEach(btn => {
        btn.disabled = true;
    });
    submitButton.disabled = true;
    undoButton.disabled = true;
    
    // Store game end info but don't show screen yet - let animations finish
    multiplayerState.pendingGameEnd = {
        isWinner: game.winner_id === multiplayerState.playerId,
        game: game
    };
}

function resetTurnState() {
    multiplayerState.turnActions = [];
    multiplayerState.movesRemaining = GAME_CONFIG.MOVES_PER_TURN;
    multiplayerState.shotAvailable = true;
    clearGhostPreviews();
    updateMovesDisplay();
    updateActionButtons();
}

// API Integration Functions
async function submitTurn() {
    if (multiplayerState.turnActions.length === 0) {
        updateGameStatus('No actions to submit');
        return;
    }
    
    try {
        updateGameStatus('Submitting turn...');
        
        const response = await fetch(`/api/games/${multiplayerState.gameId}/submit-turn`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                playerId: multiplayerState.playerId,
                actions: multiplayerState.turnActions
            })
        });
        
        const result = await response.json();
        
        if (result.success) {
            if (result.bothPlayersSubmitted) {
                updateGameStatus('Both players submitted! Executing turn...');
            } else {
                updateGameStatus('Turn submitted. Waiting for opponent...');
            }
            
            // Disable controls until next turn
            document.querySelectorAll('.move-btn, .shoot-btn').forEach(btn => {
                btn.disabled = true;
            });
            submitButton.disabled = true;
            
        } else {
            throw new Error(result.error || 'Failed to submit turn');
        }
        
    } catch (error) {
        console.error('Error submitting turn:', error);
        updateGameStatus('Failed to submit turn: ' + error.message);
    }
}

// Grid Management Functions
function initializeGrid() {
    multiplayerState.grid = [];
    for (let row = 0; row < GAME_CONFIG.GRID_HEIGHT; row++) {
        multiplayerState.grid[row] = [];
        for (let col = 0; col < GAME_CONFIG.GRID_WIDTH; col++) {
            multiplayerState.grid[row][col] = {
                type: 'empty',
                player: null,
                bullet: null
            };
        }
    }
}

function addPlayerToGrid(playerNumber, x, y) {
    console.log(`Adding player ${playerNumber} to grid at position (${x}, ${y})`);
    
    if (!multiplayerState.grid || multiplayerState.grid.length === 0) {
        console.error('Grid not initialized when trying to add player');
        return;
    }
    
    if (isValidPosition(x, y)) {
        multiplayerState.grid[y][x].player = playerNumber;
        console.log(`Player ${playerNumber} successfully added to grid`);
    } else {
        console.error(`Invalid position for player ${playerNumber}: (${x}, ${y})`);
    }
}

function clearPlayersFromGrid() {
    for (let row = 0; row < GAME_CONFIG.GRID_HEIGHT; row++) {
        for (let col = 0; col < GAME_CONFIG.GRID_WIDTH; col++) {
            multiplayerState.grid[row][col].player = null;
        }
    }
}

function renderGrid() {
    // Clear existing grid
    gameGrid.innerHTML = '';
    
    // Create grid cells
    for (let row = 0; row < GAME_CONFIG.GRID_HEIGHT; row++) {
        for (let col = 0; col < GAME_CONFIG.GRID_WIDTH; col++) {
            const cell = createGridCell(row, col);
            gameGrid.appendChild(cell);
        }
    }
}

function createGridCell(row, col) {
    const cell = document.createElement('div');
    cell.className = 'grid-cell';
    cell.dataset.row = row;
    cell.dataset.col = col;
    
    // Add cell content based on game state
    const cellData = multiplayerState.grid[row][col];
    
    if (cellData.player) {
        cell.classList.add(`player-${cellData.player}`);
        cell.textContent = cellData.player === 1 ? 'P1' : 'P2';
    }
    
    if (cellData.bullet) {
        cell.classList.add('bullet');
        cell.textContent = '•';
    }
    
    return cell;
}

// Action Management (reuse existing functions with API integration)
function setupEventListeners() {
    // Move buttons
    document.querySelectorAll('.move-btn').forEach(button => {
        button.addEventListener('click', function() {
            const direction = this.dataset.direction;
            addMoveAction(direction);
        });
    });
    
    // Shoot buttons
    document.querySelectorAll('.shoot-btn').forEach(button => {
        button.addEventListener('click', function() {
            const direction = this.dataset.direction;
            addShootAction(direction);
        });
    });
    
    // Submit turn button
    submitButton.addEventListener('click', function() {
        submitTurn();
    });
    
    // Undo button
    undoButton.addEventListener('click', function() {
        undoLastAction();
    });
}

function addMoveAction(direction) {
    if (multiplayerState.gameStatus !== 'playing') {
        updateGameStatus('Game not active');
        return;
    }
    
    if (multiplayerState.movesRemaining <= 0) {
        flashErrorButton('move', direction);
        updateGameStatus('No moves remaining this turn');
        return;
    }
    
    // Check if this move would be valid
    if (!isValidMoveAction(direction)) {
        flashErrorButton('move', direction);
        return;
    }
    
    const action = {
        type: 'move',
        direction: direction,
        timestamp: Date.now()
    };
    
    multiplayerState.turnActions.push(action);
    multiplayerState.movesRemaining--;
    
    updateGhostPreviews();
    updateMovesDisplay();
    updateActionButtons();
    
    console.log(`Added move action: ${direction}`);
    updateGameStatus(`Move added: ${direction.toUpperCase()}`);
}

function addShootAction(direction) {
    if (multiplayerState.gameStatus !== 'playing') {
        updateGameStatus('Game not active');
        return;
    }
    
    if (!multiplayerState.shotAvailable) {
        flashErrorButton('shoot', direction);
        updateGameStatus('Shot already used this turn');
        return;
    }
    
    const action = {
        type: 'shoot',
        direction: direction,
        timestamp: Date.now()
    };
    
    multiplayerState.turnActions.push(action);
    multiplayerState.shotAvailable = false;
    
    updateGhostPreviews();
    updateMovesDisplay();
    updateActionButtons();
    
    console.log(`Added shoot action: ${direction}`);
    updateGameStatus(`Shot added: ${direction.toUpperCase()}`);
}

// UI Update Functions
function updateGameStatus(message) {
    statusText.textContent = message;
    console.log(`Status: ${message}`);
}

function updatePlayerInfo(name) {
    playerName.textContent = name;
}

function updateMovesDisplay() {
    const used = GAME_CONFIG.MOVES_PER_TURN - multiplayerState.movesRemaining;
    movesRemaining.textContent = `Moves: ${used}/${GAME_CONFIG.MOVES_PER_TURN}`;
    
    if (multiplayerState.shotAvailable) {
        shotAvailable.textContent = 'Shot: Available';
        shotAvailable.classList.remove('used');
    } else {
        shotAvailable.textContent = 'Shot: Used';
        shotAvailable.classList.add('used');
    }
    
    actionsQueued.textContent = `Actions: ${multiplayerState.turnActions.length}`;
}

function updateActionButtons() {
    const hasActions = multiplayerState.turnActions.length > 0;
    const gameActive = multiplayerState.gameStatus === 'playing';
    
    submitButton.disabled = !hasActions || !gameActive;
    undoButton.disabled = !hasActions || !gameActive;
    
    // Enable/disable action buttons based on game state
    document.querySelectorAll('.move-btn, .shoot-btn').forEach(btn => {
        btn.disabled = !gameActive;
    });
}

function undoLastAction() {
    if (multiplayerState.turnActions.length === 0) {
        updateGameStatus('No actions to undo');
        return;
    }
    
    // Remove the last action
    const lastAction = multiplayerState.turnActions.pop();
    
    // Restore the appropriate resource
    if (lastAction.type === 'move') {
        multiplayerState.movesRemaining++;
    } else if (lastAction.type === 'shoot') {
        multiplayerState.shotAvailable = true;
    }
    
    // Update visual elements
    updateGhostPreviews();
    updateMovesDisplay();
    updateActionButtons();
    
    const actionType = lastAction.type.toUpperCase();
    const direction = lastAction.direction.toUpperCase();
    console.log(`Undid ${actionType} action: ${direction}`);
    updateGameStatus(`Undid: ${actionType} ${direction}`);
}

// Include all the existing validation and preview functions with minimal changes
// (using multiplayerState instead of gameState)

function isValidMoveAction(direction) {
    if (!multiplayerState.players[multiplayerState.playerNumber]) {
        return false;
    }
    
    let finalPos = calculateFinalPlayerPosition();
    const offset = getDirectionOffset(direction);
    const newPos = {
        row: finalPos.y + offset.row,
        col: finalPos.x + offset.col
    };
    
    if (!isValidPosition(newPos.col, newPos.row)) {
        updateGameStatus(`Cannot move ${direction.toUpperCase()} - out of bounds`);
        return false;
    }
    
    if (isPositionInPlayerPath(newPos)) {
        updateGameStatus(`Cannot move ${direction.toUpperCase()} - cannot move through yourself`);
        return false;
    }
    
    return true;
}

function calculateFinalPlayerPosition() {
    const currentPlayer = multiplayerState.players[multiplayerState.playerNumber];
    if (!currentPlayer) return { x: 0, y: 0 };
    
    let currentPos = { x: currentPlayer.x, y: currentPlayer.y };
    
    multiplayerState.turnActions.forEach(action => {
        if (action.type === 'move') {
            const offset = getDirectionOffset(action.direction);
            const newPos = {
                x: currentPos.x + offset.col,
                y: currentPos.y + offset.row
            };
            
            if (isValidPosition(newPos.x, newPos.y)) {
                currentPos = newPos;
            }
        }
    });
    
    return currentPos;
}

function isPositionInPlayerPath(targetPos) {
    const playerPath = calculatePlayerPath();
    return playerPath.some(pos => 
        pos.x === targetPos.col && pos.y === targetPos.row
    );
}

function calculatePlayerPath() {
    const path = [];
    const currentPlayer = multiplayerState.players[multiplayerState.playerNumber];
    if (!currentPlayer) return path;
    
    let currentPos = { x: currentPlayer.x, y: currentPlayer.y };
    path.push({ ...currentPos });
    
    multiplayerState.turnActions.forEach(action => {
        if (action.type === 'move') {
            const offset = getDirectionOffset(action.direction);
            const newPos = {
                x: currentPos.x + offset.col,
                y: currentPos.y + offset.row
            };
            
            if (isValidPosition(newPos.x, newPos.y)) {
                currentPos = newPos;
                path.push({ ...currentPos });
            }
        }
    });
    
    return path;
}

// Ghost preview functions (adapted for multiplayer state with sequential execution)
function updateGhostPreviews() {
    clearGhostPreviews();
    
    const currentPlayer = multiplayerState.players[multiplayerState.playerNumber];
    if (!currentPlayer) return;
    
    let currentPos = { x: currentPlayer.x, y: currentPlayer.y };
    
    // Process actions sequentially to show where shots will fire from
    multiplayerState.turnActions.forEach((action, index) => {
        if (action.type === 'move') {
            const offset = getDirectionOffset(action.direction);
            const newPos = {
                x: currentPos.x + offset.col,
                y: currentPos.y + offset.row
            };
            
            if (isValidPosition(newPos.x, newPos.y)) {
                currentPos = newPos;
                addGhostPreview(newPos.y, newPos.x, 'ghost-move');
            }
        } else if (action.type === 'shoot') {
            // Show bullet path from current position in the sequence
            showBulletPath(currentPos.y, currentPos.x, action.direction);
        }
    });
}

function showBulletPath(startRow, startCol, direction) {
    const offset = getDirectionOffset(direction);
    let currentRow = startRow + offset.row;
    let currentCol = startCol + offset.col;
    
    while (isValidPosition(currentCol, currentRow)) {
        addGhostPreview(currentRow, currentCol, 'ghost-bullet');
        currentRow += offset.row;
        currentCol += offset.col;
    }
}

function addGhostPreview(row, col, className) {
    const cell = getCellElement(row, col);
    if (cell && !cell.classList.contains('player-1') && !cell.classList.contains('player-2')) {
        cell.classList.add(className);
        multiplayerState.ghostPreviews.push({ row, col, className });
    }
}

function clearGhostPreviews() {
    multiplayerState.ghostPreviews.forEach(preview => {
        const cell = getCellElement(preview.row, preview.col);
        if (cell) {
            cell.classList.remove(preview.className);
        }
    });
    multiplayerState.ghostPreviews = [];
}

function getCellElement(row, col) {
    return document.querySelector(`[data-row="${row}"][data-col="${col}"]`);
}

function flashErrorButton(actionType, direction) {
    const buttonSelector = actionType === 'move' ? 
        `.move-btn[data-direction="${direction}"]` : 
        `.shoot-btn[data-direction="${direction}"]`;
    
    const button = document.querySelector(buttonSelector);
    if (button) {
        button.style.animation = 'error-flash 0.5s ease-out';
        setTimeout(() => {
            button.style.animation = '';
        }, 500);
    }
    
    if (actionType === 'move') {
        flashGhostPreviewsRed();
    }
}

function flashGhostPreviewsRed() {
    const ghostCells = document.querySelectorAll('.ghost-move');
    
    ghostCells.forEach(cell => {
        cell.style.animation = 'ghost-error-flash 0.6s ease-out';
        setTimeout(() => {
            cell.style.animation = 'pulse 1.5s ease-in-out infinite';
        }, 600);
    });
}

// Utility functions
function getDirectionOffset(direction) {
    const directionKey = direction.toUpperCase();
    const offset = GAME_CONFIG.DIRECTION_OFFSETS[directionKey];
    return offset || { row: 0, col: 0 };
}

function isValidPosition(x, y) {
    return x >= 0 && x < GAME_CONFIG.GRID_WIDTH && 
           y >= 0 && y < GAME_CONFIG.GRID_HEIGHT;
}

// Show visual feedback for what happened in the previous turn
async function showTurnResults(recentEvents, turnNumber) {
    if (!recentEvents || recentEvents.length === 0) return;
    
    // Filter events from the executed turn
    const turnEvents = recentEvents.filter(event => event.turn_number === turnNumber);
    
    // Group events by action_index and organize by type
    const eventsByActionIndex = {};
    
    turnEvents.forEach(event => {
        try {
            const eventData = JSON.parse(event.event_data);
            const actionIndex = eventData.action_index !== undefined ? eventData.action_index : 0;
            
            if (!eventsByActionIndex[actionIndex]) {
                eventsByActionIndex[actionIndex] = {
                    movements: [],
                    shots: [],
                    hits: []
                };
            }
            
            if (event.event_type === 'player_moved') {
                eventsByActionIndex[actionIndex].movements.push({
                    ...event,
                    eventData: eventData
                });
            } else if (event.event_type === 'shot_fired') {
                eventsByActionIndex[actionIndex].shots.push({
                    ...event,
                    eventData: eventData
                });
            } else if (event.event_type === 'player_hit') {
                eventsByActionIndex[actionIndex].hits.push({
                    ...event,
                    eventData: eventData
                });
            }
        } catch (error) {
            console.error('Error parsing event data:', error);
        }
    });
    
    // Execute animations in sequence by action index
    const actionIndices = Object.keys(eventsByActionIndex).sort((a, b) => parseInt(a) - parseInt(b));
    
    for (const actionIndex of actionIndices) {
        const stepEvents = eventsByActionIndex[actionIndex];
        
        console.log(`Animating action step ${parseInt(actionIndex) + 1}`);
        updateGameStatus(`Showing turn ${turnNumber} step ${parseInt(actionIndex) + 1}...`);
        
        // Step 1: Animate all player movements for this action step
        const movementPromises = stepEvents.movements.map(event => 
            animatePlayerMovement(
                event.eventData.from_x, 
                event.eventData.from_y,
                event.eventData.to_x, 
                event.eventData.to_y,
                event.player_number
            )
        );
        
        await Promise.all(movementPromises);
        
        // Step 2: Fire all shots for this action step (simultaneously with movements)
        const shotPromises = stepEvents.shots.map(event => 
            animateBulletTrail(
                event.eventData.bullet_path, 
                event.eventData.shooter_x, 
                event.eventData.shooter_y
            )
        );
        
        await Promise.all(shotPromises);
        
        // Step 3: Show hit effects
        stepEvents.hits.forEach(event => {
            highlightHit(event.eventData.target_x, event.eventData.target_y);
            showPlayerDeath(event.eventData.target_x, event.eventData.target_y);
        });
        
        // Brief pause between action steps
        if (parseInt(actionIndex) < actionIndices.length - 1) {
            await new Promise(resolve => setTimeout(resolve, GAME_CONFIG.ACTION_STEP_DELAY));
        }
    }
    
    // Check if game ended during this turn and show end screen after animations
    if (multiplayerState.pendingGameEnd) {
        console.log('Animations complete, showing game end screen after delay');
        updateGameStatus('Battle complete! Determining winner...');
        
        // Wait 2 seconds to let players absorb what happened, then show end screen
        setTimeout(() => {
            showGameEndScreen(
                multiplayerState.pendingGameEnd.isWinner, 
                multiplayerState.pendingGameEnd.game
            );
            multiplayerState.pendingGameEnd = null;
        }, 2000);
    } else {
        updateGameStatus(`Turn ${turnNumber} complete - Plan your next moves`);
    }
}

// Animate player movement from one position to another
async function animatePlayerMovement(fromX, fromY, toX, toY, playerNumber) {
    console.log(`Animating player ${playerNumber} from (${fromX},${fromY}) to (${toX},${toY})`);
    
    // Clear previous position
    const fromCell = getCellElement(fromY, fromX);
    if (fromCell) {
        fromCell.classList.remove(`player-${playerNumber}`);
        fromCell.textContent = '';
    }
    
    // Set new position with movement effect
    const toCell = getCellElement(toY, toX);
    if (toCell) {
        // Add temporary movement highlighting
        toCell.classList.add('player-moving');
        
        // Brief delay to show movement
        await new Promise(resolve => setTimeout(resolve, GAME_CONFIG.MOVEMENT_ANIMATION_DELAY));
        
        // Remove movement effect and set final player position
        toCell.classList.remove('player-moving');
        toCell.classList.add(`player-${playerNumber}`);
        toCell.textContent = playerNumber === 1 ? 'P1' : 'P2';
        
        console.log(`Player ${playerNumber} moved to (${toX},${toY})`);
    }
}

// Animate bullet trail visualization
async function animateBulletTrail(bulletPath, shooterX, shooterY) {
    if (!bulletPath || bulletPath.length === 0) return;
    
    // Highlight each cell in the bullet path with a small delay
    for (let i = 0; i < bulletPath.length; i++) {
        const pathCell = bulletPath[i];
        const cell = getCellElement(pathCell.y, pathCell.x);
        
        if (cell && !cell.classList.contains('player-1') && !cell.classList.contains('player-2')) {
            cell.classList.add('bullet-trail');
            
            // Remove the bullet trail class after animation completes
            setTimeout(() => {
                cell.classList.remove('bullet-trail');
            }, 5000);
        }
        
        // Small delay between bullet trail segments for visual effect
        if (i < bulletPath.length - 1) {
            await new Promise(resolve => setTimeout(resolve, GAME_CONFIG.BULLET_SEGMENT_DELAY));
        }
    }
}

// Highlight where a player was hit
function highlightHit(x, y) {
    const cell = getCellElement(y, x);
    if (cell) {
        cell.classList.add('bullet-hit');
        
        // Remove hit highlight after animation
        setTimeout(() => {
            cell.classList.remove('bullet-hit');
        }, 1000);
    }
}

// Show death effect for a player
function showPlayerDeath(x, y) {
    const cell = getCellElement(y, x);
    if (cell) {
        // Remove player class and add death effect
        cell.classList.remove('player-1', 'player-2');
        cell.classList.add('player-dead');
        
        // The death effect will persist to show where the player died
        console.log(`Player death effect shown at (${x},${y})`);
    }
}

// Show game end screen
function showGameEndScreen(isWinner, game) {
    // Create overlay
    const overlay = document.createElement('div');
    overlay.className = 'game-end-overlay';
    
    // Create modal
    const modal = document.createElement('div');
    modal.className = `game-end-modal ${isWinner ? 'winner' : 'loser'}`;
    
    // Create content
    const title = document.createElement('div');
    title.className = 'game-end-title';
    title.textContent = isWinner ? 'YOU WIN!' : 'GAME OVER';
    
    const message = document.createElement('div');
    message.className = 'game-end-message';
    message.textContent = isWinner 
        ? 'Congratulations! You defeated your opponent!' 
        : 'Better luck next time! You were eliminated.';
    
    // Create buttons
    const buttonContainer = document.createElement('div');
    buttonContainer.style.marginTop = '20px';
    
    const playAgainBtn = document.createElement('button');
    playAgainBtn.className = 'game-end-button primary';
    playAgainBtn.textContent = 'Play Again';
    playAgainBtn.onclick = async () => {
        await startRematch();
    };
    
    const newGameBtn = document.createElement('button');
    newGameBtn.className = 'game-end-button';
    newGameBtn.textContent = 'New Game';
    newGameBtn.onclick = () => {
        window.location.href = '/';
    };
    
    const replayBtn = document.createElement('button');
    replayBtn.className = 'game-end-button';
    replayBtn.textContent = 'View Replay';
    replayBtn.onclick = () => {
        // Future feature - for now just show an alert
        alert('Replay feature coming soon!');
    };
    
    buttonContainer.appendChild(playAgainBtn);
    buttonContainer.appendChild(newGameBtn);
    buttonContainer.appendChild(replayBtn);
    
    // Assemble modal
    modal.appendChild(title);
    modal.appendChild(message);
    modal.appendChild(buttonContainer);
    
    // Assemble overlay
    overlay.appendChild(modal);
    
    // Add to page
    document.body.appendChild(overlay);
    
    // Update status
    updateGameStatus(isWinner ? 'Victory!' : 'Defeated!');
}

// Start a rematch with the same players
async function startRematch() {
    try {
        updateGameStatus('Creating rematch...');
        
        // Remove game end overlay
        const overlay = document.querySelector('.game-end-overlay');
        if (overlay) {
            overlay.remove();
        }
        
        const response = await fetch(`/api/games/${multiplayerState.gameId}/rematch`, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ 
                playerId: multiplayerState.playerId,
                playerName: multiplayerState.playerName 
            })
        });
        
        const result = await response.json();
        
        if (result.success) {
            // Stop old polling first
            if (multiplayerState.pollTimer) {
                clearInterval(multiplayerState.pollTimer);
                multiplayerState.pollTimer = null;
            }
            
            // Reset local state for new game
            multiplayerState.gameId = result.newGameId;
            multiplayerState.playerId = result.playerId;
            multiplayerState.playerNumber = result.playerNumber;
            multiplayerState.gameStatus = result.status;
            multiplayerState.currentTurn = 1;
            multiplayerState.turnStatus = 'waiting_for_submission';
            multiplayerState.pendingGameEnd = null;
            multiplayerState.finalTurnAnimated = false;
            
            // Clear old game state
            resetTurnState();
            clearPlayersFromGrid();
            
            // Initialize grid fresh
            initializeGrid();
            renderGrid();
            
            // Add player to new spawn position
            if (result.spawnPosition) {
                addPlayerToGrid(result.playerNumber, result.spawnPosition.x, result.spawnPosition.y);
                multiplayerState.players[result.playerNumber] = {
                    id: result.playerId,
                    name: multiplayerState.playerName,
                    x: result.spawnPosition.x,
                    y: result.spawnPosition.y,
                    alive: true
                };
            }
            
            // Load new game state
            await loadGameState();
            
            // Restart polling for the new game
            startGamePolling();
            
            // Update URL without page reload
            window.history.pushState({}, '', `/game/${result.newGameId}`);
            
            if (result.status === 'waiting') {
                updateGameStatus('Waiting for opponent to join rematch...');
                showRematchInvite(result.inviteLink);
            } else {
                updateGameStatus('Rematch started! Plan your moves.');
                updateActionButtons();
            }
            
        } else {
            throw new Error(result.error || 'Failed to create rematch');
        }
        
    } catch (error) {
        console.error('Error starting rematch:', error);
        updateGameStatus('Failed to start rematch: ' + error.message);
    }
}

// Show rematch invite link
function showRematchInvite(inviteLink) {
    const linkDisplay = document.createElement('div');
    linkDisplay.style.cssText = `
        position: fixed; top: 20px; left: 50%; transform: translateX(-50%);
        background: #2a2a2a; border: 2px solid #00ff00; border-radius: 8px;
        padding: 20px; z-index: 1000; max-width: 500px;
        color: white; text-align: center;
    `;
    
    linkDisplay.innerHTML = `
        <h3>Rematch Created!</h3>
        <p>Share this link with your opponent for the rematch:</p>
        <input type="text" value="${inviteLink}" readonly style="
            width: 100%; padding: 10px; margin: 10px 0; 
            background: #333; color: white; border: 1px solid #555;
            border-radius: 4px; text-align: center;
        ">
        <button id="copy-rematch-link-btn" style="
            background: #0066ff; color: white; border: none; 
            padding: 10px 20px; border-radius: 4px; cursor: pointer;
        ">Copy Link</button>
        <button onclick="this.parentElement.remove()" style="
            background: #666; color: white; border: none; 
            padding: 10px 20px; border-radius: 4px; cursor: pointer; margin-left: 10px;
        ">Close</button>
    `;
    
    // Add event listener for copy button
    const copyBtn = linkDisplay.querySelector('#copy-rematch-link-btn');
    copyBtn.addEventListener('click', async () => {
        try {
            await navigator.clipboard.writeText(inviteLink);
            copyBtn.textContent = 'Copied!';
            setTimeout(() => {
                copyBtn.textContent = 'Copy Link';
            }, 2000);
        } catch (error) {
            console.error('Failed to copy link:', error);
            // Fallback: select the text for manual copying
            const input = linkDisplay.querySelector('input');
            input.select();
            input.setSelectionRange(0, 99999); // For mobile devices
            copyBtn.textContent = 'Selected - Press Ctrl+C';
        }
    });
    
    document.body.appendChild(linkDisplay);
}