/**
 * Game Loop Module for AI Interactive Fiction
 * Manages the main game logic and connects various modules
 */
import { BaseModule } from './base-module.js';
import { moduleRegistry } from './module-registry.js';

class GameLoopModule extends BaseModule {
    constructor() {
        super('game-loop', 'Game Loop');
        this.uiController = null;
        this.socketClient = null;
        this.ttsPlayer = null;
        this.textBuffer = null;
        this.isRunning = false;
        this.gameState = {
            started: false,
            canLoad: false,
            currentRoom: null,
            inventory: [],
            commandHistory: []
        };
    }

    /**
     * Load module dependencies
     * @returns {Promise} - Resolves when dependencies are loaded
     */
    async loadDependencies() {
        // Basic dependency declaration - details handled in waitForDependencies
        return true;
    }

    /**
     * Wait for dependencies to be ready
     */
    async waitForDependencies() {
        try {
            // Wait for TTS module with a timeout
            const ttsReady = await moduleRegistry.waitForModule('tts', 15000);
            
            if (ttsReady) {
                this.ttsPlayer = moduleRegistry.getModule('tts');
                this.reportProgress(30, "TTS module ready");
            } else {
                console.warn("TTS module not ready, game will have limited functionality");
            }
            
            // Wait for UI Controller with a timeout
            const uiReady = await moduleRegistry.waitForModule('ui-controller', 15000);
            
            if (uiReady) {
                this.uiController = moduleRegistry.getModule('ui-controller');
                this.reportProgress(50, "UI Controller ready");
            } else {
                console.warn("UI Controller not ready, game will have limited functionality");
            }
            
            // Get text buffer reference
            this.textBuffer = moduleRegistry.getModule('text-buffer');
            if (this.textBuffer) {
                this.reportProgress(60, "Text buffer ready");
            }
            
            // Continue even with limited functionality
            return true;
        } catch (error) {
            console.error("Error waiting for dependencies:", error);
            return false;
        }
    }

    /**
     * Initialize the module
     * @returns {Promise<boolean>} - Resolves with success status
     */
    async initialize() {
        this.reportProgress(100, "Game loop initialized");
        return true;
    }
    
    /**
     * Start the game loop
     */
    start() {
        console.log("GameLoop: Starting game sequence...");
        
        try {
            // Update UI with initial game state
            if (this.uiController && this.ttsPlayer) {
                this.updateUIState();
            } else {
                console.warn("GameLoop: UI Controller or TTS Player not ready for status update.");
            }
            
            console.log("GameLoop: Setting up socket listeners and connecting...");
            
            // Set up socket event listeners and connect
            this.setupSocketEventListeners();
            
            // Set the game loop as running
            this.isRunning = true;
        } catch (error) {
            console.error("Error starting game loop:", error);
        }
    }
    
    /**
     * Set up socket event listeners and connect to server
     */
    setupSocketEventListeners() {
        // Get the socket client module
        this.socketClient = moduleRegistry.getModule('socket-client');
        
        if (!this.socketClient) {
            console.error("Socket client module not found");
            return;
        }
        
        // Connect UI controller to socket client for command handling
        if (this.uiController) {
            this.uiController.socketClient = this.socketClient;
        } else {
            console.warn("GameLoop: UI Controller not ready for Socket Client assignment.");
        }
        
        // Listen for socket connection event
        this.socketClient.on('connect', () => {
            console.log("GameLoop: Socket connected event received.");
            
            // Request a new game start when we (re)connect
            console.log("GameLoop: Requesting start game on (re)connect.");
            this.requestStartGame();
        });
        
        // Listen for game state updates
        this.socketClient.on('gameStateUpdate', (data) => {
            console.log("GameLoop: Game state update received", data);
            this.updateGameState(data);
        });
        
        // Listen for narrative responses
        this.socketClient.on('narrativeResponse', (data) => {
            console.log("GameLoop: Narrative response received", data);
            // Text processing is handled by socket-client -> text-buffer -> ui-controller pipeline
        });
        
        // Listen for game introduction
        this.socketClient.on('gameIntroduction', (data) => {
            console.log("GameLoop: Received gameIntroduction");
            this.gameState.started = true;
            this.updateUIState();
            // Text processing is handled by socket-client -> text-buffer -> ui-controller pipeline
        });
        
        // Connect to the socket server
        this.socketClient.connect().then(success => {
            if (success) {
                console.log("GameLoop: Socket connection established successfully.");
                console.log("GameLoop: Requesting to start a new game");
                this.requestStartGame();
            } else {
                console.error("GameLoop: Failed to connect to socket server");
            }
        });
    }
    
    /**
     * Update the game state
     * @param {Object} data - New game state data
     */
    updateGameState(data) {
        if (!data) return;
        
        // Update game state
        if (data.currentRoom) {
            this.gameState.currentRoom = data.currentRoom;
        }
        
        if (data.inventory) {
            this.gameState.inventory = data.inventory;
        }
        
        // Update UI with new game state
        this.updateUIState();
    }
    
    /**
     * Update UI with current game state
     */
    updateUIState() {
        if (!this.uiController) return;
        
        // Update UI components based on game state
        this.uiController.updateButtonStates(this.gameState);
    }
    
    /**
     * Request to start a new game
     */
    requestStartGame() {
        if (!this.socketClient) return;
        
        this.socketClient.requestStartGame();
        this.gameState.started = true;
    }
    
    /**
     * Request to save the current game
     */
    requestSaveGame() {
        if (!this.socketClient) return;
        
        this.socketClient.requestSaveGame();
    }
    
    /**
     * Request to load a saved game
     */
    requestLoadGame() {
        if (!this.socketClient) return;
        
        this.socketClient.requestLoadGame();
    }
    
    /**
     * Manually add text to the buffer
     * Useful for testing or adding local messages
     * @param {string} text - Text to add
     */
    addText(text) {
        if (!this.textBuffer) {
            console.warn("Text buffer not available");
            return;
        }
        
        this.textBuffer.addText(text);
    }
}

// Create the singleton instance
const GameLoop = new GameLoopModule();

// Register with the module registry
moduleRegistry.register(GameLoop);

// Export the module
export { GameLoop };

// Keep a reference in window for loader system
window.GameLoop = GameLoop;
