/**
 * Galaxy Strike Online - Client Item System
 * Dynamically loads and manages items from the GameServer
 */

class ItemSystem {
    constructor(gameEngine) {
        this.game = gameEngine;
        
        // Item storage
        this.itemCatalog = new Map(); // itemId -> item data
        this.shopItems = []; // Array of shop items (legacy)
        this.shopItemsByCategory = {}; // Categorized shop items (new structure)
        this.lastUpdated = null;
        
        // Loading state
        this.isLoading = false;
        this.loadPromise = null;
        
        // Event listeners
        this.eventListeners = new Map();
    }
    
    /**
     * Initialize the item system and load data from server
     */
    async initialize() {
        console.log('[ITEM SYSTEM] Initializing client item system');
        
        if (this.loadPromise) {
            return this.loadPromise;
        }
        
        this.loadPromise = this.loadFromServer();
        return this.loadPromise;
    }
    
    /**
     * Load all items from the GameServer
     */
    async loadFromServer() {
        if (this.isLoading) {
            console.log('[ITEM SYSTEM] Already loading items from server');
            return this.loadPromise;
        }
        
        this.isLoading = true;
        
        try {
            console.log('[ITEM SYSTEM] Loading items from GameServer - Multiplayer Mode');
            console.log('[ITEM SYSTEM] Socket connection status:', !!window.game?.socket);
            
            if (!window.game || !window.game.socket) {
                throw new Error('Not connected to server - multiplayer mode requires server connection');
            }
            
            // Load shop items from server
            const shopItems = await this.fetchShopItems();
            
            // Handle new shop structure (categorized) vs old structure (flat array)
            let totalItems = 0;
            if (Array.isArray(shopItems)) {
                // Old structure: flat array
                totalItems = shopItems.length;
                console.log('[ITEM SYSTEM] Received', totalItems, 'items from server (old structure)');
                this.processServerItems(shopItems);
                this.shopItemsByCategory = {}; // Clear categorized data
            } else if (shopItems && typeof shopItems === 'object') {
                // New structure: categorized object
                totalItems = Object.values(shopItems).reduce((sum, categoryItems) => sum + categoryItems.length, 0);
                console.log('[ITEM SYSTEM] Received', totalItems, 'items from server (new structure)');
                console.log('[ITEM SYSTEM] Categories:', Object.keys(shopItems));
                
                // Store categorized data
                this.shopItemsByCategory = shopItems;
                
                // Flatten all items for processing
                const allItems = Object.values(shopItems).flat();
                this.processServerItems(allItems);
            } else {
                console.warn('[ITEM SYSTEM] Invalid shop items structure received:', typeof shopItems);
                totalItems = 0;
                this.shopItemsByCategory = {};
            }
            
            this.lastUpdated = Date.now();
            console.log(`[ITEM SYSTEM] Successfully loaded ${this.itemCatalog.size} items from server`);
            console.log('[ITEM SYSTEM] Item categories loaded:', Object.keys(this.itemCatalog).length);
            
            // Emit loaded event
            this.emit('itemsLoaded', {
                itemCount: this.itemCatalog.size,
                shopItemCount: this.shopItems.length,
                timestamp: this.lastUpdated
            });
            
            return true;
            
        } catch (error) {
            console.error('[ITEM SYSTEM] Failed to load items from server:', error);
            console.error('[ITEM SYSTEM] Error details:', {
                message: error.message,
                stack: error.stack,
                socketConnected: !!window.game?.socket,
                socketId: window.game?.socket?.id
            });
            
            // No fallback - emit error event
            this.emit('itemsLoadError', error);
            return false;
            
        } finally {
            this.isLoading = false;
        }
    }
    
