import { ROOMS, CORRIDORS, L_SHAPES, T_JUNCTIONS } from './TileDefinitions.js';

/**
 * DungeonDeck - Manages the deck of dungeon tiles
 * 
 * New approach: Deck contains abstract tile types, not specific tiles
 * When a type is drawn, we select a fitting variant from available options
 */

export class DungeonDeck {
    constructor() {
        this.deck = [];
        this.discardPile = [];
        this.shuffleDeck();
    }

    shuffleDeck() {
        // Create a deck with abstract tile types
        this.deck = [
            // 15 rooms 4x4 (abstract)
            { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' },
            { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' },
            { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' },
            { type: 'room_4x4' }, { type: 'room_4x4' }, { type: 'room_4x4' },

            // 8 rooms 4x6 (abstract)
            { type: 'room_4x6' }, { type: 'room_4x6' }, { type: 'room_4x6' }, { type: 'room_4x6' },
            { type: 'room_4x6' }, { type: 'room_4x6' }, { type: 'room_4x6' }, { type: 'room_4x6' },

            // 10 corridors (abstract)
            { type: 'corridor' }, { type: 'corridor' }, { type: 'corridor' }, { type: 'corridor' },
            { type: 'corridor' }, { type: 'corridor' }, { type: 'corridor' }, { type: 'corridor' },
            { type: 'corridor' }, { type: 'corridor' },

            // 8 L-shapes (abstract)
            { type: 'L' }, { type: 'L' }, { type: 'L' }, { type: 'L' },
            { type: 'L' }, { type: 'L' }, { type: 'L' }, { type: 'L' },

            // 6 T-junctions (abstract)
            { type: 'T' }, { type: 'T' }, { type: 'T' }, { type: 'T' },
            { type: 'T' }, { type: 'T' }
        ];

        // Fisher-Yates shuffle
        for (let i = this.deck.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [this.deck[i], this.deck[j]] = [this.deck[j], this.deck[i]];
        }

        // DEBUG: Fixed deck sequence for faster testing
        // Fixed deck removed.
        this.deck = this.deck.sort(() => Math.random() - 0.5);

        console.log("%c[DungeonDeck] SHUFFLED! Top 5 cards:", "color: orange; font-weight: bold;",
            this.deck.slice(-5).map(c => c.type).join(', '));
    }

    drawCard() {
        if (this.deck.length === 0) {
            console.warn("Deck empty! Reshuffling discards...");
            if (this.discardPile.length === 0) {
                console.error("No cards left!");
                return null;
            }
            this.deck = [...this.discardPile];
            this.discardPile = [];
            this.shuffleDeck();
        }

        const card = this.deck.pop();
        console.log(`%c[DungeonDeck] Drew: ${card.type}`, "color: cyan");
        this.discardPile.push(card);
        return card;
    }

    /**
     * Draw a compatible abstract tile type
     * @param {string} originTileType - Type of the origin tile ('room', 'corridor', 'L', 'T')
     * @param {number} maxAttempts - Maximum number of cards to try
     * @returns {object|null} - Abstract tile card or null if none found
     */
    drawCompatibleCard(originTileType, maxAttempts = 50) {
        const validTypes = this.getCompatibleTypes(originTileType);
        // console.log(`[DungeonDeck] Searching for ${validTypes.join('|')} (Origin: ${originTileType})`);

        // Check cards currently in deck
        let checkedCount = 0;
        const initialDeckSize = this.deck.length;

        // Loop until we find a match or give up
        // We use a pragmatic limit to prevent infinite loops (e.g., if even with discards we have 0 valid cards)
        const safetyLimit = this.deck.length + this.discardPile.length + 20;

        for (let i = 0; i < safetyLimit; i++) {
            // If we have checked all cards relationships in the current deck, AND we have cards in discard...
            // Reshuffle discards in to give us a chance.
            if (checkedCount >= this.deck.length && this.discardPile.length > 0) {
                console.log(`[DungeonDeck] Cycled current deck (${this.deck.length} cards) without match. Reshuffling ${this.discardPile.length} discards.`);
                this.deck = [...this.deck, ...this.discardPile];
                this.discardPile = [];
                this.shuffleDeck(); // Shuffle everything together
                checkedCount = 0; // Reset counter since we have a new deck state
            }

            if (this.deck.length === 0) {
                if (this.discardPile.length > 0) {
                    // Current deck empty, pull from discards
                    this.deck = [...this.discardPile];
                    this.discardPile = [];
                    this.shuffleDeck();
                    checkedCount = 0;
                } else {
                    console.error("No cards left anywhere!");
                    return null;
                }
            }

            const card = this.deck.pop();
            checkedCount++;

            // Check if this abstract type is compatible
            if (validTypes.includes(card.type)) {
                // Found one!
                console.log(`[DungeonDeck] MATCH! Accepted ${card.type}`);
                this.discardPile.push(card);
                return card;
            }

            // Incompatible: Put back at bottom (unshift) to try next
            this.deck.unshift(card);
        }

        console.warn(`Could not find compatible tile for ${originTileType} after ${safetyLimit} attempts. (Deck: ${this.deck.length}, Discard: ${this.discardPile.length})`);
        return null; // Return null (game will handle it, maybe stop exploring)
    }

    /**
     * Get compatible tile types for a given origin type
     * @param {string} originType - Type of the origin tile
     * @returns {string[]} - Array of compatible abstract tile types
     */
    getCompatibleTypes(originType) {
        const connectionRules = {
            'room': ['room_4x4', 'room_4x6', 'corridor'],
            'corridor': ['room_4x4', 'room_4x6', 'corridor', 'L', 'T'],
            'L': ['corridor'],
            'T': ['corridor']
        };

        return connectionRules[originType] || [];
    }
}

export const dungeonDeck = new DungeonDeck();
