export default class MobileCommands {
    constructor(commandHandler, gameContext) {
        this.commandHandler = commandHandler;
        this.gameContext = gameContext;
        this.isVisible = false;
        this.currentCommand = null;
        this.isMobileMode = false;
        
        this.init();
    }

    init() {
        // Mode toggle elements
        this.modeToggleButton = document.getElementById('toggle-input-mode');
        this.textInputMode = document.getElementById('text-input-mode');
        this.mobileCommandMode = document.getElementById('mobile-command-mode');
        
        // Dialog elements
        this.commandDialog = document.getElementById('command-dialog');
        this.commandTitle = document.getElementById('command-title');
        this.commandArguments = document.getElementById('command-arguments');
        this.executeButton = document.getElementById('execute-command');
        this.cancelButton = document.getElementById('cancel-command');

        this.setupEventListeners();
        this.populateCommands();
    }

    setupEventListeners() {
        this.modeToggleButton.addEventListener('click', () => this.toggleInputMode());
        this.executeButton.addEventListener('click', () => this.executeCommand());
        this.cancelButton.addEventListener('click', () => this.closeDialog());
        
        // Setup tab click handlers
        this.setupTabHandlers();
    }

    setupTabHandlers() {
        const tabs = document.querySelectorAll('.command-tab');
        tabs.forEach(tab => {
            // Handle click events
            tab.addEventListener('click', (e) => {
                const category = e.target.dataset.category;
                this.switchTab(category);
            });

            // Handle keyboard navigation
            tab.addEventListener('keydown', (e) => {
                this.handleTabKeydown(e);
            });
        });
    }

    handleTabKeydown(e) {
        const tabs = Array.from(document.querySelectorAll('.command-tab'));
        const currentIndex = tabs.findIndex(tab => tab === e.target);
        let newIndex = currentIndex;

        switch (e.key) {
            case 'ArrowLeft':
            case 'ArrowUp':
                e.preventDefault();
                newIndex = currentIndex > 0 ? currentIndex - 1 : tabs.length - 1;
                break;
            case 'ArrowRight':
            case 'ArrowDown':
                e.preventDefault();
                newIndex = currentIndex < tabs.length - 1 ? currentIndex + 1 : 0;
                break;
            case 'Home':
                e.preventDefault();
                newIndex = 0;
                break;
            case 'End':
                e.preventDefault();
                newIndex = tabs.length - 1;
                break;
            default:
                return;
        }

        if (newIndex !== currentIndex) {
            const newTab = tabs[newIndex];
            const category = newTab.dataset.category;
            this.switchTab(category);
        }
    }

    switchTab(category) {
        // Update all tabs and panels
        document.querySelectorAll('.command-tab').forEach(tab => {
            const isActive = tab.dataset.category === category;
            
            // Update CSS classes
            tab.classList.toggle('active', isActive);
            
            // Update ARIA attributes
            tab.setAttribute('aria-selected', isActive.toString());
            tab.setAttribute('tabindex', isActive ? '0' : '-1');
        });
        
        document.querySelectorAll('.command-panel').forEach(panel => {
            const isActive = panel.dataset.category === category;
            
            // Update CSS classes
            panel.classList.toggle('active', isActive);
            
            // Update ARIA attributes
            panel.setAttribute('aria-hidden', (!isActive).toString());
        });
        
        // Focus the active tab for keyboard navigation
        const activeTab = document.querySelector(`[data-category="${category}"].command-tab`);
        if (activeTab) {
            activeTab.focus();
        }
    }

    populateCommands() {
        // Get all available commands and their metadata
        const commands = this.getAvailableCommands();
        const categories = this.groupCommandsByCategory(commands);
        
        // Clear existing commands
        document.querySelectorAll('.command-list').forEach(list => {
            list.innerHTML = '';
        });

        // Populate each category
        Object.entries(categories).forEach(([category, commandList]) => {
            const container = document.querySelector(`[data-category="${category}"].command-list`);
            if (container) {
                commandList.forEach(command => {
                    const button = this.createCommandButton(command);
                    container.appendChild(button);
                });
            }
        });
    }