    /**
     * Fetch shop items from the GameServer
     */
    async fetchShopItems() {
        console.log('[ITEM SYSTEM] Starting fetchShopItems');
        
        if (!window.game || !window.game.socket) {
            console.error('[ITEM SYSTEM] No socket connection available');
            throw new Error('Not connected to server');
        }
        
        console.log('[ITEM SYSTEM] Socket ID:', window.game.socket.id);
        console.log('[ITEM SYSTEM] Socket connected:', window.game.socket.connected);
        
        return new Promise((resolve, reject) => {
            const timeout = setTimeout(() => {
                console.error('[ITEM SYSTEM] Server request timeout after 10 seconds');
                window.game.socket.off('shopItemsReceived', handleResponse);
                reject(new Error('Server request timeout'));
            }, 10000);
            
            // Test server connection first
            console.log('[ITEM SYSTEM] Testing server connection...');
            window.game.socket.emit('ping', { timestamp: Date.now() });
            
            // Listen for ping response
            const pingHandler = (data) => {
                console.log('[ITEM SYSTEM] Ping response received:', data);
                console.log('[ITEM SYSTEM] Server is responding! Ping roundtrip:', Date.now() - data.received, 'ms');
                window.game.socket.off('ping', pingHandler);
                window.game.socket.off('pong', pingHandler);
            };
            window.game.socket.on('ping', pingHandler);
            
            // Listen for pong response (backup)
            const pongHandler = (data) => {
                console.log('[ITEM SYSTEM] Pong response received:', data);
                console.log('[ITEM SYSTEM] Server is responding! Pong roundtrip:', Date.now() - data.timestamp, 'ms');
                window.game.socket.off('pong', pongHandler);
            };
            window.game.socket.on('pong', pongHandler);
            
            // Request shop items from server
            console.log('[ITEM SYSTEM] Emitting getShopItems request');
            console.log('[ITEM SYSTEM] Socket state:', {
                connected: window.game.socket.connected,
                id: window.game.socket.id
            });
            
            window.game.socket.emit('getShopItems', {});
            console.log('[ITEM SYSTEM] Request sent, waiting for response...');
            
            // Listen for response
            const handleResponse = (data) => {
                console.log('[ITEM SYSTEM] Received shopItemsReceived response:', data);
                clearTimeout(timeout);
                window.game.socket.off('shopItemsReceived', handleResponse);
                
                console.log('[ITEM SYSTEM] Response success:', data.success);
                console.log('[ITEM SYSTEM] Response shopItems keys:', data.shopItems ? Object.keys(data.shopItems) : 'none');
                
                if (data.success) {
                    console.log('[ITEM SYSTEM] Successfully received shop data');
                    console.log('[ITEM SYSTEM] Response timestamp:', data.timestamp);
                    
                    // Log item counts per category
                    if (data.shopItems) {
                        Object.entries(data.shopItems).forEach(([category, items]) => {
                            console.log(`[ITEM SYSTEM] ${category}: ${items.length} items`);
                        });
                    }
                    
                    resolve(data.shopItems || {});
                } else {
                    console.error('[ITEM SYSTEM] Server returned error:', data.error);
                    reject(new Error(data.error || 'Failed to load shop items'));
                }
            };
            
            console.log('[ITEM SYSTEM] Setting up shopItemsReceived listener');
            window.game.socket.on('shopItemsReceived', handleResponse);
            
            // Verify the listener was set up
            const listeners = window.game.socket.listeners('shopItemsReceived');
            console.log('[ITEM SYSTEM] shopItemsReceived listeners count:', listeners.length);
        });
    }
    
    /**
     * Fetch specific item details from server
     */
    async fetchItemDetails(itemId) {
        if (!window.game || !window.game.socket) {
            throw new Error('Not connected to server');
        }
        
        return new Promise((resolve, reject) => {
            const timeout = setTimeout(() => {
                reject(new Error('Server request timeout'));
            }, 5000);
            
            // Request item details from server
            window.game.socket.emit('getItemDetails', { itemId });
            
            // Listen for response
            const handleResponse = (data) => {
                clearTimeout(timeout);
                window.game.socket.off('itemDetailsReceived', handleResponse);
                
                if (data.success) {
                    // Cache the item
                    this.itemCatalog.set(itemId, data.item);
                    resolve(data.item);
                } else {
                    reject(new Error(data.error || 'Item not found'));
                }
            };
            
            window.game.socket.on('itemDetailsReceived', handleResponse);
        });
    }
    
    /**
     * Process items received from server
     */
    processServerItems(items) {
        // Safety check for items parameter
        if (!items || !Array.isArray(items)) {
            console.error('[ITEM SYSTEM] Invalid items parameter:', items);
            console.error('[ITEM SYSTEM] Expected array, got:', typeof items);
            return;
        }
        
        console.log('[ITEM SYSTEM] Processing', items.length, 'items from server');
        console.log('[ITEM SYSTEM] Sample items:', items.slice(0, 3));
        
        this.itemCatalog.clear();
        this.shopItems = [];
        
        for (const item of items) {
            // Store in catalog
            this.itemCatalog.set(item.id, item);
            
            // Add to shop items if available for shop
            if (item.categories && item.categories.includes('shop')) {
                this.shopItems.push(item);
            }
            
            // console.log('[ITEM SYSTEM] Added item:', {
            //     id: item.id,
            //     name: item.name,
            //     type: item.type,
            //     rarity: item.rarity,
            //     price: item.price,
            //     categories: item.categories
            // });
        }
        
        console.log('[ITEM SYSTEM] Processing complete - Catalog:', this.itemCatalog.size, 'Shop items:', this.shopItems.length);
        console.log('[ITEM SYSTEM] Shop items by type:', this.shopItems.reduce((acc, item) => {
            acc[item.type] = (acc[item.type] || 0) + 1;
            return acc;
        }, {}));
    }
    
