import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:speech_to_text/speech_to_text.dart';

/// AI語音識別服務
/// 
/// 提供完整的語音識別功能，支援：
/// - 實時語音轉文字
/// - 多語言支援（中文、英文）
/// - 音頻權限管理
/// - 錯誤處理與重試機制
/// - 音量監測
class VoiceRecognitionService {
  static final VoiceRecognitionService _instance = VoiceRecognitionService._internal();
  factory VoiceRecognitionService() => _instance;
  VoiceRecognitionService._internal();

  final SpeechToText _speechToText = SpeechToText();
  
  // 語音識別狀態
  bool _isInitialized = false;
  bool _isListening = false;
  bool _isAvailable = false;
  
  // 識別結果回調
  final StreamController<VoiceRecognitionResult> _resultController = 
      StreamController<VoiceRecognitionResult>.broadcast();
  
  // 音量回調
  final StreamController<double> _soundLevelController = 
      StreamController<double>.broadcast();
  
  // 狀態回調
  final StreamController<VoiceRecognitionState> _stateController = 
      StreamController<VoiceRecognitionState>.broadcast();

  // 支援的語言
  static const Map<String, String> supportedLanguages = {
    'zh-TW': '繁體中文',
    'zh-CN': '簡體中文', 
    'en-US': 'English (US)',
    'en-GB': 'English (UK)',
  };

  // Getters
  bool get isInitialized => _isInitialized;
  bool get isListening => _isListening;
  bool get isAvailable => _isAvailable;
  
  // Streams
  Stream<VoiceRecognitionResult> get resultStream => _resultController.stream;
  Stream<double> get soundLevelStream => _soundLevelController.stream;
  Stream<VoiceRecognitionState> get stateStream => _stateController.stream;

  /// 初始化語音識別服務
  Future<bool> initialize() async {
    try {
      // 檢查並請求麥克風權限
      final permissionStatus = await _requestMicrophonePermission();
      if (!permissionStatus) {
        debugPrint('VoiceRecognitionService: 麥克風權限被拒絕');
        return false;
      }

      // 初始化語音識別引擎
      _isAvailable = await _speechToText.initialize(
        onError: _onError,
        onStatus: _onStatus,
      );

      if (_isAvailable) {
        _isInitialized = true;
        _stateController.add(VoiceRecognitionState.initialized);
        debugPrint('VoiceRecognitionService: 初始化成功');
        return true;
      } else {
        debugPrint('VoiceRecognitionService: 語音識別不可用');
        return false;
      }
    } catch (e) {
      debugPrint('VoiceRecognitionService: 初始化失敗 - $e');
      return false;
    }
  }

  /// 開始語音識別
  Future<bool> startListening({
    String languageId = 'zh-TW',
    Duration timeout = const Duration(seconds: 30),
    bool partialResults = true,
  }) async {
    if (!_isInitialized || !_isAvailable) {
      debugPrint('VoiceRecognitionService: 服務未初始化或不可用');
      return false;
    }

    if (_isListening) {
      debugPrint('VoiceRecognitionService: 已在監聽中');
      return true;
    }

    try {
      await _speechToText.listen(
        onResult: _onResult,
        listenFor: timeout,
        pauseFor: const Duration(seconds: 3),
        partialResults: partialResults,
        localeId: languageId,
        onSoundLevelChange: _onSoundLevelChange,
        listenMode: ListenMode.confirmation,
      );

      _isListening = true;
      _stateController.add(VoiceRecognitionState.listening);
      debugPrint('VoiceRecognitionService: 開始監聽');
      return true;
    } catch (e) {
      debugPrint('VoiceRecognitionService: 開始監聽失敗 - $e');
      return false;
    }
  }

  /// 停止語音識別
  Future<void> stopListening() async {
    if (!_isListening) return;

    try {
      await _speechToText.stop();
      _isListening = false;
      _stateController.add(VoiceRecognitionState.stopped);
      debugPrint('VoiceRecognitionService: 停止監聽');
    } catch (e) {
      debugPrint('VoiceRecognitionService: 停止監聽失敗 - $e');
    }
  }

  /// 取消語音識別
  Future<void> cancel() async {
    if (!_isListening) return;

    try {
      await _speechToText.cancel();
      _isListening = false;
      _stateController.add(VoiceRecognitionState.cancelled);
      debugPrint('VoiceRecognitionService: 取消監聽');
    } catch (e) {
      debugPrint('VoiceRecognitionService: 取消監聽失敗 - $e');
    }
  }

  /// 獲取支援的語言
  Future<List<LocaleName>> getAvailableLanguages() async {
    if (!_isInitialized) return [];
    return await _speechToText.locales();
  }

  /// 檢查特定語言是否支援
  Future<bool> isLanguageSupported(String languageId) async {
    final locales = await getAvailableLanguages();
    return locales.any((locale) => locale.localeId == languageId);
  }

