import 'package:get/get.dart';
import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_to_text.dart';
import 'package:trans_lark/util/t_print.dart';
import 'package:trans_lark/widget/t_base_easy_loading.dart';

class SpeechToTextManager {
  static final SpeechToTextManager _instance = SpeechToTextManager._();

  SpeechToTextManager._();

  factory SpeechToTextManager() {
    return _instance;
  }

  final _speechToText = SpeechToText();

  var isListening = false.obs;
  var hasSpeech = false;

  Future<void> init() async {
    try {
      TBaseEasyLoading.loading();
      hasSpeech = await _speechToText.initialize(
        onStatus: _statusListener,
        onError: _errorListener,
      );
      TBaseEasyLoading.dismiss();
      _speechToText.statusListener ??= _statusListener;
      _speechToText.errorListener ??= _errorListener;
    } catch (e) {
      TPrint.d('Speech recognition failed: ${e.toString()}');
    }
  }

  Future<void> startListening(
      String localeId, SpeechResultListener onResult) async {
    TBaseEasyLoading.loading();
    try {
      await _speechToText.listen(
        onResult: onResult,
        localeId: localeId,
        listenFor: const Duration(minutes: 30),
        pauseFor: const Duration(minutes: 3),
        listenOptions: SpeechListenOptions(
          cancelOnError: true,
          autoPunctuation: true,
          listenMode: ListenMode.dictation,
        ),
      );
      TBaseEasyLoading.dismiss();
    } catch (e) {
      if (e.runtimeType == ListenFailedException) {
        TPrint.d(
            'speechToText.listen：${(e as ListenFailedException).message}');
      } else {
        TPrint.d('speechToText.listen：${e.toString()}');
      }
      TBaseEasyLoading.toast(
          'The current language does not support speech recognition');
    }
  }

  void _statusListener(String status) {
    TPrint.d('状态：$status');
    if (status == 'listening') {
      isListening.value = true;
    } else {
      isListening.value = false;
    }
  }

  void _errorListener(SpeechRecognitionError error) {
    TPrint.d('Received error status: $error, listening: ${_speechToText.isListening}');
    TBaseEasyLoading.toast('Speech recognition failed: ${error.errorMsg}');
  }

  Future<void> stopListening() async {
    if (isListening.value) {
      TBaseEasyLoading.loading();
      await _speechToText.stop();
      TBaseEasyLoading.dismiss();
    }
  }
}
