// Game configuration - matches server-side config
const GAME_CONFIG = {
    GRID_WIDTH: 20,
    GRID_HEIGHT: 20,
    MOVES_PER_TURN: 4,
    SHOTS_PER_TURN: 1,
    CELL_SIZE_PX: 30
};

// Game state
let gameState = {
    grid: [],
    players: {},
    currentPlayer: 1, // For now, assume we're player 1
    gamePhase: 'waiting', // waiting, playing, game_over
    turnActions: [],
    movesRemaining: GAME_CONFIG.MOVES_PER_TURN,
    shotAvailable: true,
    ghostPreviews: [] // Track ghost preview positions
};

// 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 game when page loads
document.addEventListener('DOMContentLoaded', function() {
    initializeGame();
    setupEventListeners();
});

function initializeGame() {
    console.log('Initializing Grid Battle Game...');
    
    // Initialize empty grid
    initializeGrid();
    
    // Render the grid
    renderGrid();
    
    // Add test players for visualization
    addTestPlayers();
    
    // Update UI
    updateGameStatus('Game initialized - Ready for players');
    updatePlayerInfo('Test Player');
    updateMovesDisplay();
    updateActionButtons();
}

function initializeGrid() {
    gameState.grid = [];
    for (let row = 0; row < GAME_CONFIG.GRID_HEIGHT; row++) {
        gameState.grid[row] = [];
        for (let col = 0; col < GAME_CONFIG.GRID_WIDTH; col++) {
            gameState.grid[row][col] = {
                type: 'empty',
                player: null,
                bullet: 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 = gameState.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;
}

function addTestPlayers() {
    // Add player 1 at position (2, 2)
    gameState.grid[2][2].player = 1;
    gameState.players[1] = { row: 2, col: 2, name: 'Player 1' };
    
    // Add player 2 at position (17, 17)
    gameState.grid[17][17].player = 2;
    gameState.players[2] = { row: 17, col: 17, name: 'Player 2' };
    
    // Re-render to show players
    renderGrid();
}

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 (gameState.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()
    };
    
    gameState.turnActions.push(action);
    gameState.movesRemaining--;
    
    updateGhostPreviews();
    updateMovesDisplay();
    updateActionButtons();
    
    console.log(`Added move action: ${direction}`);
    updateGameStatus(`Move added: ${direction.toUpperCase()}`);
}

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

function submitTurn() {
    if (gameState.turnActions.length === 0) {
        updateGameStatus('No actions to submit');
        return;
    }
    
    console.log('Submitting turn with actions:', gameState.turnActions);
    
    // TODO: Send actions to server via WebSocket
    
    // For now, just reset the turn locally
    gameState.turnActions = [];
    gameState.movesRemaining = GAME_CONFIG.MOVES_PER_TURN;
    gameState.shotAvailable = true;
    
    clearGhostPreviews();
    updateMovesDisplay();
    updateActionButtons();
    updateGameStatus('Turn submitted - waiting for opponent');
}

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 - gameState.movesRemaining;
    movesRemaining.textContent = `Moves: ${used}/${GAME_CONFIG.MOVES_PER_TURN}`;
    
    if (gameState.shotAvailable) {
        shotAvailable.textContent = 'Shot: Available';
        shotAvailable.classList.remove('used');
    } else {
        shotAvailable.textContent = 'Shot: Used';
        shotAvailable.classList.add('used');
    }
    
    actionsQueued.textContent = `Actions: ${gameState.turnActions.length}`;
}

function undoLastAction() {
    if (gameState.turnActions.length === 0) {
        updateGameStatus('No actions to undo');
        return;
    }
    
    // Remove the last action
    const lastAction = gameState.turnActions.pop();
    
    // Restore the appropriate resource
    if (lastAction.type === 'move') {
        gameState.movesRemaining++;
    } else if (lastAction.type === 'shoot') {
        gameState.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}`);
}

function updateActionButtons() {
    const hasActions = gameState.turnActions.length > 0;
    submitButton.disabled = !hasActions;
    undoButton.disabled = !hasActions;
}

// Ghost preview functions
function updateGhostPreviews() {
    clearGhostPreviews();
    
    if (!gameState.players[gameState.currentPlayer]) {
        return;
    }
    
    // Calculate the projected player position after all moves
    let currentPos = {
        row: gameState.players[gameState.currentPlayer].row,
        col: gameState.players[gameState.currentPlayer].col
    };
    
    // Simulate each action to show the ghost trail
    gameState.turnActions.forEach((action, index) => {
        if (action.type === 'move') {
            const offset = getDirectionOffset(action.direction);
            const newPos = {
                row: currentPos.row + offset.row,
                col: currentPos.col + offset.col
            };
            
            if (isValidPosition(newPos.row, newPos.col)) {
                currentPos = newPos;
                addGhostPreview(newPos.row, newPos.col, 'ghost-move');
            }
        } else if (action.type === 'shoot') {
            // Show bullet path from current position
            showBulletPath(currentPos.row, currentPos.col, action.direction);
        }
    });
}

function showBulletPath(startRow, startCol, direction) {
    const offset = getDirectionOffset(direction);
    let currentRow = startRow + offset.row;
    let currentCol = startCol + offset.col;
    
    // Show bullet path until it hits a wall or goes off-grid
    while (isValidPosition(currentRow, currentCol)) {
        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);
        gameState.ghostPreviews.push({ row, col, className });
    }
}

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

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

// Movement validation functions
function isValidMoveAction(direction) {
    if (!gameState.players[gameState.currentPlayer]) {
        return false;
    }
    
    // Calculate final position after all queued moves
    let finalPos = calculateFinalPlayerPosition();
    
    // Get the new position for this move
    const offset = getDirectionOffset(direction);
    const newPos = {
        row: finalPos.row + offset.row,
        col: finalPos.col + offset.col
    };
    
    // Check if move is within grid bounds
    if (!isValidPosition(newPos.row, newPos.col)) {
        updateGameStatus(`Cannot move ${direction.toUpperCase()} - out of bounds`);
        return false;
    }
    
    // Check if move would go through the player's own path
    if (isPositionInPlayerPath(newPos)) {
        updateGameStatus(`Cannot move ${direction.toUpperCase()} - cannot move through yourself`);
        return false;
    }
    
    return true;
}

function calculateFinalPlayerPosition() {
    let currentPos = {
        row: gameState.players[gameState.currentPlayer].row,
        col: gameState.players[gameState.currentPlayer].col
    };
    
    // Apply all queued move actions
    gameState.turnActions.forEach(action => {
        if (action.type === 'move') {
            const offset = getDirectionOffset(action.direction);
            const newPos = {
                row: currentPos.row + offset.row,
                col: currentPos.col + offset.col
            };
            
            if (isValidPosition(newPos.row, newPos.col)) {
                currentPos = newPos;
            }
        }
    });
    
    return currentPos;
}

function isPositionInPlayerPath(targetPos) {
    // Get all positions the player will occupy during their turn
    const playerPath = calculatePlayerPath();
    
    // Check if target position conflicts with any position in the path
    return playerPath.some(pos => 
        pos.row === targetPos.row && pos.col === targetPos.col
    );
}

function calculatePlayerPath() {
    const path = [];
    let currentPos = {
        row: gameState.players[gameState.currentPlayer].row,
        col: gameState.players[gameState.currentPlayer].col
    };
    
    // Add starting position
    path.push({ ...currentPos });
    
    // Apply all queued move actions and track each position
    gameState.turnActions.forEach(action => {
        if (action.type === 'move') {
            const offset = getDirectionOffset(action.direction);
            const newPos = {
                row: currentPos.row + offset.row,
                col: currentPos.col + offset.col
            };
            
            if (isValidPosition(newPos.row, newPos.col)) {
                currentPos = newPos;
                path.push({ ...currentPos });
            }
        }
    });
    
    return path;
}

function flashErrorButton(actionType, direction) {
    // Flash the button
    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);
    }
    
    // Flash ghost previews red for move actions
    if (actionType === 'move') {
        flashGhostPreviewsRed();
    }
}

function flashGhostPreviewsRed() {
    // Find all current ghost move cells
    const ghostCells = document.querySelectorAll('.ghost-move');
    
    ghostCells.forEach(cell => {
        // Apply red flash animation
        cell.style.animation = 'ghost-error-flash 0.6s ease-out';
        
        // Reset animation after completion
        setTimeout(() => {
            cell.style.animation = 'pulse 1.5s ease-in-out infinite';
        }, 600);
    });
}

// Utility functions
function getDirectionOffset(direction) {
    const offsets = {
        'north': { row: -1, col: 0 },
        'south': { row: 1, col: 0 },
        'east': { row: 0, col: 1 },
        'west': { row: 0, col: -1 }
    };
    return offsets[direction] || { row: 0, col: 0 };
}

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