    /**
     * Get item by ID
     */
    getItem(itemId) {
        // Return from cache if available
        if (this.itemCatalog.has(itemId)) {
            return this.itemCatalog.get(itemId);
        }
        
        // Try to fetch from server if not cached
        if (window.game && window.game.socket) {
            this.fetchItemDetails(itemId).catch(error => {
                console.warn(`[ITEM SYSTEM] Failed to fetch item ${itemId}:`, error);
            });
        }
        
        return null;
    }
    
    /**
     * Get all shop items
     */
    getShopItems() {
        return [...this.shopItems];
    }
    
    /**
     * Get shop items by category (new structure)
     */
    getShopItemsByCategory() {
        return this.shopItemsByCategory || {};
    }
    
    /**
     * Get items by category
     */
    getItemsByCategory(category) {
        return Array.from(this.itemCatalog.values()).filter(item => 
            item.type === category || (item.categories && item.categories.includes(category))
        );
    }
    
    /**
     * Get items by type
     */
    getItemsByType(type) {
        return Array.from(this.itemCatalog.values()).filter(item => item.type === type);
    }
    
    /**
     * Get items by rarity
     */
    getItemsByRarity(rarity) {
        return Array.from(this.itemCatalog.values()).filter(item => item.rarity === rarity);
    }
    
    /**
     * Check if player can use item based on requirements
     */
    canPlayerUseItem(item, playerLevel = null) {
        if (!item.requirements) return true;
        
        // Get player level if not provided
        if (playerLevel === null && window.game && window.game.systems && window.game.systems.player) {
            playerLevel = window.game.systems.player.level;
        }
        
        // Check level requirement
        if (item.requirements.level && playerLevel < item.requirements.level) {
            return false;
        }
        
        // Add other requirement checks here
        
        return true;
    }
    
    /**
     * Get filtered shop items for current player
     */
    getAvailableShopItems() {
        return this.shopItems.filter(item => this.canPlayerUseItem(item));
    }
    
    /**
     * Format item price for display
     */
    formatPrice(item) {
        if (!item.price) return 'Free';
        
        const currency = item.currency || 'credits';
        const price = this.game.formatNumber(item.price);
        
        return `${price} ${currency}`;
    }
    
    /**
     * Get item rarity color
     */
    getRarityColor(rarity) {
        const colors = {
            common: '#888888',
            uncommon: '#00ff00',
            rare: '#0088ff',
            legendary: '#ff8800',
            epic: '#ff00ff'
        };
        
        return colors[rarity] || '#ffffff';
    }
    
    /**
     * Refresh items from server
     */
    async refresh() {
        console.log('[ITEM SYSTEM] Refreshing items from server');
        return this.loadFromServer();
    }
    
    /**
     * Event system
     */
    on(event, callback) {
        if (!this.eventListeners.has(event)) {
            this.eventListeners.set(event, []);
        }
        this.eventListeners.get(event).push(callback);
    }
    
    off(event, callback) {
        if (this.eventListeners.has(event)) {
            const listeners = this.eventListeners.get(event);
            const index = listeners.indexOf(callback);
            if (index > -1) {
                listeners.splice(index, 1);
            }
        }
    }
    
    emit(event, data) {
        if (this.eventListeners.has(event)) {
            for (const callback of this.eventListeners.get(event)) {
                try {
                    callback(data);
                } catch (error) {
                    console.error(`[ITEM SYSTEM] Error in event listener for ${event}:`, error);
                }
            }
        }
    }
    
    /**
     * catalog getter — alias for shopItemsByCategory, used by Economy.updateShopUI
     */
    get catalog() {
        return this.shopItemsByCategory;
    }

    /**
     * Get system statistics
     */
    getStats() {
        const stats = {
            totalItems: this.itemCatalog.size,
            shopItems: this.shopItems.length,
            lastUpdated: this.lastUpdated,
            isLoading: this.isLoading,
            socketConnected: !!(window.game?.socket),
            socketId: window.game?.socket?.id
        };
        
        // Add category breakdown
        stats.categories = {};
        for (const item of this.itemCatalog.values()) {
            stats.categories[item.type] = (stats.categories[item.type] || 0) + 1;
        }
        
        return stats;
    }
}

// Export for use in other modules
if (typeof module !== 'undefined' && module.exports) {
    module.exports = ItemSystem;
} else {
    window.ItemSystem = ItemSystem;
}
