// ============================================
// VOICE CONTROL - AI AGENT
// ============================================

class VoiceControl {
  constructor() {
    this.recognition = null;
    this.isListening = false;
    this.isSupported = false;
    this.commands = this.initializeCommands();
    this.audioDevices = [];
    this.selectedDeviceId = null;
    this.mediaStream = null;
    this.audioContext = null;
    this.analyser = null;
    this.animationFrame = null;
    this.restartTimeout = null;
    this.lastSpeechTime = 0;
    this.aiMode = true; // AI Natural Language Processing mode
    this.aiNLP = null; // Will be initialized when AI mode is enabled
    this.init();
    this.loadAudioDevices();
  }

  init() {
    // Check browser support
    const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
    
    if (!SpeechRecognition) {
      console.warn('Speech Recognition not supported in this browser');
      return;
    }

    this.isSupported = true;
    this.recognition = new SpeechRecognition();
    this.recognition.continuous = false; // Single recognition per start
    this.recognition.interimResults = true; // Show interim results
    this.recognition.lang = 'vi-VN'; // Vietnamese
    this.recognition.maxAlternatives = 1;

    this.setupEventListeners();
  }

  setupEventListeners() {
    if (!this.recognition) return;

    this.recognition.onstart = () => {
      console.log('Speech recognition started');
      this.isListening = true;
      this.updateUI(true);
      this.startAudioVisualization();
      this.showTranscript('🎤 Đang nghe... Hãy nói NGAY!', 'listening');
      
      // Show urgent message after a short delay
      setTimeout(() => {
        if (this.isListening) {
          this.showFeedback('💡 Tip: Nói trong 5 giây, sau đó sẽ tự động sẵn sàng lại', 'info');
        }
      }, 1000);
    };

    this.recognition.onend = () => {
      console.log('Speech recognition ended, isListening:', this.isListening);
      // Auto-restart after a short delay if still supposed to be listening
      if (this.isListening) {
        console.log('Auto-restarting recognition in 500ms...');
        this.restartTimeout = setTimeout(() => {
          if (this.isListening) {
            console.log('Attempting to restart recognition...');
            try {
              this.recognition.start();
              this.showTranscript('🎤 Sẵn sàng... Nói tiếp!', 'listening');
            } catch (error) {
              console.error('Error restarting:', error);
              // Try again after a longer delay
              setTimeout(() => {
                if (this.isListening) {
                  try {
                    this.recognition.start();
                  } catch (e) {
                    console.error('Failed to restart:', e);
                    this.isListening = false;
                    this.updateUI(false);
                    this.stopAudioVisualization();
                  }
                }
              }, 1000);
            }
          } else {
            console.log('isListening is false, skip restart');
          }
        }, 500);
      } else {
        console.log('Not listening, cleaning up...');
        this.updateUI(false);
        this.stopAudioVisualization();
      }
    };

    this.recognition.onresult = (event) => {
      let interimTranscript = '';
      let finalTranscript = '';

      for (let i = event.resultIndex; i < event.results.length; i++) {
        const transcript = event.results[i][0].transcript;
        if (event.results[i].isFinal) {
          finalTranscript += transcript;
        } else {
          interimTranscript += transcript;
        }
      }

      // Show interim results in real-time
      if (interimTranscript) {
        console.log('Interim:', interimTranscript);
        this.showTranscript(`🎤 "${interimTranscript}"`, 'interim');
      }

      // Process final result
      if (finalTranscript) {
        console.log('Final:', finalTranscript);
        const command = finalTranscript.toLowerCase();
        this.showTranscript(`✓ "${finalTranscript}"`, 'final');
        setTimeout(() => {
          this.processCommand(command);
        }, 300);
      }
    };

    this.recognition.onerror = (event) => {
      console.error('Speech recognition error:', event.error);
      
      // Don't stop on no-speech error in continuous mode
      if (event.error === 'no-speech') {
        console.log('No speech detected, but continuing to listen...');
        this.showTranscript('🎤 Không nghe thấy... Thử lại!', 'listening');
        // Don't stop, let it auto-restart
        return;
      }
      
      if (event.error === 'aborted') {
        console.log('Recognition aborted, will restart...');
        return;
      }
      
      // Only stop on critical errors
      if (event.error === 'not-allowed' || event.error === 'service-not-allowed') {
        this.isListening = false;
        this.updateUI(false);
        this.stopAudioVisualization();
        this.showFeedback('❌ Vui lòng cho phép truy cập microphone', 'error');
      } else if (event.error === 'network') {
        this.isListening = false;
        this.updateUI(false);
        this.stopAudioVisualization();
        this.showFeedback('❌ Lỗi kết nối mạng', 'error');
      } else {
        console.log('Non-critical error, continuing...', event.error);
      }
    };

    this.recognition.onspeechstart = () => {
      console.log('Speech detected!');
      this.showTranscript('🎤 Đang nhận diện...', 'interim');
    };

    this.recognition.onspeechend = () => {
      console.log('Speech ended');
    };

    this.recognition.onaudiostart = () => {
      console.log('Audio capturing started');
    };

    this.recognition.onaudioend = () => {
      console.log('Audio capturing ended');
    };

    this.recognition.onsoundstart = () => {
      console.log('Sound detected');
    };

    this.recognition.onsoundend = () => {
      console.log('Sound ended');
    };
  }

