/**
 * Utility for building comprehensive game state JSON for bot integration
 */

import { parseCard, parseCards, getPlayableCards, isCardPlayable } from './cardParser';

/**
 * Build a complete game state object for external consumption (e.g., bot/AI)
 * @param {object} gameState - Current game state from React component
 * @param {string} currentUser - The current user's player name (Player 1 or Player 2)
 * @returns {object} Comprehensive game state in JSON format
 */
export const buildGameStateJSON = (gameState, currentUser) => {
    const {
        gameOver,
        winner,
        turn,
        player1Deck,
        player2Deck,
        currentColor,
        currentNumber,
        playedCardsPile,
        drawCardPile
    } = gameState;

    // Get last 5 played cards (or all if less than 5)
    const recentCards = playedCardsPile.slice(-5);
    const currentCard = playedCardsPile[playedCardsPile.length - 1];

    // Determine which player is the bot (Player 2)
    const botDeck = player2Deck;
    const opponentDeck = player1Deck;
    const isBotTurn = turn === 'Player 2';

    // Parse bot's cards with playability info
    // Parse bot's cards and mark playability based on game rules (independent of whose turn)
    const botParsedCards = botDeck.map(cardCode => {
        const card = parseCard(cardCode);
        const playable = isCardPlayable(cardCode, currentColor, currentNumber);
        return {
            ...card,
            isPlayable: playable
        };
    });

    // Build the comprehensive state object
    return {
        // Game meta info
        game: {
            isOver: gameOver,
            winner: winner || null,
            currentTurn: turn,
            turnNumber: playedCardsPile.length, // Approximate turn count
        },

        // Current card on the pile
        currentCard: {
            code: currentCard,
            ...parseCard(currentCard),
            currentColor: currentColor,
            currentNumber: currentNumber
        },

        // Recently played cards (last 5)
        recentlyPlayed: recentCards.map((cardCode, index) => ({
            code: cardCode,
            ...parseCard(cardCode),
            position: recentCards.length - index // 1 = most recent
        })),

        // Player 1 info (opponent to bot)
        player1: {
            name: 'Player 1',
            cardCount: player1Deck.length,
            isCurrentTurn: turn === 'Player 1',
            cards: [] // Hidden from bot
        },

        // Player 2 info (bot)
        player2: {
            name: 'Player 2',
            cardCount: player2Deck.length,
            isCurrentTurn: turn === 'Player 2',
            cards: botParsedCards, // Visible to bot
            playableCards: botParsedCards.filter(c => c.isPlayable)
        },

        // Deck info
        deck: {
            drawPileCount: drawCardPile.length,
            playedPileCount: playedCardsPile.length
        },

        // Bot decision context
        botContext: {
            canPlay: isBotTurn && botParsedCards.some(c => c.isPlayable),
            mustDraw: isBotTurn && !botParsedCards.some(c => c.isPlayable),
            hasUno: player2Deck.length === 2, // Should press UNO button next turn
            isWinning: player2Deck.length === 1,
            actions: isBotTurn ? getAvailableActions(botParsedCards, currentColor, currentNumber) : []
        }
    };
};

/**
 * Get available actions for the bot
 * @param {object[]} parsedCards - Bot's parsed cards
 * @param {string} currentColor - Current color
 * @param {number|string} currentNumber - Current number
 * @returns {object[]} Array of available action objects
 */
const getAvailableActions = (parsedCards, currentColor, currentNumber) => {
    const actions = [];

    // Check each card for playability
    parsedCards.forEach(card => {
        if (card.isPlayable) {
            actions.push({
                action: 'play_card',
                card: {
                    code: card.code,
                    type: card.type,
                    value: card.value,
                    color: card.color,
                    displayName: card.displayName
                },
                // For wild cards, need to choose a color
                requiresColorChoice: card.type === 'wild' || card.type === 'draw4_wild'
            });
        }
    });

    // If no playable cards, must draw
    if (actions.length === 0) {
        actions.push({
            action: 'draw_card',
            card: null
        });
    }

    return actions;
};

/**
 * Format game state for console logging
 * @param {object} gameStateJSON - The game state object
 * @returns {string} Formatted JSON string
 */
export const formatGameStateForLog = (gameStateJSON) => {
    return JSON.stringify(gameStateJSON, null, 2);
};

/**
 * Create a simplified game state for quick display
 * @param {object} gameStateJSON - The full game state object
 * @returns {object} Simplified state
 */
export const simplifyGameState = (gameStateJSON) => {
    return {
        turn: gameStateJSON.game.currentTurn,
        currentCard: `${gameStateJSON.currentCard.displayName} (${gameStateJSON.currentCard.code})`,
        player1Cards: gameStateJSON.player1.cardCount,
        player2Cards: gameStateJSON.player2.cardCount,
        botCanPlay: gameStateJSON.botContext.canPlay,
        playableCards: gameStateJSON.player2.playableCards.length
    };
};