    getAvailableCommands() {
        const commands = [];
        const seenFunctions = new Set();
        
        // Get commands from the command handler, avoiding duplicates
        if (this.commandHandler.commands) {
            for (const [name, func] of this.commandHandler.commands) {
                // Skip if we've already seen this function (it's an alias)
                if (seenFunctions.has(func)) {
                    continue;
                }
                
                let metadata = null;
                
                // Check for new Command objects with getMetadata() method
                if (func.getMetadata) {
                    metadata = func.getMetadata();
                }
                // Check for old-style metadata property
                else if (func.metadata) {
                    metadata = func.metadata;
                }
                
                if (metadata) {
                    commands.push({
                        name: name,
                        ...metadata
                    });
                    seenFunctions.add(func);
                }
            }
        }
        
        // Add direction commands based on current room exits
        const currentRoom = this.gameContext.getRoom(this.gameContext.player.currentRoom);
        if (currentRoom && currentRoom.exits) {
            const availableExits = Array.from(currentRoom.exits.keys());
            availableExits.forEach(direction => {
                commands.push({
                    name: direction,
                    category: 'Movement',
                    description: `Go ${direction}`,
                    arguments: []
                });
            });
        }
        
        return commands;
    }

    groupCommandsByCategory(commands) {
        const categories = {};
        
        commands.forEach(command => {
            const category = command.category || 'Other';
            if (!categories[category]) {
                categories[category] = [];
            }
            categories[category].push(command);
        });
        
        return categories;
    }

    createCommandButton(command) {
        const button = document.createElement('button');
        button.className = 'command-button';
        button.innerHTML = `
            <div class="command-name">${command.name}</div>
            <div class="command-description">${command.description}</div>
        `;
        
        // Add ARIA attributes
        button.setAttribute('aria-label', `${command.name}: ${command.description}`);
        button.setAttribute('type', 'button');
        
        // Add arguments info for screen readers if present
        if (command.arguments && command.arguments.length > 0) {
            const argCount = command.arguments.length;
            const requiredArgs = command.arguments.filter(arg => !arg.optional).length;
            let ariaDescription = `Requires ${requiredArgs} argument${requiredArgs !== 1 ? 's' : ''}`;
            if (argCount > requiredArgs) {
                const optionalArgs = argCount - requiredArgs;
                ariaDescription += ` with ${optionalArgs} optional argument${optionalArgs !== 1 ? 's' : ''}`;
            }
            button.setAttribute('aria-describedby', `${command.name}-args-info`);
            
            // Create hidden description for screen readers
            const ariaDescElement = document.createElement('span');
            ariaDescElement.id = `${command.name}-args-info`;
            ariaDescElement.className = 'sr-only';
            ariaDescElement.textContent = ariaDescription;
            button.appendChild(ariaDescElement);
        }
        
        button.addEventListener('click', () => {
            this.selectCommand(command);
        });
        
        return button;
    }

    selectCommand(command) {
        this.currentCommand = command;
        
        if (command.arguments && command.arguments.length > 0) {
            this.showArgumentDialog(command);
        } else {
            // Execute command immediately if no arguments needed
            this.executeCommand();
        }
    }

    showArgumentDialog(command) {
        this.commandTitle.textContent = `${command.name} - ${command.description}`;
        this.commandArguments.innerHTML = '';
        
        command.arguments.forEach((arg, index) => {
            const argElement = this.createArgumentInput(arg, index);
            this.commandArguments.appendChild(argElement);
        });
        
        this.commandDialog.showModal();
    }

    createArgumentInput(arg, index) {
        const group = document.createElement('div');
        group.className = 'argument-group';
        
        const label = document.createElement('label');
        label.textContent = `${arg.description}${arg.optional ? ' (optional)' : ''}`;
        label.htmlFor = `arg-${index}`;
        
        let input;
        
        switch (arg.type) {
            case 'item':
                input = this.createItemSelector(arg, index);
                break;
                
            case 'select':
                input = this.createSelectInput(arg, index);
                break;
                
            case 'text':
            default:
                input = document.createElement('input');
                input.type = 'text';
                input.id = `arg-${index}`;
                input.placeholder = arg.description;
                break;
        }
        
        group.appendChild(label);
        group.appendChild(input);
        
        return group;
    }

