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

typedef StartPlayMusicNative =
    Int32 Function(
      Pointer<Void>,
      Int32 soundId,
      Pointer<Int8> filePath,
      Int32 loopCount,
    );
typedef StartPlayMusicDart =
    int Function(
      Pointer<Void>,
      int soundId,
      Pointer<Int8> filePath,
      int loopCount,
    );

typedef StopPlayMusicNative = Int32 Function(Pointer<Void>, Int32 soundId);
typedef StopPlayMusicDart = int Function(Pointer<Void>, int soundId);

typedef PausePlayMusicNative = Int32 Function(Pointer<Void>, Int32 soundId);
typedef PausePlayMusicDart = int Function(Pointer<Void>, int soundId);

typedef ResumePlayMusicNative = Int32 Function(Pointer<Void>, Int32 soundId);
typedef ResumePlayMusicDart = int Function(Pointer<Void>, int soundId);

typedef IsMusicPlayEndNative = Int32 Function(Pointer<Void>, Int32 soundId);
typedef IsMusicPlayEndDart = int Function(Pointer<Void>, int soundId);

typedef SetAllMusicVolumeNative = Int32 Function(Pointer<Void>, Int32 volume);
typedef SetAllMusicVolumeDart = int Function(Pointer<Void>, int volume);

typedef SetMusicPublishVolumeNative =
    Int32 Function(Pointer<Void>, Int32 soundId, Int32 volume);
typedef SetMusicPublishVolumeDart =
    int Function(Pointer<Void>, int soundId, int volume);

typedef GetMusicPublishVolumeNative =
    Int32 Function(Pointer<Void>, Int32 soundId);
typedef GetMusicPublishVolumeDart = int Function(Pointer<Void>, int soundId);

typedef SetMusicPlayoutVolumeNative =
    Int32 Function(Pointer<Void>, Int32 soundId, Int32 volume);
typedef SetMusicPlayoutVolumeDart =
    int Function(Pointer<Void>, int soundId, int volume);

typedef GetMusicPlayoutVolumeNative =
    Int32 Function(Pointer<Void>, Int32 soundId);
typedef GetMusicPlayoutVolumeDart = int Function(Pointer<Void>, int soundId);

typedef SetMusicPitchNative =
    Int32 Function(Pointer<Void>, Int32 soundId, Float pitch);
typedef SetMusicPitchDart =
    int Function(Pointer<Void>, int soundId, double pitch);

typedef GetMusicDurationInMSNative =
    Int32 Function(Pointer<Void>, Int32 soundId);
typedef GetMusicDurationInMSDart = int Function(Pointer<Void>, int soundId);

typedef GetMusicCurrentPosInMSNative =
    Int32 Function(Pointer<Void>, Int32 soundId);
typedef GetMusicCurrentPosInMSDart = int Function(Pointer<Void>, int soundId);

typedef SeekMusicToPosInTimeNative =
    Int32 Function(Pointer<Void>, Int32 soundId, Int32 time);
typedef SeekMusicToPosInTimeDart =
    int Function(Pointer<Void>, int soundId, int time);

typedef EnableMusicPublishNative =
    Int32 Function(Pointer<Void>, Int32 soundId, Int8 enable);
typedef EnableMusicPublishDart =
    int Function(Pointer<Void>, int soundId, int enable);

typedef EnableMusicPlayoutNative =
    Int32 Function(Pointer<Void>, Int32 soundId, Int8 enable);
typedef EnableMusicPlayoutDart =
    int Function(Pointer<Void>, int soundId, int enable);

typedef SetVoiceTypeNative = Int32 Function(Pointer<Void>, Int32 voiceType);
typedef SetVoiceTypeDart = int Function(Pointer<Void>, int voiceType);

typedef SetKaraokeTypeNative = Int32 Function(Pointer<Void>, Int32 type);
typedef SetKaraokeTypeDart = int Function(Pointer<Void>, int type);