  /// 請求麥克風權限
  Future<bool> _requestMicrophonePermission() async {
    final status = await Permission.microphone.status;
    
    if (status.isGranted) {
      return true;
    }

    if (status.isDenied) {
      final result = await Permission.microphone.request();
      return result.isGranted;
    }

    if (status.isPermanentlyDenied) {
      await openAppSettings();
      return false;
    }

    return false;
  }

  /// 處理識別結果
  void _onResult(SpeechRecognitionResult result) {
    final voiceResult = VoiceRecognitionResult(
      recognizedWords: result.recognizedWords,
      confidence: result.confidence,
      isFinal: result.finalResult,
      alternatives: result.alternates.map((alt) => 
        VoiceAlternative(
          text: alt.recognizedWords,
          confidence: alt.confidence,
        )
      ).toList(),
    );

    _resultController.add(voiceResult);
    
    if (result.finalResult) {
      debugPrint('VoiceRecognitionService: 最終結果 - ${result.recognizedWords}');
    } else {
      debugPrint('VoiceRecognitionService: 部分結果 - ${result.recognizedWords}');
    }
  }

  /// 處理錯誤
  void _onError(SpeechRecognitionError error) {
    debugPrint('VoiceRecognitionService: 錯誤 - ${error.errorMsg}');
    
    final errorType = _mapErrorType(error.errorMsg);
    _stateController.add(VoiceRecognitionState.error(errorType, error.errorMsg));
    
    _isListening = false;
  }

  /// 處理狀態變化
  void _onStatus(String status) {
    debugPrint('VoiceRecognitionService: 狀態變化 - $status');
    
    switch (status) {
      case 'listening':
        _isListening = true;
        _stateController.add(VoiceRecognitionState.listening);
        break;
      case 'notListening':
        _isListening = false;
        _stateController.add(VoiceRecognitionState.stopped);
        break;
      case 'done':
        _isListening = false;
        _stateController.add(VoiceRecognitionState.completed);
        break;
    }
  }

  /// 處理音量變化
  void _onSoundLevelChange(double level) {
    _soundLevelController.add(level);
  }

  /// 映射錯誤類型
  VoiceRecognitionErrorType _mapErrorType(String errorMsg) {
    if (errorMsg.contains('network')) {
      return VoiceRecognitionErrorType.network;
    } else if (errorMsg.contains('audio')) {
      return VoiceRecognitionErrorType.audio;
    } else if (errorMsg.contains('permission')) {
      return VoiceRecognitionErrorType.permission;
    } else if (errorMsg.contains('timeout')) {
      return VoiceRecognitionErrorType.timeout;
    } else {
      return VoiceRecognitionErrorType.unknown;
    }
  }

  /// 清理資源
  void dispose() {
    _resultController.close();
    _soundLevelController.close();
    _stateController.close();
  }
}

/// 語音識別結果
class VoiceRecognitionResult {
  final String recognizedWords;
  final double confidence;
  final bool isFinal;
  final List<VoiceAlternative> alternatives;

  VoiceRecognitionResult({
    required this.recognizedWords,
    required this.confidence,
    required this.isFinal,
    this.alternatives = const [],
  });

  @override
  String toString() {
    return 'VoiceRecognitionResult(words: $recognizedWords, confidence: $confidence, isFinal: $isFinal)';
  }
}

/// 語音識別替代結果
class VoiceAlternative {
  final String text;
  final double confidence;

  VoiceAlternative({
    required this.text,
    required this.confidence,
  });

  @override
  String toString() {
    return 'VoiceAlternative(text: $text, confidence: $confidence)';
  }
}

/// 語音識別狀態
class VoiceRecognitionState {
  final VoiceRecognitionStatus status;
  final VoiceRecognitionErrorType? errorType;
  final String? errorMessage;

  VoiceRecognitionState._(this.status, [this.errorType, this.errorMessage]);

  static VoiceRecognitionState get uninitialized => 
      VoiceRecognitionState._(VoiceRecognitionStatus.uninitialized);
  
  static VoiceRecognitionState get initialized => 
      VoiceRecognitionState._(VoiceRecognitionStatus.initialized);
  
  static VoiceRecognitionState get listening => 
      VoiceRecognitionState._(VoiceRecognitionStatus.listening);
  
  static VoiceRecognitionState get stopped => 
      VoiceRecognitionState._(VoiceRecognitionStatus.stopped);
  
  static VoiceRecognitionState get completed => 
      VoiceRecognitionState._(VoiceRecognitionStatus.completed);
  
  static VoiceRecognitionState get cancelled => 
      VoiceRecognitionState._(VoiceRecognitionStatus.cancelled);

  static VoiceRecognitionState error(VoiceRecognitionErrorType errorType, String message) =>
      VoiceRecognitionState._(VoiceRecognitionStatus.error, errorType, message);

  bool get hasError => status == VoiceRecognitionStatus.error;
}

/// 語音識別狀態枚舉
enum VoiceRecognitionStatus {
  uninitialized,
  initialized,
  listening,
  stopped,
  completed,
  cancelled,
  error,
}

/// 語音識別錯誤類型
enum VoiceRecognitionErrorType {
  network,
  audio,
  permission,
  timeout,
  unknown,
}