import 'dart:ffi'; // 引入 FFI 库
import 'package:ffi/ffi.dart'; // 导入 ffi 扩展方法
import '../tmg_type.dart';
import 'tmg_load_dynamic.dart';

typedef ApplyPTTAuthbufferNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> userSig);
typedef ApplyPTTAuthbufferDart =
    int Function(Pointer<Void>, Pointer<Int8> userSig);

typedef SetMaxMessageLengthNative = Int32 Function(Pointer<Void>, Int32 msTime);
typedef SetMaxMessageLengthDart = int Function(Pointer<Void>, int msTime);

typedef StartRecordingNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> filePath);
typedef StartRecordingDart =
    int Function(Pointer<Void>, Pointer<Int8> filePath);

typedef StopRecordingNative = Int32 Function(Pointer<Void>);
typedef StopRecordingDart = int Function(Pointer<Void>);

typedef CancelRecordingNative = Int32 Function(Pointer<Void>);
typedef CancelRecordingDart = int Function(Pointer<Void>);

typedef UploadRecordedFileNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> filePath);
typedef UploadRecordedFileDart =
    int Function(Pointer<Void>, Pointer<Int8> filePath);

typedef DownloadRecordedFileNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> fileId, Pointer<Int8> filePath);
typedef DownloadRecordedFileDart =
    int Function(Pointer<Void>, Pointer<Int8> fileId, Pointer<Int8> filePath);

typedef PlayRecordedFileNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> filePath, Int32 voiceType);
typedef PlayRecordedFileDart =
    int Function(Pointer<Void>, Pointer<Int8> filePath, int voiceType);

typedef StopPlayFileNative = Int32 Function(Pointer<Void>);
typedef StopPlayFileDart = int Function(Pointer<Void>);

typedef SpeechToTextNative =
    Int32 Function(
      Pointer<Void>,
      Pointer<Int8> fileID,
      Pointer<Int8> speechLanguage,
      Pointer<Int8> translateLanguage,
    );
typedef SpeechToTextDart =
    int Function(
      Pointer<Void>,
      Pointer<Int8> fileID,
      Pointer<Int8> speechLanguage,
      Pointer<Int8> translateLanguage,
    );

typedef TranslateTextNative =
    Int32 Function(
      Pointer<Void>,
      Pointer<Int8> text,
      Pointer<Int8> sourceLanguage,
      Pointer<Int8> translateLanguage,
    );
typedef TranslateTextDart =
    int Function(
      Pointer<Void>,
      Pointer<Int8> text,
      Pointer<Int8> sourceLanguage,
      Pointer<Int8> translateLanguage,
    );

typedef GetFileSizeNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> filePath);
typedef GetFileSizeDart = int Function(Pointer<Void>, Pointer<Int8> filePath);

typedef GetVoiceFileDurationNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> filePath);
typedef GetVoiceFileDurationDart =
    int Function(Pointer<Void>, Pointer<Int8> filePath);

typedef StartRecordingWithStreamingRecognitionNative =
    Int32 Function(
      Pointer<Void>,
      Pointer<Int8> filePath,
      Pointer<Int8> speechLanguage,
      Pointer<Int8> translateLanguage,
    );
typedef StartRecordingWithStreamingRecognitionDart =
    int Function(
      Pointer<Void>,
      Pointer<Int8> filePath,
      Pointer<Int8> speechLanguage,
      Pointer<Int8> translateLanguage,
    );

typedef SetPTTSourceLanguageNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> sourceLanguage);
typedef SetPTTSourceLanguageDart =
    int Function(Pointer<Void>, Pointer<Int8> sourceLanguage);

typedef TextToSpeechNative =
    Int32 Function(
      Pointer<Void>,
      Int32 serialNumber,
      Pointer<Int8> text,
      Pointer<Int8> voiceName,
      Pointer<Int8> languageCode,
      Float speakingRate,
    );
typedef TextToSpeechDart =
    int Function(
      Pointer<Void>,
      int serialNumber,
      Pointer<Int8> text,
      Pointer<Int8> voiceName,
      Pointer<Int8> languageCode,
      double speakingRate,
    );

class TMGPTTBindings {
  late final Pointer<Void> _gmeInstance;
  TMGLoadDynamic _tmgDynamicInstance = TMGLoadDynamic.GetInstance();
  DynamicLibrary? _gmeSdkLib = null;

  TMGPTTBindings() {
    _gmeSdkLib = _tmgDynamicInstance.GetGmeSdkLib();
    _gmeInstance = _tmgDynamicInstance.GetGmeSdkInstance();
  }

  late final ApplyPTTAuthbufferDart ApplyPTTAuthbufferPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<ApplyPTTAuthbufferNative>>(
            'GMEUnity_ApplyPTTAuthbuffer',
          )
          .asFunction<ApplyPTTAuthbufferDart>();

  int ApplyPTTAuthbuffer(String userSig) {
    return ApplyPTTAuthbufferPtr(
      _gmeInstance,
      userSig.toNativeUtf8().cast<Int8>(),
    );
  }

  late final SetMaxMessageLengthDart SetMaxMessageLengthPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetMaxMessageLengthNative>>(
            'GMEUnity_SetMaxMessageLength',
          )
          .asFunction<SetMaxMessageLengthDart>();

  int SetMaxMessageLength(int msTime) {
    return SetMaxMessageLengthPtr(_gmeInstance, msTime);
  }

  late final StartRecordingDart StartRecordingPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StartRecordingNative>>(
            'GMEUnity_StartRecording',
          )
          .asFunction<StartRecordingDart>();

  int StartRecording(String filePath) {
    return StartRecordingPtr(
      _gmeInstance,
      filePath.toNativeUtf8().cast<Int8>(),
    );
  }