  initializeCommands() {
    return {
      // Brightness
      brightness: {
        patterns: [
          /làm sáng(?:\s+lên)?(?:\s+(\d+))?/i,
          /tăng độ sáng(?:\s+(\d+))?/i,
          /sáng hơn(?:\s+(\d+))?/i,
          /làm tối(?:\s+xuống)?(?:\s+(\d+))?/i,
          /giảm độ sáng(?:\s+(\d+))?/i,
          /tối hơn(?:\s+(\d+))?/i
        ],
        execute: (match, transcript) => {
          const value = match[1] ? parseInt(match[1]) : 20;
          const isDarken = transcript.includes('tối') || transcript.includes('giảm');
          const finalValue = isDarken ? -value : value;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.brightness = Math.max(-100, Math.min(100, adjustments.brightness + finalValue));
            const slider = document.getElementById('brightnessSlider');
            if (slider) slider.value = adjustments.brightness;
            document.getElementById('brightnessValue').textContent = adjustments.brightness;
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã ${isDarken ? 'làm tối' : 'làm sáng'} ${Math.abs(finalValue)}%`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Contrast
      contrast: {
        patterns: [
          /tăng độ tương phản(?:\s+(\d+))?/i,
          /tương phản cao hơn(?:\s+(\d+))?/i,
          /giảm độ tương phản(?:\s+(\d+))?/i,
          /tương phản thấp hơn(?:\s+(\d+))?/i
        ],
        execute: (match, transcript) => {
          const value = match[1] ? parseInt(match[1]) : 20;
          const isDecrease = transcript.includes('giảm') || transcript.includes('thấp');
          const finalValue = isDecrease ? -value : value;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.contrast = Math.max(-100, Math.min(100, adjustments.contrast + finalValue));
            const slider = document.getElementById('contrastSlider');
            if (slider) slider.value = adjustments.contrast;
            document.getElementById('contrastValue').textContent = adjustments.contrast;
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã ${isDecrease ? 'giảm' : 'tăng'} độ tương phản ${Math.abs(finalValue)}%`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Saturation
      saturation: {
        patterns: [
          /tăng độ bão hòa(?:\s+(\d+))?/i,
          /màu sắc rực rỡ hơn(?:\s+(\d+))?/i,
          /giảm độ bão hòa(?:\s+(\d+))?/i,
          /màu sắc nhạt hơn(?:\s+(\d+))?/i
        ],
        execute: (match, transcript) => {
          const value = match[1] ? parseInt(match[1]) : 20;
          const isDecrease = transcript.includes('giảm') || transcript.includes('nhạt');
          const finalValue = isDecrease ? -value : value;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.saturation = Math.max(-100, Math.min(100, adjustments.saturation + finalValue));
            const slider = document.getElementById('saturationSlider');
            if (slider) slider.value = adjustments.saturation;
            document.getElementById('saturationValue').textContent = adjustments.saturation;
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã ${isDecrease ? 'giảm' : 'tăng'} độ bão hòa ${Math.abs(finalValue)}%`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Black & White
      blackWhite: {
        patterns: [
          /chuyển(?:\s+thành)?(?:\s+ảnh)?(?:\s+)?đen trắng/i,
          /làm(?:\s+ảnh)?(?:\s+)?đen trắng/i,
          /black and white/i,
          /grayscale/i,
          /bỏ màu/i
        ],
        execute: () => {
          const bwToggle = document.getElementById('bwToggle');
          if (bwToggle && typeof bwEnabled !== 'undefined') {
            window.bwEnabled = true;
            bwToggle.checked = true;
            if (typeof applyFilters === 'function') applyFilters();
            return '✓ Đã chuyển sang ảnh đen trắng';
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Restore color
      restoreColor: {
        patterns: [
          /khôi phục màu/i,
          /trả lại màu/i,
          /bật màu lại/i,
          /tắt đen trắng/i
        ],
        execute: () => {
          const bwToggle = document.getElementById('bwToggle');
          if (bwToggle && typeof bwEnabled !== 'undefined') {
            window.bwEnabled = false;
            bwToggle.checked = false;
            if (typeof applyFilters === 'function') applyFilters();
            return '✓ Đã khôi phục màu sắc';
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Blur
      blur: {
        patterns: [
          /làm mờ(?:\s+(\d+))?/i,
          /blur(?:\s+(\d+))?/i,
          /mờ hơn(?:\s+(\d+))?/i
        ],
        execute: (match) => {
          const value = match[1] ? parseInt(match[1]) : 5;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.blurAmount = Math.max(0, Math.min(20, value));
            const slider = document.getElementById('blurAmountSlider');
            if (slider) slider.value = adjustments.blurAmount;
            document.getElementById('blurAmountValue').textContent = adjustments.blurAmount;
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã làm mờ ${adjustments.blurAmount}px`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Sharpen
      sharpen: {
        patterns: [
          /làm nét(?:\s+(\d+))?/i,
          /sharpen(?:\s+(\d+))?/i,
          /nét hơn(?:\s+(\d+))?/i
        ],
        execute: (match) => {
          const value = match[1] ? parseInt(match[1]) : 50;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.sharpenAmount = Math.max(0, Math.min(200, value));
            const slider = document.getElementById('sharpenAmountSlider');
            if (slider) slider.value = adjustments.sharpenAmount;
            document.getElementById('sharpenAmountValue').textContent = adjustments.sharpenAmount;
            if (typeof applySharpenFilter === 'function') applySharpenFilter();
            return `✓ Đã làm nét ${adjustments.sharpenAmount}%`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Flip
      flip: {
        patterns: [
          /lật ngang/i,
          /lật(?:\s+)?horizontal/i,
          /flip horizontal/i,
          /lật dọc/i,
          /lật(?:\s+)?vertical/i,
          /flip vertical/i
        ],
        execute: (match, transcript) => {
          const isHorizontal = transcript.includes('ngang') || transcript.includes('horizontal');
          
          if (typeof adjustments !== 'undefined') {
            if (isHorizontal) {
              adjustments.flipHorizontal = !adjustments.flipHorizontal;
            } else {
              adjustments.flipVertical = !adjustments.flipVertical;
            }
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã lật ${isHorizontal ? 'ngang' : 'dọc'}`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Rotate
      rotate: {
        patterns: [
          /xoay(?:\s+)?(\d+)(?:\s+)?(?:độ)?/i,
          /rotate(?:\s+)?(\d+)/i,
          /quay(?:\s+)?(\d+)(?:\s+)?(?:độ)?/i
        ],
        execute: (match) => {
          const angle = match[1] ? parseInt(match[1]) : 90;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.rotateAngle = angle % 360;
            const slider = document.getElementById('rotateAngleSlider');
            if (slider) slider.value = adjustments.rotateAngle;
            document.getElementById('rotateAngleValue').textContent = adjustments.rotateAngle + '°';
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã xoay ${adjustments.rotateAngle}°`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Invert
      invert: {
        patterns: [
          /đảo ngược màu/i,
          /invert/i,
          /negative/i,
          /âm bản/i
        ],
        execute: () => {
          const invertToggle = document.getElementById('invertToggle');
          if (invertToggle && typeof adjustments !== 'undefined') {
            adjustments.invertEnabled = !adjustments.invertEnabled;
            invertToggle.checked = adjustments.invertEnabled;
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã ${adjustments.invertEnabled ? 'bật' : 'tắt'} đảo ngược màu`;
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Reset
      reset: {
        patterns: [
          /reset(?:\s+)?(?:tất cả)?/i,
          /đặt lại/i,
          /khôi phục ban đầu/i,
          /xóa(?:\s+)?(?:tất cả)?(?:\s+)?(?:hiệu ứng)?/i
        ],
        execute: () => {
          const resetBtn = document.getElementById('resetAdjustments');
          if (resetBtn) {
            resetBtn.click();
            return '✓ Đã reset tất cả hiệu ứng';
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Download
      download: {
        patterns: [
          /tải xuống/i,
          /download/i,
          /lưu ảnh/i,
          /save/i
        ],
        execute: () => {
          const downloadBtn = document.getElementById('downloadBtn');
          if (downloadBtn && !downloadBtn.disabled) {
            downloadBtn.click();
            return '✓ Đang tải xuống ảnh...';
          }
          return '❌ Chưa có ảnh để tải';
        }
      },

      // Sepia/Vintage
      sepia: {
        patterns: [
          /sepia/i,
          /vintage/i,
          /cổ điển/i,
          /phong cách cũ/i
        ],
        execute: () => {
          const filterSelect = document.getElementById('photoFilterType');
          if (filterSelect && typeof adjustments !== 'undefined') {
            adjustments.photoFilterType = 'sepia';
            filterSelect.value = 'sepia';
            adjustments.filterDensity = 50;
            const densitySlider = document.getElementById('filterDensitySlider');
            if (densitySlider) densitySlider.value = 50;
            document.getElementById('filterDensityValue').textContent = '50';
            if (typeof applyFilters === 'function') applyFilters();
            return '✓ Đã áp dụng hiệu ứng Sepia';
          }
          return '❌ Không thể thực hiện';
        }
      },

      // Warm/Cool
      temperature: {
        patterns: [
          /ấm hơn(?:\s+(\d+))?/i,
          /warm(?:er)?(?:\s+(\d+))?/i,
          /lạnh hơn(?:\s+(\d+))?/i,
          /cool(?:er)?(?:\s+(\d+))?/i
        ],
        execute: (match, transcript) => {
          const value = match[1] ? parseInt(match[1]) : 30;
          const isCool = transcript.includes('lạnh') || transcript.includes('cool');
          const finalValue = isCool ? -value : value;
          
          if (typeof adjustments !== 'undefined') {
            adjustments.temperature = Math.max(-100, Math.min(100, finalValue));
            const slider = document.getElementById('temperatureSlider');
            if (slider) slider.value = adjustments.temperature;
            document.getElementById('temperatureValue').textContent = adjustments.temperature;
            if (typeof applyFilters === 'function') applyFilters();
            return `✓ Đã điều chỉnh nhiệt độ màu ${isCool ? 'lạnh' : 'ấm'} hơn`;
          }
          return '❌ Không thể thực hiện';
        }
      }
    };
  }

  async processCommand(transcript) {
    // Check if this is a context-aware command (AI Vision)
    if (window.voiceAIVision && window.voiceAIVision.isContextCommand(transcript)) {
      console.log('🎯 Context-aware command detected, using AI Vision...');
      this.showFeedback('🤖 Đang phân tích ảnh với AI Vision...', 'info');
      
      const previewImage = document.getElementById('previewImage');
      if (!previewImage || !previewImage.src) {
        this.showFeedback('❌ Cần có ảnh để sử dụng AI Vision', 'error');
        return;
      }

      const visionResult = await window.voiceAIVision.processContextCommand(transcript, previewImage);
      
      if (visionResult.needsApiKey) {
        // Prompt for API key
        await this.promptForVisionApiKey();
        // Retry
        const retryResult = await window.voiceAIVision.processContextCommand(transcript, previewImage);
        this.showFeedback(retryResult.message, retryResult.success ? 'success' : 'error');
      } else {
        this.showFeedback(visionResult.message, visionResult.success ? 'success' : 'error');
      }
      
      return;
    }

    // AI Mode: Use Natural Language Processing
    if (this.aiMode && this.aiNLP) {
      console.log('🤖 AI Mode: Analyzing natural language...');
      const aiResult = await this.aiNLP.analyzeIntent(transcript);
      
      if (aiResult.understood) {
        console.log('✓ AI understood:', aiResult.command);
        const source = aiResult.source === 'gemini' ? '🤖 Gemini AI' : '📋 Rule-based';
        this.showFeedback(`${source}: ${aiResult.message}`, 'success');
        await this.executeAICommand(aiResult.command);
        
        // Save to history
        if (typeof saveToHistory === 'function') {
          saveToHistory('AI Voice Command', transcript);
        }
        return;
      } else {
        console.log('❓ AI did not understand');
        this.showFeedback(aiResult.message, 'error');
        if (aiResult.suggestions && aiResult.suggestions.length > 0) {
          setTimeout(() => {
            this.showFeedback(`💡 ${aiResult.suggestions[0]}`, 'info');
          }, 2000);
        }
        return;
      }
    }

    // Classic Mode: Pattern matching
    let commandFound = false;
    let result = '';

    for (const [commandName, command] of Object.entries(this.commands)) {
      for (const pattern of command.patterns) {
        const match = transcript.match(pattern);
        if (match) {
          commandFound = true;
          result = command.execute(match, transcript);
          console.log(`Command matched: ${commandName}`, result);
          this.showFeedback(result, result.includes('✓') ? 'success' : 'error');
          
          if (result.includes('✓') && typeof saveToHistory === 'function') {
            saveToHistory('Voice Command', transcript);
          }
          
          return;
        }
      }
    }

    if (!commandFound) {
      this.showFeedback(`❓ Không hiểu lệnh: "${transcript}"`, 'error');
      this.showAvailableCommands();
    }
  }

  // Execute AI-generated command
  executeAICommand(command) {
    console.log('Executing AI command:', command);

    switch (command.type) {
      case 'colorPreset':
        this.executeColorPreset(command);
        break;
      case 'combo':
        this.executeCombo(command);
        break;
      case 'adjustment':
        this.executeAdjustment(command);
        break;
      case 'toggle':
        this.executeToggle(command);
        break;
      case 'flip':
        this.executeFlip(command);
        break;
      case 'rotate':
        this.executeRotate(command);
        break;
      case 'filter':
        this.executeFilter(command);
        break;
      case 'reset':
        this.executeReset();
        break;
      case 'download':
        this.executeDownload();
        break;
      case 'zoomIn':
        this.executeZoomIn();
        break;
      case 'zoomOut':
        this.executeZoomOut();
        break;
      case 'zoomReset':
        this.executeZoomReset();
        break;
      case 'fitToScreen':
        this.executeFitToScreen();
        break;
    }
  }

  executeCombo(command) {
    console.log('🎯 Executing combo command:', command.target);
    
    if (!command.adjustments || !Array.isArray(command.adjustments)) {
      this.showFeedback('❌ Lệnh combo không hợp lệ', 'error');
      return;
    }

    // Apply all adjustments
    let appliedCount = 0;
    for (const adj of command.adjustments) {
      if (typeof adjustments !== 'undefined' && adj.target in adjustments) {
        // Apply relative adjustment
        adjustments[adj.target] = Math.max(-100, Math.min(100, adjustments[adj.target] + adj.value));
        
        // Update slider
        const slider = document.getElementById(`${adj.target}Slider`);
        if (slider) {
          slider.value = adjustments[adj.target];
        }
        
        // Update value display
        const valueDisplay = document.getElementById(`${adj.target}Value`);
        if (valueDisplay) {
          valueDisplay.textContent = adjustments[adj.target];
        }
        
        appliedCount++;
      }
    }

    // Apply filters
    if (typeof applyFilters === 'function') {
      applyFilters();
    }

    this.showFeedback(`✓ ${command.description} (${appliedCount} điều chỉnh)`, 'success');
  }

  async executeColorPreset(command) {
    if (!this.aiNLP || !this.aiNLP.colorPresets) {
      this.showFeedback('❌ Color presets không khả dụng', 'error');
      return;
    }

    const result = await this.aiNLP.colorPresets.applyPreset(command.presetName);
    
    if (result.success) {
      let message = result.message;
      if (result.generatedByAI) {
        message += ' (Tạo bởi AI 🤖)';
      }
      this.showFeedback(message, 'success');
      console.log('✓ Applied adjustments:', result.applied);
    } else {
      this.showFeedback(result.message, 'error');
    }
  }

  executeAdjustment(command) {
    if (typeof adjustments === 'undefined') return;

    const target = command.target;
    const value = command.value;

    if (command.relative) {
      // Relative adjustment
      adjustments[target] = Math.max(-100, Math.min(100, adjustments[target] + value));
    } else {
      // Absolute adjustment
      adjustments[target] = Math.max(-100, Math.min(100, value));
    }

    // Update UI
    const slider = document.getElementById(`${target}Slider`);
    if (slider) slider.value = adjustments[target];
    
    const valueEl = document.getElementById(`${target}Value`);
    if (valueEl) valueEl.textContent = adjustments[target];

    // Apply
    if (target === 'sharpen' && typeof applySharpenFilter === 'function') {
      applySharpenFilter();
    } else if (typeof applyFilters === 'function') {
      applyFilters();
    }
  }

  executeToggle(command) {
    const target = command.target;

    if (target === 'blackWhite') {
      const toggle = document.getElementById('bwToggle');
      if (toggle) {
        console.log('🎨 Toggling Black & White to:', command.value);
        
        // Update checkbox first
        toggle.checked = command.value;
        
        // Trigger click event to ensure all event listeners fire
        // This is more reliable than manually setting variables
        if (toggle.checked !== command.value) {
          toggle.click();
        } else {
          // If already in correct state, just trigger change event
          toggle.dispatchEvent(new Event('change', { bubbles: true }));
        }
        
        console.log('✓ Black & White toggled, checkbox state:', toggle.checked);
      } else {
        console.error('❌ bwToggle element not found');
      }
    } else if (target === 'invert') {
      const toggle = document.getElementById('invertToggle');
      if (toggle && typeof adjustments !== 'undefined') {
        adjustments.invertEnabled = !adjustments.invertEnabled;
        toggle.checked = adjustments.invertEnabled;
        if (typeof applyFilters === 'function') applyFilters();
      }
    }
  }

  executeFlip(command) {
    if (typeof adjustments === 'undefined') return;

    if (command.target === 'horizontal') {
      adjustments.flipHorizontal = !adjustments.flipHorizontal;
    } else {
      adjustments.flipVertical = !adjustments.flipVertical;
    }

    if (typeof applyFilters === 'function') applyFilters();
  }

  executeRotate(command) {
    if (typeof adjustments === 'undefined') return;

    adjustments.rotateAngle = command.value % 360;
    
    const slider = document.getElementById('rotateAngleSlider');
    if (slider) slider.value = adjustments.rotateAngle;
    
    const valueEl = document.getElementById('rotateAngleValue');
    if (valueEl) valueEl.textContent = adjustments.rotateAngle + '°';

    if (typeof applyFilters === 'function') applyFilters();
  }

  executeFilter(command) {
    if (command.target === 'sepia') {
      const filterSelect = document.getElementById('photoFilterType');
      if (filterSelect && typeof adjustments !== 'undefined') {
        adjustments.photoFilterType = 'sepia';
        filterSelect.value = 'sepia';
        adjustments.filterDensity = 50;
        
        const densitySlider = document.getElementById('filterDensitySlider');
        if (densitySlider) densitySlider.value = 50;
        
        const valueEl = document.getElementById('filterDensityValue');
        if (valueEl) valueEl.textContent = '50';
        
        if (typeof applyFilters === 'function') applyFilters();
      }
    }
  }

  executeReset() {
    const resetBtn = document.getElementById('resetAdjustments');
    if (resetBtn) resetBtn.click();
  }

  executeZoomIn() {
    const zoomInBtn = document.getElementById('zoomInBtn');
    if (zoomInBtn) {
      zoomInBtn.click();
      this.showFeedback('✓ Đã phóng to', 'success');
    } else {
      this.showFeedback('❌ Không thể phóng to', 'error');
    }
  }

  executeZoomOut() {
    const zoomOutBtn = document.getElementById('zoomOutBtn');
    if (zoomOutBtn) {
      zoomOutBtn.click();
      this.showFeedback('✓ Đã thu nhỏ', 'success');
    } else {
      this.showFeedback('❌ Không thể thu nhỏ', 'error');
    }
  }

  executeZoomReset() {
    const zoomResetBtn = document.getElementById('zoomResetBtn');
    if (zoomResetBtn) {
      zoomResetBtn.click();
      this.showFeedback('✓ Đã reset zoom về 100%', 'success');
    } else {
      this.showFeedback('❌ Không thể reset zoom', 'error');
    }
  }

  executeFitToScreen() {
    // Fit to screen is same as zoom reset
    this.executeZoomReset();
  }

  executeDownload() {
    const downloadBtn = document.getElementById('downloadBtn');
    if (downloadBtn && !downloadBtn.disabled) downloadBtn.click();
  }

  showAvailableCommands() {
    console.log('📋 Các lệnh có sẵn:');
    console.log('- Làm sáng/tối [số]');
    console.log('- Tăng/giảm độ tương phản [số]');
    console.log('- Chuyển đen trắng');
    console.log('- Làm mờ [số]');
    console.log('- Làm nét [số]');
    console.log('- Lật ngang/dọc');
    console.log('- Xoay [số] độ');
    console.log('- Reset tất cả');
    console.log('- Tải xuống');
    console.log('🎯 AI Vision Commands:');
    console.log('- Cắt bớt phần trời ở trên');
    console.log('- Làm cho khuôn mặt sáng hơn');
    console.log('- Xóa người ở góc phải');
    console.log('- Làm nền mờ');
  }

  /**
   * Prompt for Vision API key
   */
  async promptForVisionApiKey() {
    if (typeof Swal === 'undefined') {
      const apiKey = prompt('Nhập Gemini API Key để sử dụng AI Vision:');
      if (apiKey) {
        window.voiceAIVision.saveApiKey(apiKey);
        await window.voiceAIVision.init(apiKey);
      }
      return;
    }

    const result = await Swal.fire({
      title: '🔑 Gemini API Key',
      html: `
        <p style="margin-bottom: 15px;">Để sử dụng AI Vision (context-aware commands), bạn cần Gemini API Key.</p>
        <p style="margin-bottom: 15px; font-size: 13px; color: #888;">
          Lấy API key miễn phí tại: 
          <a href="https://makersuite.google.com/app/apikey" target="_blank" style="color: #4a9eff;">
            Google AI Studio
          </a>
        </p>
        <input type="text" id="visionApiKey" class="swal2-input" placeholder="Nhập API key...">
        <p style="margin-top: 10px; font-size: 12px; color: #666;">
          💡 API key sẽ được lưu trong trình duyệt của bạn
        </p>
      `,
      showCancelButton: true,
      confirmButtonText: 'Lưu',
      cancelButtonText: 'Hủy',
      preConfirm: () => {
        const apiKey = document.getElementById('visionApiKey').value;
        if (!apiKey) {
          Swal.showValidationMessage('Vui lòng nhập API key');
          return false;
        }
        return apiKey;
      }
    });

    if (result.isConfirmed && result.value) {
      window.voiceAIVision.saveApiKey(result.value);
      await window.voiceAIVision.init(result.value);
      this.showFeedback('✓ Đã lưu API key', 'success');
    }
  }

  async start() {
    if (!this.isSupported) {
      this.showFeedback('❌ Trình duyệt không hỗ trợ nhận diện giọng nói', 'error');
      return;
    }

    if (!this.isListening) {
      try {
        // Start audio stream for visualization
        await this.startAudioStream();
        this.isListening = true; // Set flag before starting
        this.recognition.start();

      } catch (error) {
        console.error('Error starting recognition:', error);
        this.isListening = false;
        this.showFeedback('❌ Không thể bắt đầu nhận diện giọng nói', 'error');
      }
    }
  }

  stop() {
    console.log('🛑 Stopping voice control...');
    this.isListening = false; // Set flag first to prevent auto-restart
    
    // Clear restart timeout
    if (this.restartTimeout) {
      clearTimeout(this.restartTimeout);
      this.restartTimeout = null;
    }
    
    if (this.recognition) {
      try {
        this.recognition.stop();
      } catch (error) {
        console.error('Error stopping recognition:', error);
      }
    }
    this.stopAudioStream();
    this.updateUI(false);
    
    // Hide transcript
    const transcriptEl = document.getElementById('voiceTranscript');
    if (transcriptEl) {
      transcriptEl.style.display = 'none';
    }
    
    console.log('✓ Voice control stopped, isListening:', this.isListening);
    
    // Resume wake word if it's active (only if not already handled by single command mode)
    if (typeof voiceWakeWord !== 'undefined' && voiceWakeWord && voiceWakeWord.isWakeWordActive) {
      console.log('📞 Calling resumeWakeWord from stop() in 1000ms...');
      setTimeout(() => {
        voiceWakeWord.resumeWakeWord();
      }, 1000);
    }
  }

  // Start audio stream for visualization
  async startAudioStream() {
    try {
      const constraints = {
        audio: this.selectedDeviceId ? { deviceId: { exact: this.selectedDeviceId } } : true
      };
      
      this.mediaStream = await navigator.mediaDevices.getUserMedia(constraints);
      this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      this.analyser = this.audioContext.createAnalyser();
      const microphone = this.audioContext.createMediaStreamSource(this.mediaStream);
      microphone.connect(this.analyser);
      
      this.analyser.fftSize = 256;
    } catch (error) {
      console.error('Error starting audio stream:', error);
    }
  }

  // Stop audio stream
  stopAudioStream() {
    if (this.mediaStream) {
      this.mediaStream.getTracks().forEach(track => track.stop());
      this.mediaStream = null;
    }
    if (this.audioContext) {
      this.audioContext.close();
      this.audioContext = null;
    }
    this.analyser = null;
  }

  // Start audio visualization
  startAudioVisualization() {
    if (!this.analyser) return;

    const visualize = () => {
      if (!this.isListening || !this.analyser) return;

      const bufferLength = this.analyser.frequencyBinCount;
      const dataArray = new Uint8Array(bufferLength);
      this.analyser.getByteFrequencyData(dataArray);

      // Calculate average volume
      const volume = dataArray.reduce((a, b) => a + b) / bufferLength;
      
      // Update wave animation based on volume
      this.updateWaveAnimation(volume);

      this.animationFrame = requestAnimationFrame(visualize);
    };

    visualize();
  }

  // Stop audio visualization
  stopAudioVisualization() {
    if (this.animationFrame) {
      cancelAnimationFrame(this.animationFrame);
      this.animationFrame = null;
    }
    // Reset wave animation
    this.updateWaveAnimation(0);
  }

  // Update wave animation based on volume
  updateWaveAnimation(volume) {
    const waveSpans = document.querySelectorAll('.voice-wave span');
    if (!waveSpans.length) return;

    // Only animate if volume is above threshold
    const threshold = 5;
    const isActive = volume > threshold;

    waveSpans.forEach((span, index) => {
      if (isActive) {
        // Calculate height based on volume (10% to 100%)
        const baseHeight = 10 + (volume / 128) * 90;
        // Add variation for each bar
        const variation = Math.sin((Date.now() / 200) + index) * 20;
        const height = Math.max(10, Math.min(100, baseHeight + variation));
        span.style.height = height + '%';
        span.style.opacity = '1';
      } else {
        // Minimal height when no sound
        span.style.height = '30%';
        span.style.opacity = '0.3';
      }
    });
  }

  // Show transcript in real-time
  showTranscript(text, type = 'interim') {
    const transcriptEl = document.getElementById('voiceTranscript');
    if (!transcriptEl) return;

    transcriptEl.textContent = text;
    transcriptEl.className = `voice-transcript ${type}`;
    transcriptEl.style.display = 'block';

    // Auto-hide after delay for final results
    if (type === 'final') {
      setTimeout(() => {
        transcriptEl.style.display = 'none';
      }, 2000);
    }
  }

  updateUI(isListening) {
    const voiceBtn = document.getElementById('voiceControlBtn');
    const voiceIndicator = document.getElementById('voiceIndicator');
    
    if (voiceBtn) {
      if (isListening) {
        voiceBtn.classList.add('listening');
        voiceBtn.title = 'Đang nghe... (Click để dừng)';
      } else {
        voiceBtn.classList.remove('listening');
        voiceBtn.title = 'Voice Control (Click để bắt đầu)';
      }
    }

    if (voiceIndicator) {
      voiceIndicator.style.display = isListening ? 'flex' : 'none';
    }
  }

  showFeedback(message, type = 'info') {
    if (typeof showMessage === 'function') {
      showMessage(message, type);
    } else {
      console.log(message);
    }

    // Also show in voice feedback area
    const feedbackEl = document.getElementById('voiceFeedback');
    if (feedbackEl) {
      feedbackEl.textContent = message;
      feedbackEl.className = `voice-feedback ${type}`;
      feedbackEl.style.display = 'block';
      
      setTimeout(() => {
        feedbackEl.style.display = 'none';
      }, 3000);
    }
  }

  // Load available audio input devices
  async loadAudioDevices() {
    try {
      // Request permission first
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      
      // Get all devices
      const devices = await navigator.mediaDevices.enumerateDevices();
      this.audioDevices = devices.filter(device => device.kind === 'audioinput');
      
      // Stop the stream
      stream.getTracks().forEach(track => track.stop());
      
      // Load saved device from localStorage
      const savedDeviceId = localStorage.getItem('voiceControlDeviceId');
      if (savedDeviceId && this.audioDevices.find(d => d.deviceId === savedDeviceId)) {
        this.selectedDeviceId = savedDeviceId;
      } else if (this.audioDevices.length > 0) {
        this.selectedDeviceId = this.audioDevices[0].deviceId;
      }
      
      // Update UI
      this.updateDeviceList();
      
      console.log('Audio devices loaded:', this.audioDevices.length);
    } catch (error) {
      console.error('Error loading audio devices:', error);
      this.showFeedback('❌ Không thể truy cập microphone', 'error');
    }
  }

  // Update device list in settings panel
  updateDeviceList() {
    const deviceSelect = document.getElementById('voiceDeviceSelect');
    if (!deviceSelect) return;

    deviceSelect.innerHTML = '';
    
    this.audioDevices.forEach(device => {
      const option = document.createElement('option');
      option.value = device.deviceId;
      option.textContent = device.label || `Microphone ${this.audioDevices.indexOf(device) + 1}`;
      if (device.deviceId === this.selectedDeviceId) {
        option.selected = true;
      }
      deviceSelect.appendChild(option);
    });
  }

  // Change audio input device
  changeDevice(deviceId) {
    this.selectedDeviceId = deviceId;
    localStorage.setItem('voiceControlDeviceId', deviceId);
    
    // If currently listening, restart with new device
    if (this.isListening) {
      this.stop();
      setTimeout(() => this.start(), 100);
    }
    
    const device = this.audioDevices.find(d => d.deviceId === deviceId);
    const deviceName = device ? device.label : 'Unknown';
    this.showFeedback(`✓ Đã chuyển sang: ${deviceName}`, 'success');
  }

  // Test microphone
  async testMicrophone() {
    try {
      const constraints = {
        audio: this.selectedDeviceId ? { deviceId: { exact: this.selectedDeviceId } } : true
      };
      
      const stream = await navigator.mediaDevices.getUserMedia(constraints);
      
      // Create audio context to analyze volume
      const audioContext = new (window.AudioContext || window.webkitAudioContext)();
      const analyser = audioContext.createAnalyser();
      const microphone = audioContext.createMediaStreamSource(stream);
      microphone.connect(analyser);
      
      analyser.fftSize = 256;
      const bufferLength = analyser.frequencyBinCount;
      const dataArray = new Uint8Array(bufferLength);
      
      // Show test indicator
      const testIndicator = document.getElementById('micTestIndicator');
      const testContainer = document.querySelector('.mic-test-container');
      if (testContainer) {
        testContainer.style.display = 'block';
      }
      if (testIndicator) {
        testIndicator.style.width = '0%';
      }
      
      // Monitor volume for 3 seconds
      let maxVolume = 0;
      const checkVolume = () => {
        analyser.getByteFrequencyData(dataArray);
        const volume = dataArray.reduce((a, b) => a + b) / bufferLength;
        maxVolume = Math.max(maxVolume, volume);
        
        // Update visual indicator
        if (testIndicator) {
          const level = Math.min(100, (volume / 128) * 100);
          testIndicator.style.width = level + '%';
        }
      };
      
      const interval = setInterval(checkVolume, 50);
      
      setTimeout(() => {
        clearInterval(interval);
        stream.getTracks().forEach(track => track.stop());
        audioContext.close();
        
        if (testContainer) {
          setTimeout(() => {
            testContainer.style.display = 'none';
          }, 2000);
        }
        
        if (maxVolume > 10) {
          this.showFeedback('✓ Microphone hoạt động tốt!', 'success');
        } else {
          this.showFeedback('⚠️ Không phát hiện âm thanh. Hãy thử nói gì đó.', 'error');
        }
      }, 3000);
      
      this.showFeedback('🎤 Đang test microphone... Hãy nói gì đó!', 'info');
      
    } catch (error) {
      console.error('Error testing microphone:', error);
      this.showFeedback('❌ Không thể test microphone', 'error');
    }
  }

  // Refresh device list
  async refreshDevices() {
    this.showFeedback('🔄 Đang làm mới danh sách...', 'info');
    await this.loadAudioDevices();
    this.showFeedback('✓ Đã cập nhật danh sách thiết bị', 'success');
  }
}

// Initialize Voice Control
let voiceControl = null;
let voiceWakeWord = null;

document.addEventListener('DOMContentLoaded', () => {
  voiceControl = new VoiceControl();
  
  // Initialize AI NLP
  if (typeof VoiceAINLP !== 'undefined') {
    voiceControl.aiNLP = new VoiceAINLP();
    console.log('🤖 AI Natural Language Processing initialized');
  }
  
  // Initialize Wake Word
  if (typeof VoiceWakeWord !== 'undefined') {
    voiceWakeWord = new VoiceWakeWord(voiceControl);
    console.log('👋 Wake Word "Mimi ơi" initialized');
  }
  
  // Setup voice control button
  const voiceBtn = document.getElementById('voiceControlBtn');
  const voiceHelpPanel = document.getElementById('voiceHelpPanel');
  const voiceHelpCloseBtn = document.getElementById('voiceHelpCloseBtn');
  
  if (voiceBtn) {
    voiceBtn.addEventListener('click', () => {
      if (voiceControl.isListening) {
        voiceControl.stop();
      } else {
        voiceControl.start();
        // Show help panel on first use
        if (voiceHelpPanel && !localStorage.getItem('voiceHelpShown')) {
          voiceHelpPanel.style.display = 'block';
          localStorage.setItem('voiceHelpShown', 'true');
          setTimeout(() => {
            voiceHelpPanel.style.display = 'none';
          }, 10000); // Auto hide after 10 seconds
        }
      }
    });

    // Right click to show help
    voiceBtn.addEventListener('contextmenu', (e) => {
      e.preventDefault();
      if (voiceHelpPanel) {
        voiceHelpPanel.style.display = voiceHelpPanel.style.display === 'none' ? 'block' : 'none';
      }
    });
  }

  // Close help panel
  if (voiceHelpCloseBtn) {
    voiceHelpCloseBtn.addEventListener('click', () => {
      if (voiceHelpPanel) {
        voiceHelpPanel.style.display = 'none';
      }
    });
  }

  // Setup voice settings button
  const voiceSettingsBtn = document.getElementById('voiceSettingsBtn');
  const voiceSettingsPanel = document.getElementById('voiceSettingsPanel');
  const voiceSettingsCloseBtn = document.getElementById('voiceSettingsCloseBtn');
  
  if (voiceSettingsBtn) {
    voiceSettingsBtn.addEventListener('click', () => {
      if (voiceSettingsPanel) {
        voiceSettingsPanel.style.display = voiceSettingsPanel.style.display === 'none' ? 'block' : 'none';
        // Hide help panel if open
        if (voiceHelpPanel) {
          voiceHelpPanel.style.display = 'none';
        }
      }
    });
  }

  // Close settings panel
  if (voiceSettingsCloseBtn) {
    voiceSettingsCloseBtn.addEventListener('click', () => {
      if (voiceSettingsPanel) {
        voiceSettingsPanel.style.display = 'none';
      }
    });
  }

  // Device select change
  const voiceDeviceSelect = document.getElementById('voiceDeviceSelect');
  if (voiceDeviceSelect) {
    voiceDeviceSelect.addEventListener('change', (e) => {
      if (voiceControl) {
        voiceControl.changeDevice(e.target.value);
        // Save selected device
        localStorage.setItem('voiceControlDevice', e.target.value);
      }
    });
    
    // Load saved device
    const savedDevice = localStorage.getItem('voiceControlDevice');
    if (savedDevice && voiceControl) {
      // Wait for devices to load
      setTimeout(() => {
        const option = Array.from(voiceDeviceSelect.options).find(opt => opt.value === savedDevice);
        if (option) {
          voiceDeviceSelect.value = savedDevice;
          voiceControl.changeDevice(savedDevice);
        }
      }, 500);
    }
  }

  // Language select change
  const voiceLanguageSelect = document.getElementById('voiceLanguageSelect');
  if (voiceLanguageSelect) {
    voiceLanguageSelect.addEventListener('change', (e) => {
      if (voiceControl && voiceControl.recognition) {
        voiceControl.recognition.lang = e.target.value;
        localStorage.setItem('voiceControlLanguage', e.target.value);
        voiceControl.showFeedback(`✓ Đã chuyển sang ${e.target.options[e.target.selectedIndex].text}`, 'success');
      }
    });

    // Load saved language
    const savedLang = localStorage.getItem('voiceControlLanguage');
    if (savedLang) {
      voiceLanguageSelect.value = savedLang;
      if (voiceControl && voiceControl.recognition) {
        voiceControl.recognition.lang = savedLang;
      }
    }
  }

  // Voice mode select
  const voiceModeSelect = document.getElementById('voiceModeSelect');
  const voiceModeInfo = document.getElementById('voiceModeInfo');
  if (voiceModeSelect) {
    voiceModeSelect.addEventListener('change', (e) => {
      if (voiceControl) {
        voiceControl.aiMode = e.target.value === 'ai';
        localStorage.setItem('voiceControlMode', e.target.value);
        
        const mode = e.target.value === 'ai' ? 'AI Mode' : 'Classic Mode';
        voiceControl.showFeedback(`✓ Đã chuyển sang ${mode}`, 'success');
        
        // Update info text
        if (voiceModeInfo) {
          if (e.target.value === 'ai') {
            voiceModeInfo.innerHTML = '🤖 AI Mode: Nói tự nhiên, AI sẽ hiểu ý bạn<br>Ví dụ: "Làm cho ảnh sáng hơn một chút"';
          } else {
            voiceModeInfo.innerHTML = '📋 Classic Mode: Nói lệnh chính xác<br>Ví dụ: "Làm sáng 30"';
          }
        }
      }
    });

    // Load saved mode
    const savedMode = localStorage.getItem('voiceControlMode') || 'ai';
    voiceModeSelect.value = savedMode;
    if (voiceControl) {
      voiceControl.aiMode = savedMode === 'ai';
    }
  }

  // Test microphone button
  const testMicrophoneBtn = document.getElementById('testMicrophoneBtn');
  if (testMicrophoneBtn) {
    testMicrophoneBtn.addEventListener('click', () => {
      if (voiceControl) {
        voiceControl.testMicrophone();
      }
    });
  }

  // Refresh devices button
  const refreshDevicesBtn = document.getElementById('refreshDevicesBtn');
  if (refreshDevicesBtn) {
    refreshDevicesBtn.addEventListener('click', () => {
      if (voiceControl) {
        voiceControl.refreshDevices();
      }
    });
  }

  // Wake Word Toggle
  const wakeWordToggle = document.getElementById('wakeWordToggle');
  if (wakeWordToggle) {
    wakeWordToggle.addEventListener('change', (e) => {
      if (voiceWakeWord) {
        if (e.target.checked) {
          voiceWakeWord.start();
        } else {
          voiceWakeWord.stop();
        }
      }
    });
  }

  // Single Command Mode Toggle
  const singleCommandToggle = document.getElementById('singleCommandToggle');
  if (singleCommandToggle) {
    singleCommandToggle.addEventListener('change', (e) => {
      if (voiceWakeWord) {
        voiceWakeWord.toggleSingleCommandMode(e.target.checked);
      }
    });
  }

  // Keyboard shortcut: Ctrl/Cmd + Shift + V
  document.addEventListener('keydown', (e) => {
    if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'V') {
      e.preventDefault();
      if (voiceControl) {
        if (voiceControl.isListening) {
          voiceControl.stop();
        } else {
          voiceControl.start();
        }
      }
    }

    // Show help with Ctrl/Cmd + Shift + H
    if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'H') {
      e.preventDefault();
      if (voiceHelpPanel) {
        voiceHelpPanel.style.display = voiceHelpPanel.style.display === 'none' ? 'block' : 'none';
      }
    }

    // Show settings with Ctrl/Cmd + Shift + S
    if ((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'S') {
      e.preventDefault();
      if (voiceSettingsPanel) {
        voiceSettingsPanel.style.display = voiceSettingsPanel.style.display === 'none' ? 'block' : 'none';
      }
    }
  });
});

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