    createItemSelector(arg, index) {
        const container = document.createElement('fieldset');
        container.className = 'item-selector';
        
        // Create legend for accessibility
        const legend = document.createElement('legend');
        legend.textContent = `Select ${arg.description.toLowerCase()}`;
        legend.className = 'item-selector-legend';
        container.appendChild(legend);
        
        // Get available items from room and inventory
        const room = this.gameContext.getRoom(this.gameContext.player.currentRoom);
        const roomItems = room.getItems();
        const inventoryItems = this.gameContext.player.getInventory();
        
        const allItems = [...roomItems, ...inventoryItems];
        
        if (allItems.length === 0) {
            const noItemsMessage = document.createElement('div');
            noItemsMessage.className = 'no-items-message';
            noItemsMessage.textContent = 'No items available';
            noItemsMessage.setAttribute('aria-live', 'polite');
            container.appendChild(noItemsMessage);
            return container;
        }
        
        // Group items by location for better accessibility
        const itemsByLocation = {};
        
        // Add "look at room" option for optional arguments (put first)
        if (arg.optional) {
            const roomOption = {
                id: 'room',
                name: 'the room',
                description: 'Look around the current room'
            };
            itemsByLocation['General'] = [roomOption];
        }
        
        // Add room and inventory items
        itemsByLocation['Room'] = roomItems;
        itemsByLocation['Inventory'] = inventoryItems;
        
        Object.entries(itemsByLocation).forEach(([location, items]) => {
            if (items.length === 0) return;
            
            // Create a section for each location
            const locationSection = document.createElement('div');
            locationSection.className = 'item-location-section';
            
            const locationHeading = document.createElement('h4');
            locationHeading.textContent = location;
            locationHeading.className = 'item-location-heading';
            locationSection.appendChild(locationHeading);
            
            items.forEach((item, itemIndex) => {
                const radioId = `item-${index}-${location}-${itemIndex}`;
                const radioContainer = document.createElement('div');
                radioContainer.className = 'item-radio-container';
                
                const radio = document.createElement('input');
                radio.type = 'radio';
                radio.id = radioId;
                radio.name = `item-selector-${index}`;
                radio.value = item.name;
                radio.className = 'item-radio';
                radio.setAttribute('aria-describedby', `${radioId}-desc`);
                
                const label = document.createElement('label');
                label.htmlFor = radioId;
                label.className = 'item-radio-label';
                label.textContent = item.name;
                
                // Add description for screen readers
                const description = document.createElement('span');
                description.id = `${radioId}-desc`;
                description.className = 'item-radio-description';
                description.textContent = `${item.description || 'Item'} (in ${location.toLowerCase()})`;
                
                radio.addEventListener('change', (e) => {
                    if (e.target.checked) {
                        this.selectedItems.set(index, item.name);
                    }
                });
                
                radioContainer.appendChild(radio);
                radioContainer.appendChild(label);
                radioContainer.appendChild(description);
                locationSection.appendChild(radioContainer);
            });
            
            container.appendChild(locationSection);
        });
        
        return container;
    }

    createSelectInput(arg, index) {
        const select = document.createElement('select');
        select.id = `arg-${index}`;
        
        if (arg.options) {
            arg.options.forEach(option => {
                const optionElement = document.createElement('option');
                optionElement.value = option;
                optionElement.textContent = option;
                select.appendChild(optionElement);
            });
        }
        
        return select;
    }

    executeCommand() {
        if (!this.currentCommand) return;
        
        let commandString = this.currentCommand.name;
        
        // Collect arguments
        if (this.currentCommand.arguments && this.currentCommand.arguments.length > 0) {
            const args = [];
            
            this.currentCommand.arguments.forEach((arg, index) => {
                let value = '';
                
                if (arg.type === 'item') {
                    // Check for selected radio button
                    const radioButton = document.querySelector(`input[name="item-selector-${index}"]:checked`);
                    if (radioButton) {
                        // If "the room" is selected, don't add any argument (empty string)
                        value = radioButton.value === 'the room' ? '' : radioButton.value;
                    } else {
                        value = '';
                    }
                } else {
                    const input = document.getElementById(`arg-${index}`);
                    if (input) {
                        value = input.value;
                    }
                }
                
                if (value) {
                    args.push(value);
                }
            });
            
            if (args.length > 0) {
                commandString += ' ' + args.join(' ');
            }
        }
        
        // Execute the command
        console.log('Executing command:', commandString);
        this.commandHandler.doCommand(commandString);
        
        // Clean up
        this.closeDialog();
    }

    closeDialog() {
        this.commandDialog.close();
        this.currentCommand = null;
    }

    toggleInputMode() {
        this.isMobileMode = !this.isMobileMode;
        
        if (this.isMobileMode) {
            this.textInputMode.hidden = true;
            this.mobileCommandMode.hidden = false;
            this.modeToggleButton.textContent = '⌨️ Text Mode';
            this.populateCommands(); // Refresh commands when switching to mobile mode
        } else {
            this.textInputMode.hidden = false;
            this.mobileCommandMode.hidden = true;
            this.modeToggleButton.textContent = '📱 Mobile Mode';
        }
    }

    // Update available commands when game state changes
    refreshCommands() {
        if (this.isMobileMode) {
            this.populateCommands();
            // Re-setup tab handlers after commands are populated
            this.setupTabHandlers();
        }
    }
}