  late final StopRecordingDart StopRecordingPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StopRecordingNative>>('GMEUnity_StopRecording')
          .asFunction<StopRecordingDart>();

  int StopRecording() {
    return StopRecordingPtr(_gmeInstance);
  }

  late final CancelRecordingDart CancelRecordingPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<CancelRecordingNative>>(
            'GMEUnity_CancelRecording',
          )
          .asFunction<CancelRecordingDart>();

  int CancelRecording() {
    return CancelRecordingPtr(_gmeInstance);
  }

  late final UploadRecordedFileDart UploadRecordedFilePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<UploadRecordedFileNative>>(
            'GMEUnity_UploadRecordedFile',
          )
          .asFunction<UploadRecordedFileDart>();

  int UploadRecordedFile(String filePath) {
    return UploadRecordedFilePtr(
      _gmeInstance,
      filePath.toNativeUtf8().cast<Int8>(),
    );
  }

  late final DownloadRecordedFileDart DownloadRecordedFilePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<DownloadRecordedFileNative>>(
            'GMEUnity_DownloadRecordedFile',
          )
          .asFunction<DownloadRecordedFileDart>();

  int DownloadRecordedFile(String fileId, String filePath) {
    return DownloadRecordedFilePtr(
      _gmeInstance,
      fileId.toNativeUtf8().cast<Int8>(),
      filePath.toNativeUtf8().cast<Int8>(),
    );
  }

  late final PlayRecordedFileDart PlayRecordedFilePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<PlayRecordedFileNative>>(
            'GMEUnity_StartPlayFile',
          )
          .asFunction<PlayRecordedFileDart>();

  int PlayRecordedFile(String filePath, ITMG_VOICE_TYPE voiceType) {
    return PlayRecordedFilePtr(
      _gmeInstance,
      filePath.toNativeUtf8().cast<Int8>(),
      voiceType.value,
    );
  }

  late final StopPlayFileDart StopPlayFilePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StopPlayFileNative>>('GMEUnity_StopPlayFile')
          .asFunction<StopPlayFileDart>();

  int StopPlayFile() {
    return StopPlayFilePtr(_gmeInstance);
  }

  late final SpeechToTextDart SpeechToTextPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SpeechToTextNative>>('GMEUnity_SpeechToText')
          .asFunction<SpeechToTextDart>();

  int SpeechToText(
    String fileID,
    String speechLanguage,
    String translateLanguage,
  ) {
    return SpeechToTextPtr(
      _gmeInstance,
      fileID.toNativeUtf8().cast<Int8>(),
      speechLanguage.toNativeUtf8().cast<Int8>(),
      translateLanguage.toNativeUtf8().cast<Int8>(),
    );
  }

  late final TranslateTextDart TranslateTextPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<TranslateTextNative>>('GMEUnity_TranslateText')
          .asFunction<TranslateTextDart>();

  int TranslateText(
    String text,
    String sourceLanguage,
    String translateLanguage,
  ) {
    return TranslateTextPtr(
      _gmeInstance,
      text.toNativeUtf8().cast<Int8>(),
      sourceLanguage.toNativeUtf8().cast<Int8>(),
      translateLanguage.toNativeUtf8().cast<Int8>(),
    );
  }

  late final GetFileSizeDart GetFileSizePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<GetFileSizeNative>>('GMEUnity_GetFileSize')
          .asFunction<GetFileSizeDart>();

  int GetFileSize(String filePath) {
    return GetFileSizePtr(_gmeInstance, filePath.toNativeUtf8().cast<Int8>());
  }

  late final GetVoiceFileDurationDart GetVoiceFileDurationPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<GetVoiceFileDurationNative>>(
            'GMEUnity_GetVoiceFileDuration',
          )
          .asFunction<GetVoiceFileDurationDart>();

  int GetVoiceFileDuration(String filePath) {
    return GetVoiceFileDurationPtr(
      _gmeInstance,
      filePath.toNativeUtf8().cast<Int8>(),
    );
  }

  late final StartRecordingWithStreamingRecognitionDart
  StartRecordingWithStreamingRecognitionPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StartRecordingWithStreamingRecognitionNative>>(
            'GMEUnity_StartRecordingWithStreamingRecognition',
          )
          .asFunction<StartRecordingWithStreamingRecognitionDart>();

  int StartRecordingWithStreamingRecognition(
    String filePath,
    String speechLanguage,
    String translateLanguage,
  ) {
    return StartRecordingWithStreamingRecognitionPtr(
      _gmeInstance,
      filePath.toNativeUtf8().cast<Int8>(),
      speechLanguage.toNativeUtf8().cast<Int8>(),
      translateLanguage.toNativeUtf8().cast<Int8>(),
    );
  }

  late final SetPTTSourceLanguageDart SetPTTSourceLanguagePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetPTTSourceLanguageNative>>(
            'GMEUnity_SetPTTSourceLanguage',
          )
          .asFunction<SetPTTSourceLanguageDart>();

  int SetPTTSourceLanguage(String sourceLanguage) {
    return SetPTTSourceLanguagePtr(
      _gmeInstance,
      sourceLanguage.toNativeUtf8().cast<Int8>(),
    );
  }

  late final TextToSpeechDart TextToSpeechPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<TextToSpeechNative>>('GMEUnity_TextToSpeech')
          .asFunction<TextToSpeechDart>();

  int TextToSpeech(
    int serialNumber,
    String text,
    String voiceName,
    String languageCode,
    double speakingRate,
  ) {
    return TextToSpeechPtr(
      _gmeInstance,
      serialNumber,
      text.toNativeUtf8().cast<Int8>(),
      voiceName.toNativeUtf8().cast<Int8>(),
      languageCode.toNativeUtf8().cast<Int8>(),
      speakingRate,
    );
  }
}