typedef StartRecordNative =
    Int32 Function(Pointer<Void>, Pointer<Int8> filePath, Int32 content);
typedef StartRecordDart =
    int Function(Pointer<Void>, Pointer<Int8> filePath, int content);

typedef StopRecordNative = Int32 Function(Pointer<Void>);
typedef StopRecordDart = int Function(Pointer<Void>);

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

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

  late final StartPlayMusicDart StartPlayMusicPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StartPlayMusicNative>>(
            'GMEUnity_StartPlayMusic',
          )
          .asFunction<StartPlayMusicDart>();

  int StartPlayMusic(int soundId, String filePath, int loopCount) {
    return StartPlayMusicPtr(
      _gmeInstance,
      soundId,
      filePath.toNativeUtf8().cast<Int8>(),
      loopCount,
    );
  }

  late final StopPlayMusicDart StopPlayMusicPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StopPlayMusicNative>>('GMEUnity_StopPlayMusic')
          .asFunction<StopPlayMusicDart>();

  int StopPlayMusic(int soundId) {
    return StopPlayMusicPtr(_gmeInstance, soundId);
  }

  late final PausePlayMusicDart PausePlayMusicPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<PausePlayMusicNative>>(
            'GMEUnity_PausePlayMusic',
          )
          .asFunction<PausePlayMusicDart>();

  int PausePlayMusic(int soundId) {
    return PausePlayMusicPtr(_gmeInstance, soundId);
  }

  late final ResumePlayMusicDart ResumePlayMusicPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<ResumePlayMusicNative>>(
            'GMEUnity_ResumePlayMusic',
          )
          .asFunction<ResumePlayMusicDart>();

  int ResumePlayMusic(int soundId) {
    return ResumePlayMusicPtr(_gmeInstance, soundId);
  }

  late final IsMusicPlayEndDart IsMusicPlayEndPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<IsMusicPlayEndNative>>(
            'GMEUnity_IsMusicPlayEnd',
          )
          .asFunction<IsMusicPlayEndDart>();

  bool IsMusicPlayEnd(int soundId) {
    return IsMusicPlayEndPtr(_gmeInstance, soundId) != 0;
  }

  late final SetAllMusicVolumeDart SetAllMusicVolumePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetAllMusicVolumeNative>>(
            'GMEUnity_SetAllMusicVolume',
          )
          .asFunction<SetAllMusicVolumeDart>();

  int SetAllMusicVolume(int volume) {
    return SetAllMusicVolumePtr(_gmeInstance, volume);
  }

  late final SetMusicPublishVolumeDart SetMusicPublishVolumePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetMusicPublishVolumeNative>>(
            'GMEUnity_SetMusicPublishVolume',
          )
          .asFunction<SetMusicPublishVolumeDart>();

  int SetMusicPublishVolume(int soundId, int volume) {
    return SetMusicPublishVolumePtr(_gmeInstance, soundId, volume);
  }

  late final GetMusicPublishVolumeDart GetMusicPublishVolumePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<GetMusicPublishVolumeNative>>(
            'GMEUnity_GetMusicPublishVolume',
          )
          .asFunction<GetMusicPublishVolumeDart>();

  int GetMusicPublishVolume(int soundId) {
    return GetMusicPublishVolumePtr(_gmeInstance, soundId);
  }

  late final SetMusicPlayoutVolumeDart SetMusicPlayoutVolumePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetMusicPlayoutVolumeNative>>(
            'GMEUnity_SetMusicPlayoutVolume',
          )
          .asFunction<SetMusicPlayoutVolumeDart>();

  int SetMusicPlayoutVolume(int soundId, int volume) {
    return SetMusicPlayoutVolumePtr(_gmeInstance, soundId, volume);
  }

  late final GetMusicPlayoutVolumeDart GetMusicPlayoutVolumePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<GetMusicPlayoutVolumeNative>>(
            'GMEUnity_GetMusicPlayoutVolume',
          )
          .asFunction<GetMusicPlayoutVolumeDart>();

  int GetMusicPlayoutVolume(int soundId) {
    return GetMusicPlayoutVolumePtr(_gmeInstance, soundId);
  }

  late final SetMusicPitchDart SetMusicPitchPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetMusicPitchNative>>('GMEUnity_SetMusicPitch')
          .asFunction<SetMusicPitchDart>();

  int SetMusicPitch(int soundId, double pitch) {
    return SetMusicPitchPtr(_gmeInstance, soundId, pitch);
  }

  late final GetMusicDurationInMSDart GetMusicDurationInMSPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<GetMusicDurationInMSNative>>(
            'GMEUnity_GetMusicDurationInMS',
          )
          .asFunction<GetMusicDurationInMSDart>();

  int GetMusicDurationInMS(int soundId) {
    return GetMusicDurationInMSPtr(_gmeInstance, soundId);
  }

  late final GetMusicCurrentPosInMSDart GetMusicCurrentPosInMSPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<GetMusicCurrentPosInMSNative>>(
            'GMEUnity_GetMusicCurrentPosInMS',
          )
          .asFunction<GetMusicCurrentPosInMSDart>();

  int GetMusicCurrentPosInMS(int soundId) {
    return GetMusicCurrentPosInMSPtr(_gmeInstance, soundId);
  }

  late final SeekMusicToPosInTimeDart SeekMusicToPosInTimePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SeekMusicToPosInTimeNative>>(
            'GMEUnity_SeekMusicToPosInTime',
          )
          .asFunction<SeekMusicToPosInTimeDart>();

  int SeekMusicToPosInTime(int soundId, int time) {
    return SeekMusicToPosInTimePtr(_gmeInstance, soundId, time);
  }

  late final EnableMusicPublishDart EnableMusicPublishPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<EnableMusicPublishNative>>(
            'GMEUnity_EnableMusicPublish',
          )
          .asFunction<EnableMusicPublishDart>();

  int EnableMusicPublish(int soundId, bool enable) {
    return EnableMusicPublishPtr(_gmeInstance, soundId, enable ? 1 : 0);
  }

  late final EnableMusicPlayoutDart EnableMusicPlayoutPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<EnableMusicPlayoutNative>>(
            'GMEUnity_EnableMusicPlayout',
          )
          .asFunction<EnableMusicPlayoutDart>();

  int EnableMusicPlayout(int soundId, bool enable) {
    return EnableMusicPlayoutPtr(_gmeInstance, soundId, enable ? 1 : 0);
  }

  late final SetVoiceTypeDart SetVoiceTypePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetVoiceTypeNative>>('GMEUnity_SetVoiceType')
          .asFunction<SetVoiceTypeDart>();

  int SetVoiceType(ITMG_VOICE_TYPE type) {
    return SetVoiceTypePtr(_gmeInstance, type.value);
  }

  late final SetKaraokeTypeDart SetKaraokeTypePtr =
      _gmeSdkLib!
          .lookup<NativeFunction<SetKaraokeTypeNative>>(
            'GMEUnity_SetKaraokeType',
          )
          .asFunction<SetKaraokeTypeDart>();

  int SetKaraokeType(ITMG_KARAOKE_TYPE type) {
    return SetKaraokeTypePtr(_gmeInstance, type.value);
  }

  late final StartRecordDart StartRecordPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StartRecordNative>>('GMEUnity_StartRecord')
          .asFunction<StartRecordDart>();

  int StartRecord(String filePath, ITMG_AUDIO_RECORDING_CONTENT content) {
    return StartRecordPtr(
      _gmeInstance,
      filePath.toNativeUtf8().cast<Int8>(),
      content.value,
    );
  }

  late final StopRecordDart StopRecordPtr =
      _gmeSdkLib!
          .lookup<NativeFunction<StopRecordNative>>('GMEUnity_StopRecord')
          .asFunction<StopRecordDart>();

  int StopRecord() {
    return StopRecordPtr(_gmeInstance);
  }
}
