/**
 * Utility functions for parsing UNO card codes into readable JSON objects
 * Card codes format: '5R', 'D2G', 'skipB', 'W', 'D4W', '_Y' (reverse)
 */

/**
 * Parse a card code into a detailed card object
 * @param {string} cardCode - The card code (e.g., '5R', 'D2G', 'W')
 * @returns {object} Card object with type, value, color, and display name
 */
export const parseCard = (cardCode) => {
    if (!cardCode) return null;

    const card = {
        code: cardCode,
        type: 'unknown',
        value: null,
        color: null,
        colorName: null,
        displayName: ''
    };

    // Extract color (last character for most cards)
    const lastChar = cardCode.charAt(cardCode.length - 1).toUpperCase();
    const colorMap = {
        'R': 'red',
        'G': 'green',
        'B': 'blue',
        'Y': 'yellow'
    };

    // Wild cards (no color)
    if (cardCode === 'W') {
        card.type = 'wild';
        card.value = 300;
        card.displayName = 'Wild';
        return card;
    }

    if (cardCode === 'D4W') {
        card.type = 'draw4_wild';
        card.value = 600;
        card.displayName = 'Draw 4 Wild';
        return card;
    }

    // Cards with color
    card.color = lastChar;
    card.colorName = colorMap[lastChar] || 'unknown';

    // Number cards (0-9)
    const firstChar = cardCode.charAt(0);
    if (firstChar >= '0' && firstChar <= '9') {
        card.type = 'number';
        card.value = parseInt(firstChar, 10);
        card.displayName = `${firstChar} ${card.colorName}`;
        return card;
    }

    // Skip cards
    if (cardCode.startsWith('skip')) {
        card.type = 'skip';
        card.value = 404;
        card.displayName = `Skip ${card.colorName}`;
        return card;
    }

    // Draw 2 cards
    if (cardCode.startsWith('D2')) {
        card.type = 'draw2';
        card.value = 252;
        card.displayName = `Draw 2 ${card.colorName}`;
        return card;
    }

    // Reverse cards
    if (cardCode === '_' + lastChar) {
        card.type = 'reverse';
        card.value = 0;
        card.displayName = `Reverse ${card.colorName}`;
        return card;
    }

    return card;
};

/**
 * Check if a card can be played on the current card
 * @param {string} cardCode - The card to check
 * @param {string} currentColor - Current color in play
 * @param {string|number} currentNumber - Current number/value in play
 * @returns {boolean} Whether the card can be played
 */
export const isCardPlayable = (cardCode, currentColor, currentNumber) => {
    const card = parseCard(cardCode);
    
    // Wild cards can always be played
    if (card.type === 'wild' || card.type === 'draw4_wild') {
        return true;
    }
    // Normalize currentColor: accept 'R' or 'red' (case-insensitive)
    let normColor = null;
    if (typeof currentColor === 'string') {
        const c = currentColor.trim().toUpperCase();
        const nameToLetter = { RED: 'R', GREEN: 'G', BLUE: 'B', YELLOW: 'Y' };
        normColor = nameToLetter[c] || c.charAt(0);
    }

    // Check color match
    if (card.color && normColor && card.color === normColor) {
        return true;
    }
    // Check number/value match (coerce currentNumber to number)
    const normNumber = (currentNumber === null || currentNumber === undefined) ? null : Number(currentNumber);
    if (card.value !== null && normNumber !== null && card.value === normNumber) {
        return true;
    }

    // Special case: reverse cards
    if (card.type === 'reverse' && normNumber === 0) {
        return true;
    }

    return false;
};

/**
 * Parse multiple cards into detailed objects
 * @param {string[]} cardCodes - Array of card codes
 * @returns {object[]} Array of parsed card objects
 */
export const parseCards = (cardCodes) => {
    return cardCodes.map(parseCard);
};

/**
 * Get playable cards from a hand
 * @param {string[]} hand - Player's card codes
 * @param {string} currentColor - Current color in play
 * @param {string|number} currentNumber - Current number/value in play
 * @returns {object[]} Array of playable cards with their details
 */
export const getPlayableCards = (hand, currentColor, currentNumber) => {
    return hand
        .filter(cardCode => isCardPlayable(cardCode, currentColor, currentNumber))
        .map(cardCode => ({
            ...parseCard(cardCode),
            isPlayable: true
        }));
};
