import 'dart:ffi'; // 引入 FFI 库
import 'package:ffi/ffi.dart'; // 导入 ffi 扩展方法
import '../tmg_sdk.dart';
import '../tmg_type.dart';
import '../tmg_audio_ctrl.dart';
import '../tmg_audio_effect_ctrl.dart';
import '../tmg_room.dart';
import '../tmg_ptt.dart';
import '../bindings/tmg_sdk_bindings.dart' as TmgSdkBindings;
import 'tmg_audio_ctrl_impl.dart';
import 'tmg_audio_effect_ctrl_impl.dart';
import 'tmg_room_impl.dart';
import 'tmg_ptt_impl.dart';

typedef AVEventCallback_CSharp =
    Void Function(
      Pointer<Void> api_proxy_holder,
      Int32 event_type,
      Pointer<Int8> data,
    );

class TMGContextImpl extends ITMGContext {
  late final _instance;
  static ITMGDelegate? _onEventCallback;
  late TMGAudioCtrlImpl _audioCtrlInstance = new TMGAudioCtrlImpl();
  late TMGAudioEffectCtrlImpl _audioEffectCtrlInstance =
      new TMGAudioEffectCtrlImpl();
  late TMGRoomImpl _roomInstance = new TMGRoomImpl();
  late TMGPTTImpl _pttInstance = new TMGPTTImpl();

  TMGContextImpl() {
    _instance = new TmgSdkBindings.TmgSdkBindings();
  }

  @override
  int SetTMGDelegate(ITMGDelegate onEventCallback) {
    _onEventCallback = onEventCallback;
    final onEventCallbackPointer = Pointer.fromFunction<AVEventCallback_CSharp>(
      OnEventNativeCallback,
    );
    return _instance.SetDelegate(onEventCallbackPointer);
  }

  @override
  void SetRegion(String region) {
    _instance.SetRegion(region);
  }

  @override
  int Init(String appId, String userID) {
    return _instance.Init(appId, userID);
  }

  @override
  void Poll() {
    _instance.Poll();
  }

  @override
  int Pause() {
    return _instance.Pause();
  }

  @override
  int Resume() {
    return _instance.Resume();
  }

  @override
  int Uninit() {
    return _instance.Uninit();
  }

  @override
  int SetScene(ITMG_APP_SCENE scene) {
    return _instance.SetScene(scene.value);
  }

  @override
  int SetAudioRole(ITMG_AUDIO_MEMBER_ROLE role) {
    return _instance.SetAudioRole(role.value);
  }

  @override
  int SetRangeAudioMode(ITMG_RANGE_AUDIO_MODE rangeAudioMode) {
    return _instance.SetRangeAudioMode(rangeAudioMode.value);
  }

  @override
  int SetRangeAudioTeamID(int teamID) {
    return _instance.SetRangeAudioTeamID(teamID);
  }

  @override
  String GenAuthBuffer(int appId, String roomId, String userId, String key) {
    String result = _instance.GenAuthBuffer(appId, roomId, userId, key);
    return result;
  }

  @override
  int EnterRoom(String room_id, ITMGRoomType room_type, String user_sig) {
    return _instance.EnterRoom(room_id, room_type.value, user_sig);
  }

  @override
  int ExitRoom() {
    return _instance.ExitRoom();
  }

  @override
  bool IsRoomEntered() {
    return _instance.IsRoomEntered();
  }

  @override
  int SetLogLevel(int levelWrite, int levelPrint) {
    return _instance.SetLogLevel(levelWrite, levelPrint);
  }

  @override
  int SetLogPath(String logDir) {
    return _instance.SetLogPath(logDir);
  }

  @override
  String GetLogPath() {
    return _instance.GetLogPath();
  }

  @override
  String GetSDKVersion() {
    return _instance.GetSDKVersion();
  }

  @override
  void SetAppVersion(String appVersion) {
    return _instance.SetAppVersion(appVersion);
  }

  @override
  int ShowDebugView(bool show) {
    return _instance.ShowDebugView(show);
  }

  @override
  ITMGRoom GetRoom() {
    if (_roomInstance == null) {
      _roomInstance = TMGRoomImpl();
    }
    return _roomInstance;
  }

  @override
  ITMGPTT GetPTT() {
    if (_pttInstance == null) {
      _pttInstance = TMGPTTImpl();
    }
    return _pttInstance;
  }

  @override
  ITMGAudioCtrl GetAudioCtrl() {
    if (_audioCtrlInstance == null) {
      _audioCtrlInstance = TMGAudioCtrlImpl();
    }
    return _audioCtrlInstance;
  }

  @override
  ITMGAudioEffectCtrl GetAudioEffectCtrl() {
    if (_audioEffectCtrlInstance == null) {
      _audioEffectCtrlInstance = TMGAudioEffectCtrlImpl();
    }

    return _audioEffectCtrlInstance;
  }

  @override
  int SetRecvMixStreamCount(int count) {
    return _instance.SetAdvanceParams("RecvMixStreamCount", count.toString());
  }

  @override
  int SetAdvanceParams(String key, String value) {
    return _instance.SetAdvanceParams(key, value);
  }

  @override
  String GetAdvanceParams(String key) {
    return _instance.GetAdvanceParams(key);
  }

  @override
  ITMG_MIC_PERMISSION CheckMicPermission() {
    return ITMG_MIC_PERMISSION.values[_instance.CheckMicPermission()];
  }

  static void OnEventNativeCallback(
    Pointer<Void> api_proxy_holder,
    int event_type,
    Pointer<Int8> data,
  ) {
    if (_onEventCallback != null) {
      _onEventCallback?.onEvent(event_type, data.cast<Utf8>().toDartString());
    }
  }
}
