import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:fluro/fluro.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:yumi/app_localizations.dart';
import 'package:yumi/app/constants/sc_room_msg_type.dart';
import 'package:yumi/shared/tools/sc_permission_utils.dart';
import 'package:yumi/shared/tools/sc_room_utils.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
import 'package:yumi/services/room/rc_room_manager.dart';
import 'package:yumi/services/audio/rtm_manager.dart';
import 'package:yumi/services/auth/user_profile_manager.dart';
import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart';
import 'package:provider/provider.dart';
import 'package:yumi/ui_kit/components/sc_tts.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/app/routes/sc_routes.dart';
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
import 'package:yumi/shared/tools/sc_lk_dialog_util.dart';
import 'package:yumi/shared/tools/sc_loading_manager.dart';
import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
import 'package:yumi/shared/business_logic/models/res/join_room_res.dart';
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
import 'package:yumi/shared/business_logic/models/res/mic_res.dart';
import 'package:yumi/shared/business_logic/models/res/room_res.dart';
import 'package:yumi/modules/room/voice_room_route.dart';
import 'package:yumi/ui_kit/widgets/room/empty_mai_select.dart';
import 'package:yumi/ui_kit/widgets/room/room_user_info_card.dart';
import '../../shared/tools/sc_heartbeat_utils.dart';
import '../../shared/data_sources/models/enum/sc_heartbeat_status.dart';
import '../../shared/data_sources/models/enum/sc_room_info_event_type.dart';
import '../../shared/data_sources/models/enum/sc_room_roles_type.dart';
import '../../shared/business_logic/models/res/sc_is_follow_room_res.dart';
import '../../shared/business_logic/models/res/sc_room_red_packet_list_res.dart';
import '../../shared/business_logic/models/res/sc_room_rocket_status_res.dart';
import '../../shared/business_logic/models/res/sc_room_theme_list_res.dart';
import '../../shared/tools/sc_room_profile_cache.dart';
import '../../ui_kit/components/sc_float_ichart.dart';

typedef OnSoundVoiceChange = Function(num index, int volum);
typedef RtcProvider = RealTimeCommunicationManager;

class RealTimeCommunicationManager extends ChangeNotifier {
  bool needUpDataUserInfo = false;

  ///当前所在房间
  JoinRoomRes? currenRoom;

  /// 声音音量变化监听
  final List<OnSoundVoiceChange> _onSoundVoiceChangeList = [];

  ///麦位
  Map<num, MicRes> roomWheatMap = {};

  RtcEngine? engine;
  BuildContext? context;
  RtmProvider? rtmProvider;

  SCIsFollowRoomRes? isFollowRoomRes;
  SCRoomRocketStatusRes? roomRocketStatus;

  ///房间是否静音
  bool roomIsMute = false;

  bool closeFullGame = false;

  ///禁音开关 默认关闭
  bool isMic = true;

  ///在线用户列表
  List<SocialChatUserProfile> onlineUsers = [];

  ///房间管理员
  List<SocialChatUserProfile> managerUsers = [];

  ///音乐是否正在播放
  bool isMusicPlaying = false;

  ///房间红包列表
  List<SCRoomRedPacketListRes> redPacketList = [];

  num roomTaskClaimableCount = 0;

  initializeRealTimeCommunicationManager(BuildContext context) {
    this.context = context;
  }

  Future<void> joinAgoraVoiceChannel() async {
    try {
      engine = await _initAgoraRtcEngine();
      engine?.setAudioProfile(
        profile: AudioProfileType.audioProfileSpeechStandard,
        scenario: AudioScenarioType.audioScenarioGameStreaming,
      );
      engine?.enableAudioVolumeIndication(
        interval: 500,
        smooth: 3,
        reportVad: true,
      );
      await engine?.disableVideo();
      await engine?.setLocalPublishFallbackOption(
        StreamFallbackOptions.streamFallbackOptionAudioOnly,
      );
      engine?.registerEventHandler(
        RtcEngineEventHandler(
          onError: (ErrorCodeType err, String msg) {
            print('rtc错误${err}');
          },
          onLocalAudioStateChanged:
              (
                RtcConnection connection,
                LocalAudioStreamState state,
                LocalAudioStreamReason reason,
              ) {},
          onAudioRoutingChanged: (routing) {},
          onAudioMixingStateChanged: (
            AudioMixingStateType state,
            AudioMixingReasonType reason,
          ) {
            switch (state) {
              case AudioMixingStateType.audioMixingStatePlaying:
                isMusicPlaying = true;
                break;
              case AudioMixingStateType.audioMixingStateStopped:
              case AudioMixingStateType.audioMixingStateFailed:
                isMusicPlaying = false;
                break;
              default:
                break;
            }
          },
          onRemoteAudioStateChanged: (
            RtcConnection connection,
            int remoteUid,
            RemoteAudioState state,
            RemoteAudioStateReason reason,
            int elapsed,
          ) {
            // print('用户 $remoteUid 音频状态: $state, 原因: $reason');
          },
          onJoinChannelSuccess: (RtcConnection connection, int elapsed) {
            print('rtc 自己加入 ${connection.channelId} ${connection.localUid}');
          },
          onUserJoined: (connection, remoteUid, elapsed) {
            print('rtc用户 $remoteUid 加入了频道');
          },
          // 监听远端用户离开
          onUserOffline: (connection, remoteUid, reason) {
            print('rtc用户 $remoteUid 离开了频道 (原因: ${reason})');
          },
          onTokenPrivilegeWillExpire: (
            RtcConnection connection,
            String token,
          ) async {
            var rtcToken = await SCAccountRepository().getRtcToken(
              currenRoom?.roomProfile?.roomProfile?.id ?? "",
              AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
            );
            engine?.renewToken(rtcToken.rtcToken ?? "");
          },
          onAudioVolumeIndication: initializeAudioVolumeIndicationCallback,
        ),
      );
      var rtcToken = await SCAccountRepository().getRtcToken(
        currenRoom?.roomProfile?.roomProfile?.id ?? "",
        AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
      );
      await engine?.joinChannel(
        token: rtcToken.rtcToken ?? "",
        channelId: currenRoom?.roomProfile?.roomProfile?.id ?? "",
        uid: int.parse(
          AccountStorage().getCurrentUser()?.userProfile?.account ?? "0",
        ),
        options: ChannelMediaOptions(
          // 自动订阅所有视频流
          autoSubscribeVideo: false,
          // 自动订阅所有音频流
          autoSubscribeAudio: true,
          // 发布摄像头采集的视频
          publishCameraTrack: false,
          // 发布麦克风采集的音频
          publishMicrophoneTrack: true,
          // 设置用户角色为 clientRoleBroadcaster（主播）或 clientRoleAudience（观众）
          clientRoleType: ClientRoleType.clientRoleAudience,
          channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
        ),
      );
      engine?.muteAllRemoteAudioStreams(roomIsMute);
    } catch (e) {
      SCTts.show("Join room fail");
      exitCurrentVoiceRoomSession(false);
      print('加入失败：${e.runtimeType},${e.toString()}');
    }
  }

  Future<RtcEngine> _initAgoraRtcEngine() async {
    RtcEngine? engine;
    while (engine == null) {
      engine = createAgoraRtcEngine();
      await engine.initialize(
        RtcEngineContext(appId: SCGlobalConfig.agoraRtcAppid),
      );
    }
    return engine;
  }

  void initializeAudioVolumeIndicationCallback(
    RtcConnection connection,
    List<AudioVolumeInfo> speakers,
    int speakerNumber,
    int totalVolume,
  ) {
    // if (user == null) {
    //   throw "本地User尚未初始化";
    // }
    // print('初始化声音监听器:${user.toJson()}');

    ///声音全部清零
    roomWheatMap.forEach((k, v) {
      roomWheatMap[k]!.setVolume = 0;
    });
    for (var info in speakers) {
      num? uid = info.uid;
      int voloum = info.volume!;
      print('${info.uid}在说话---${voloum}');

      if (voloum > 0) {
        ///是本地声音
        if (uid == 0) {
          uid = num.parse(
            AccountStorage().getCurrentUser()!.userProfile!.account!,
          );
        }

        ///在哪个麦
        roomWheatMap.forEach((k, v) {
          if (v.user != null) {
            if (num.parse(v.user!.account!) == uid) {
              roomWheatMap[k]!.setVolume = voloum;
              for (var element in _onSoundVoiceChangeList) {
                element(k, voloum);
              }
            }
          }
        });
      }
    }
  }

  ///关注/取消房间
  void followCurrentVoiceRoom() async {
    var result = await SCAccountRepository().followRoom(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
    );
    if (isFollowRoomRes != null) {
      isFollowRoomRes = isFollowRoomRes!.copyWith(
        followRoom: !isFollowRoomRes!.followRoom!,
      );
    } else {
      isFollowRoomRes = SCIsFollowRoomRes(followRoom: result);
    }
    SmartDialog.dismiss(tag: "unFollowDialog");
    notifyListeners();
  }

  int startTime = 0;

  String? _preferNonEmpty(String? primary, String? fallback) {
    if ((primary ?? "").trim().isNotEmpty) {
      return primary;
    }
    if ((fallback ?? "").trim().isNotEmpty) {
      return fallback;
    }
    return primary ?? fallback;
  }

  void updateCurrentRoomBasicInfo({
    String? roomCover,
    String? roomName,
    String? roomDesc,
  }) {
    final currentRoomProfile = currenRoom?.roomProfile?.roomProfile;
    if (currenRoom == null || currentRoomProfile == null) {
      return;
    }
    currenRoom = currenRoom?.copyWith(
      roomProfile: currenRoom?.roomProfile?.copyWith(
        roomProfile: currentRoomProfile.copyWith(
          roomCover: _preferNonEmpty(roomCover, currentRoomProfile.roomCover),
          roomName: _preferNonEmpty(roomName, currentRoomProfile.roomName),
          roomDesc: _preferNonEmpty(roomDesc, currentRoomProfile.roomDesc),
        ),
      ),
    );
    SCRoomProfileCache.saveRoomProfile(
      roomId: currentRoomProfile.id ?? "",
      roomCover: roomCover,
      roomName: roomName,
      roomDesc: roomDesc,
    );
    notifyListeners();
  }

  void joinVoiceRoomSession(
    BuildContext context,
    String roomId, {
    String? pwd,
    bool clearRoomData = false,
    bool needOpenRedenvelope = false,
    String redPackId = "",
  }) async {
    int nextTime = DateTime.now().millisecondsSinceEpoch;
    if (nextTime - startTime < 1000) {
      //频繁点击
      return;
    }
    startTime = nextTime;
    if (clearRoomData) {
      _clearData();
    }
    bool hasPermission = await SCPermissionUtils.checkMicrophonePermission();
    if (!hasPermission) {
      SCTts.show('Microphone permission is denied.');
      throw ArgumentError('Microphone permission is denied.');
    }
    if (roomId == currenRoom?.roomProfile?.roomProfile?.id) {
      ///最小化进入房间,或者进入的是同一个房间
      final loaded = await loadRoomInfo(
        currenRoom?.roomProfile?.roomProfile?.id ?? "",
      );
      if (!loaded) {
        return;
      }
      if (!context.mounted) {
        return;
      }
      Provider.of<SocialChatUserProfileManager>(
        context,
        listen: false,
      ).fetchUserProfileData();
      retrieveMicrophoneList();
      SCFloatIchart().remove();
      SCNavigatorUtils.push(
        context,
        '${VoiceRoomRoute.voiceRoom}?id=$roomId',
        transition: TransitionType.custom,
        transitionDuration: kOpenRoomTransitionDuration,
        transitionBuilder: (
          BuildContext context,
          Animation<double> animation,
          Animation<double> secondaryAnimation,
          Widget child,
        ) {
          return kOpenRoomTransitionBuilder(
            context,
            animation,
            secondaryAnimation,
            child,
          );
        },
      );
    } else {
      SCFloatIchart().remove();
      if (currenRoom != null) {
        await exitCurrentVoiceRoomSession(false);
      }
      if (!context.mounted) {
        return;
      }
      rtmProvider = Provider.of<RtmProvider>(context, listen: false);
      SCLoadingManager.show(context: context);
      try {
        currenRoom = await SCAccountRepository().entryRoom(
          roomId,
          pwd: pwd,
          redPackId: redPackId,
          needOpenRedenvelope: needOpenRedenvelope,
        );
        await initializeRoomSession(
          needOpenRedenvelope: needOpenRedenvelope,
          redPackId: redPackId,
        );
        notifyListeners();
      } catch (e) {
        await resetLocalRoomState(fallbackRtmProvider: rtmProvider);
        rethrow;
      } finally {
        SCLoadingManager.hide();
      }
    }
  }

  ///初始化房间相关
  Future initializeRoomSession({
    bool needOpenRedenvelope = false,
    String? redPackId,
  }) async {
    if ((currenRoom?.roomProfile?.roomProfile?.event ==
                SCRoomInfoEventType.WAITING_CONFIRMED.name ||
            currenRoom?.roomProfile?.roomProfile?.event ==
                SCRoomInfoEventType.ID_CHANGE.name) &&
        currenRoom?.entrants?.roles == SCRoomRolesType.HOMEOWNER.name) {
      ///需要去修改房间信息,创建群聊
      SCNavigatorUtils.push(
        context!,
        "${VoiceRoomRoute.roomEdit}?need=true",
        replace: false,
      );
      return Future;
    }
    SCRoomUtils.roomSCGlobalConfig(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
    );
    if (currenRoom?.roomProfile?.roomProfile?.id !=
        AccountStorage().getCurrentUser()?.userProfile?.id) {
      SCChatRoomRepository()
          .isFollowRoom(currenRoom?.roomProfile?.roomProfile?.id ?? "")
          .then((value) {
            isFollowRoomRes = value;
            notifyListeners();
          });
    }
    SCNavigatorUtils.push(context!, VoiceRoomRoute.voiceRoom, replace: false);
    var joinResult = await rtmProvider?.joinRoomGroup(
      currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "",
      "",
    );
    SCChatRoomRepository()
        .rocketClaim(currenRoom?.roomProfile?.roomProfile?.id ?? "")
        .catchError((e) {
          return true; // 错误已处理
        });
    rtmProvider?.addMsg(
      Msg(
        groupId: currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "",
        msg: SCAppLocalizations.of(context!)!.systemRoomTips,
        type: SCRoomMsgType.systemTips,
      ),
    );
    rtmProvider?.addMsg(
      Msg(
        groupId: currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "",
        msg: currenRoom?.roomProfile?.roomProfile?.roomDesc,
        type: SCRoomMsgType.systemTips,
      ),
    );

    ///获取麦位
    retrieveMicrophoneList();
    Provider.of<SocialChatRoomManager>(
      context!,
      listen: false,
    ).fetchContributionLevelData(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
    );
    await joinAgoraVoiceChannel();
    if (joinResult?.code == 0) {
      Msg joinMsg = Msg(
        groupId: currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "",
        user: AccountStorage().getCurrentUser()?.userProfile,
        msg: "",
        role: currenRoom?.entrants?.roles ?? "",
        type: SCRoomMsgType.joinRoom,
      );
      rtmProvider?.dispatchMessage(joinMsg, addLocal: true);
      if (SCGlobalConfig.isEntryVehicleAnimation) {
        if (AccountStorage().getCurrentUser()?.userProfile?.getMountains() !=
            null) {
          Future.delayed(Duration(milliseconds: 550), () {
            SCGiftVapSvgaManager().play(
              AccountStorage()
                      .getCurrentUser()
                      ?.userProfile
                      ?.getMountains()
                      ?.sourceUrl ??
                  "",
              priority: 100,
              type: 1,
            );
          });
        }
      }
      if (rtmProvider?.msgUserJoinListener != null) {
        rtmProvider?.msgUserJoinListener!(joinMsg);
      }
    }
    SCChatRoomRepository()
        .rocketStatus(currenRoom?.roomProfile?.roomProfile?.id ?? "")
        .then((res) {
          roomRocketStatus = res;
          notifyListeners();
        })
        .catchError((e) {});
    loadRoomRedPacketList(1);

    fetchRoomTaskClaimableCount();
  }

  ///更新房间火箭信息
  void updateRoomRocketConfigurationStatus(SCRoomRocketStatusRes res) {
    roomRocketStatus = res;
    notifyListeners();
  }

  ///获取在线用户
  Future fetchOnlineUsersList() async {
    onlineUsers = await SCChatRoomRepository().roomOnlineUsers(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
    );
    managerUsers.clear();
    for (var user in onlineUsers) {
      if (user.roles == SCRoomRolesType.ADMIN.name) {
        managerUsers.add(user);
      }
    }
    notifyListeners();
  }

  Future retrieveMicrophoneList() async {
    bool isOnMic = false;
    var roomWheatList = await SCChatRoomRepository().micList(
      currenRoom!.roomProfile?.roomProfile?.id ?? "",
    );
    for (var roomWheat in roomWheatList) {
      roomWheatMap[roomWheat.micIndex!] = roomWheat;
      if (roomWheat.user != null &&
          roomWheat.user!.id ==
              AccountStorage().getCurrentUser()?.userProfile?.id) {
        isOnMic = true;

        ///自己在麦上
        SCHeartbeatUtils.scheduleAnchorHeartbeat(
          currenRoom?.roomProfile?.roomProfile?.id ?? "",
        );
      }
    }
    notifyListeners();
    SCHeartbeatUtils.scheduleHeartbeat(
      SCHeartbeatStatus.VOICE_LIVE.name,
      isOnMic,
      roomId: currenRoom?.roomProfile?.roomProfile?.id,
    );
    Future.delayed(Duration(milliseconds: 1500), () {
      fetchOnlineUsersList();
    });
  }

  void fetchRoomTaskClaimableCount() {
    SCChatRoomRepository()
        .roomTaskClaimableCount()
        .then((res) {
          roomTaskClaimableCount = res.claimableCount ?? 0;
          notifyListeners();
        })
        .catchError((e) {});
  }

  Future<List<SCRoomRedPacketListRes>> loadRoomRedPacketList(
    int current,
  ) async {
    var result = await SCChatRoomRepository().roomRedPacketList(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
      current,
    );
    if (current == 1) {
      redPacketList = result;
      notifyListeners();
    }
    return result;
  }

  Future exitCurrentVoiceRoomSession(bool isLogout) async {
    try {
      rtmProvider?.msgAllListener = null;
      rtmProvider?.msgChatListener = null;
      rtmProvider?.msgGiftListener = null;
      SCLoadingManager.show(context: context);
      SCGiftVapSvgaManager().dispose();
      SCHeartbeatUtils.scheduleHeartbeat(SCHeartbeatStatus.ONLINE.name, false);
      SCHeartbeatUtils.cancelAnchorTimer();
      rtmProvider?.cleanRoomData();
      await engine?.leaveChannel();
      await Future.delayed(Duration(milliseconds: 100));
      await engine?.release();
      await rtmProvider?.quitGroup(
        currenRoom!.roomProfile?.roomProfile?.roomAccount ?? "",
      );
      await SCAccountRepository().quitRoom(
        currenRoom!.roomProfile?.roomProfile?.id ?? "",
      );
      _clearData();
      SCLoadingManager.hide();
      if (!isLogout) {
        SCNavigatorUtils.popUntil(context!, ModalRoute.withName(SCRoutes.home));
      }
    } catch (e) {
      print('rtc退出房间出错: $e');
      _clearData();
      SCLoadingManager.hide();
      if (!isLogout) {
        SCNavigatorUtils.popUntil(context!, ModalRoute.withName(SCRoutes.home));
      }
    }
  }

  Future<void> resetLocalRoomState({RtmProvider? fallbackRtmProvider}) async {
    rtmProvider ??= fallbackRtmProvider;
    try {
      SCHeartbeatUtils.cancelTimer();
      SCHeartbeatUtils.cancelAnchorTimer();
      final groupId = currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
      if (groupId.isNotEmpty) {
        await rtmProvider?.quitGroup(groupId);
      }
      await engine?.leaveChannel();
      await Future.delayed(const Duration(milliseconds: 100));
      await engine?.release();
    } catch (e) {
      print('rtc清理本地房间状态出错: $e');
    } finally {
      engine = null;
      rtmProvider?.cleanRoomData();
      _clearData();
      notifyListeners();
    }
  }

  ///清空列表数据
  void _clearData() {
    roomRocketStatus = null;
    rtmProvider
            ?.onNewMessageListenerGroupMap["${currenRoom?.roomProfile?.roomProfile?.roomAccount}"] =
        null;
    roomWheatMap.clear();
    onlineUsers.clear();
    needUpDataUserInfo = false;
    SCRoomUtils.roomUsersMap.clear();
    roomIsMute = false;
    rtmProvider?.roomAllMsgList.clear();
    rtmProvider?.roomChatMsgList.clear();
    redPacketList.clear();
    currenRoom = null;
    isMic = true;
    isMusicPlaying = false;
    DataPersistence.setLastTimeRoomId("");
    SCGiftVapSvgaManager().clearTasks();
    SCRoomUtils.closeAllDialogs();
    SCGlobalConfig.isEntryVehicleAnimation = true;
    SCGlobalConfig.isGiftSpecialEffects = true;
    SCGlobalConfig.isFloatingAnimationInGlobal = true;
    SCGlobalConfig.isLuckGiftSpecialEffects = true;
  }

  void toggleRemoteAudioMuteForAllUsers() {
    roomIsMute = !roomIsMute;
    engine?.muteAllRemoteAudioStreams(roomIsMute);
    notifyListeners();
  }

  ///点击的位置
  void clickSite(num index, {SocialChatUserProfile? clickUser}) {
    if (index == -1) {
      if (clickUser != null) {
        if (clickUser.id ==
            AccountStorage().getCurrentUser()?.userProfile?.id) {
          ///是自己，直接打开资料卡
          showBottomInCenterDialog(
            context!,
            RoomUserInfoCard(userId: clickUser.id),
          );
        } else {
          showBottomInBottomDialog(
            context!,
            EmptyMaiSelect(index: index, clickUser: clickUser),
          );
        }
      }
    } else {
      SocialChatUserProfile? roomWheatUser = roomWheatMap[index]?.user;
      showBottomInBottomDialog(
        context!,
        EmptyMaiSelect(index: index, clickUser: roomWheatUser),
      );
      // if (roomWheatUser != null) {
      //   ///麦上有人
      //   if (roomWheatUser.id ==
      //       AccountStorage().getCurrentUser()?.userProfile?.id) {
      //     ///是自己
      //     showBottomInBottomDialog(
      //       context!,
      //       EmptyMaiSelect(index: index, clickUser: roomWheatUser),
      //     );
      //   } else {
      //     showBottomInBottomDialog(
      //       context!,
      //       RoomUserInfoCard(userId: roomWheatUser.id),
      //     );
      //   }
      // } else {
      //   showBottomInBottomDialog(
      //     context!,
      //     EmptyMaiSelect(index: index, clickUser: roomWheatUser),
      //   );
      // }
    }
  }

  addSoundVoiceChangeListener(OnSoundVoiceChange onSoundVoiceChange) {
    _onSoundVoiceChangeList.add(onSoundVoiceChange);
    print('添加监听:${_onSoundVoiceChangeList.length}');
  }

  removeSoundVoiceChangeListener(OnSoundVoiceChange onSoundVoiceChange) {
    _onSoundVoiceChangeList.remove(onSoundVoiceChange);
    print('删除监听:${_onSoundVoiceChangeList.length}');
  }

  void shangMai(num index, {String? eventType, String? inviterId}) async {
    var myUser = AccountStorage().getCurrentUser()?.userProfile;
    if (currenRoom?.roomProfile?.roomSetting?.touristMike ?? false) {
    } else {
      if (isTourists()) {
        SCTts.show(
          SCAppLocalizations.of(context!)!.touristsAreNotAllowedToGoOnTheMic,
        );
        return;
      }
    }

    try {
      var micGoUpRes = await SCChatRoomRepository().micGoUp(
        currenRoom?.roomProfile?.roomProfile?.id ?? "",
        index,
        eventType: eventType,
        inviterId: inviterId,
      );

      /// 设置成主播角色
      engine?.renewToken(micGoUpRes.roomToken ?? "");
      if (!micGoUpRes.micMute!) {
        if (!isMic) {
          engine?.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
          adjustRecordingSignalVolume(100);
          await engine?.muteLocalAudioStream(false);
        }
      } else {
        engine?.setClientRole(role: ClientRoleType.clientRoleAudience);
        await engine?.muteLocalAudioStream(true);
      }
      SCHeartbeatUtils.scheduleAnchorHeartbeat(
        currenRoom?.roomProfile?.roomProfile?.id ?? "",
      );
      var us = roomWheatMap[index];
      us?.copyWith(
        user: SocialChatUserProfile(
          id: myUser?.id,
          account: myUser?.account,
          userAvatar: myUser?.userAvatar,
          userNickname: myUser?.userNickname,
          userSex: myUser?.userSex,
        ),
      );
      roomWheatMap[index] = us!;
      if (us.micMute!) {
        ///房主上麦自动解禁麦位
        if (isFz()) {
          jieJinMai(index);
        }
      }

      notifyListeners();
    } catch (ex) {
      SCTts.show('Failed to put on the microphone, $ex');
    }
  }

  xiaMai(num index) async {
    SCChatRoomRepository()
        .micGoDown(currenRoom?.roomProfile?.roomProfile?.id ?? "", index)
        .whenComplete(() {
          //自己
          if (roomWheatMap[index]?.user?.id ==
              AccountStorage().getCurrentUser()?.userProfile?.id) {
            isMic = true;
            engine?.muteLocalAudioStream(true);
          }
          SCHeartbeatUtils.cancelAnchorTimer();

          /// 设置成主持人角色
          engine?.renewToken("");
          engine?.setClientRole(role: ClientRoleType.clientRoleAudience);
          roomWheatMap[index]?.setUser = null;
          notifyListeners();
        });
  }

  ///踢人下麦
  killXiaMai(String userId) {
    try {
      roomWheatMap.forEach((k, v) async {
        if (v.user?.id == userId) {
          var canKill = await SCChatRoomRepository().kickOffMicrophone(
            currenRoom?.roomProfile?.roomProfile?.id ?? "",
            userId,
          );
          if (canKill) {
            await SCChatRoomRepository().micKill(
              currenRoom?.roomProfile?.roomProfile?.id ?? "",
              k,
            );
            Provider.of<RtmProvider>(context!, listen: false).dispatchMessage(
              Msg(
                groupId: currenRoom?.roomProfile?.roomProfile?.roomAccount,
                msg: userId,
                type: SCRoomMsgType.killXiaMai,
              ),
              addLocal: false,
            );
            roomWheatMap[k]?.setUser = null;
            notifyListeners();
          } else {
            SCTts.show("cant kill the user");
          }
        }
      });
    } catch (e) {
      SCTts.show("kill the user fail");
      print('踢人下麦失败');
    }
  }

  ///自己是否在麦上
  bool isOnMai() {
    return roomWheatMap.values
        .map((userWheat) => userWheat.user?.id)
        .toList()
        .contains(AccountStorage().getCurrentUser()?.userProfile?.id);
  }

  ///自己是否在指定的麦上
  bool isOnMaiInIndex(num index) {
    return roomWheatMap[index]?.user?.id ==
        AccountStorage().getCurrentUser()?.userProfile?.id;
  }

  ///点击的用户在哪个麦上
  num userOnMaiInIndex(String userId) {
    num index = -1;
    roomWheatMap.forEach((k, value) {
      if (value.user?.id == userId) {
        index = k;
      }
    });
    return index;
  }

  ///座位上的用户是否开麦
  bool userOnMaiInIndexOfMute(String userId) {
    bool micMute = false;
    roomWheatMap.forEach((k, value) {
      if (value.user?.id == userId) {
        value.micMute;
      }
    });
    return micMute;
  }

  ///是否是房主
  bool isFz() {
    return currenRoom?.entrants?.roles == SCRoomRolesType.HOMEOWNER.name;
  }

  ///是否是管理
  bool isGL() {
    return currenRoom?.entrants?.roles == SCRoomRolesType.ADMIN.name;
  }

  ///是否是会员
  bool isHY() {
    return currenRoom?.entrants?.roles == SCRoomRolesType.MEMBER.name;
  }

  ///是否是游客
  bool isTourists() {
    return currenRoom?.entrants?.roles == SCRoomRolesType.TOURIST.name;
  }

  ///麦位变动
  void micChange(List<MicRes>? mics) {
    if (mics == null || mics.isEmpty) {
      return;
    }
    roomWheatMap.clear();
    for (var mic in mics) {
      roomWheatMap[mic.micIndex!] = mic;
      if (mic.user?.id == AccountStorage().getCurrentUser()?.userProfile?.id) {
        if (mic.micMute!) {
          ///麦克风静音
          engine?.muteLocalAudioStream(true);
        } else {
          // if (!isMic) {
          //   engine?.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
          // }
          // engine?.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
          ///这个用户需要禁麦/解禁麦克风
          engine?.muteLocalAudioStream(false);
        }
      }
    }
    notifyListeners();

    ///判断自己是不是在麦上
    num index = userOnMaiInIndex(
      AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
    );
    if (index == -1) {
      engine?.muteLocalAudioStream(true);
    }
  }

  ///找一个空麦位 -1表示没有空位
  num findWheat() {
    for (var entry in roomWheatMap.entries) {
      if (entry.value.user == null && !entry.value.micLock!) {
        return entry.key;
      }
    }
    return -1;
  }

  Future<bool> loadRoomInfo(String roomId) async {
    try {
      debugPrint("[Room Cover Sync] loadRoomInfo start roomId=$roomId");
      final value = await SCChatRoomRepository().specific(roomId);
      final currentRoomProfile = currenRoom?.roomProfile?.roomProfile;
      debugPrint(
        "[Room Cover Sync] loadRoomInfo fetched roomId=${value.id ?? roomId} roomCover=${value.roomCover ?? ""} roomName=${value.roomName ?? ""}",
      );
      currenRoom = currenRoom?.copyWith(
        roomProfile: currenRoom?.roomProfile?.copyWith(
          roomCounter: value.counter ?? currenRoom?.roomProfile?.roomCounter,
          roomSetting: value.setting ?? currenRoom?.roomProfile?.roomSetting,
          roomProfile: currentRoomProfile?.copyWith(
            roomCover: _preferNonEmpty(
              value.roomCover,
              currentRoomProfile.roomCover,
            ),
            roomName: _preferNonEmpty(
              value.roomName,
              currentRoomProfile.roomName,
            ),
            roomDesc: _preferNonEmpty(
              value.roomDesc,
              currentRoomProfile.roomDesc,
            ),
          ),
        ),
      );
      debugPrint(
        "[Room Cover Sync] loadRoomInfo applied roomId=$roomId roomCover=${currenRoom?.roomProfile?.roomProfile?.roomCover ?? ""}",
      );

      ///如果是游客禁止上麦，已经在麦上的游客需要下麦
      bool touristMike =
          currenRoom?.roomProfile?.roomSetting?.touristMike ?? false;
      if (!touristMike && isTourists()) {
        num index = userOnMaiInIndex(
          AccountStorage().getCurrentUser()?.userProfile?.id ?? "",
        );
        if (index > -1) {
          xiaMai(index);
        }
      }
      notifyListeners();
      return true;
    } catch (e) {
      await resetLocalRoomState(fallbackRtmProvider: rtmProvider);
      SCTts.show("Room not exists");
      return false;
    }
  }

  ///解锁麦位
  void jieFeng(num index) async {
    await SCChatRoomRepository().micLock(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
      index,
      false,
    );
  }

  ///锁麦
  void fengMai(num index) async {
    await SCChatRoomRepository().micLock(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
      index,
      true,
    );
  }

  ///静音麦克风
  void jinMai(num index) async {
    await SCChatRoomRepository().micMute(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
      index,
      true,
    );
    if (isOnMaiInIndex(index)) {
      Provider.of<RtcProvider>(
        context!,
        listen: false,
      ).engine?.setClientRole(role: ClientRoleType.clientRoleAudience);
    }
    var mic = roomWheatMap[index];
    if (mic != null) {
      roomWheatMap[index] = mic.copyWith(micMute: true);
      notifyListeners();
    }
  }

  ///解除静音麦克风
  void jieJinMai(num index) async {
    await SCChatRoomRepository().micMute(
      currenRoom?.roomProfile?.roomProfile?.id ?? "",
      index,
      false,
    );
    if (isOnMaiInIndex(index)) {
      if (!Provider.of<RtcProvider>(context!, listen: false).isMic) {
        if (roomWheatMap[index]?.user != null) {
          adjustRecordingSignalVolume(100);
          Provider.of<RtcProvider>(
            context!,
            listen: false,
          ).engine?.setClientRole(role: ClientRoleType.clientRoleBroadcaster);
        }
      }
    }

    var mic = roomWheatMap[index];
    if (mic != null) {
      roomWheatMap[index] = mic.copyWith(micMute: false);
      notifyListeners();
    }
  }

  void addOnlineUser(String groupId, SocialChatUserProfile user) {
    if (groupId != currenRoom?.roomProfile?.roomProfile?.roomAccount) {
      return;
    }
    bool isExtOnlineList = false;
    for (var us in onlineUsers) {
      if (us.id == user.id) {
        isExtOnlineList = true;
        break;
      }
    }
    if (!isExtOnlineList) {
      Provider.of<RtcProvider>(context!, listen: false).onlineUsers.add(user);
      notifyListeners();
    }
  }

  void removOnlineUser(String groupId, String userId) {
    if (groupId != currenRoom?.roomProfile?.roomProfile?.roomAccount) {
      return;
    }
    SocialChatUserProfile? isExtOnlineUser;
    for (var us in onlineUsers) {
      if (us.id == userId) {
        isExtOnlineUser = us;
        break;
      }
    }
    if (isExtOnlineUser != null) {
      Provider.of<RtcProvider>(
        context!,
        listen: false,
      ).onlineUsers.remove(isExtOnlineUser);
      notifyListeners();
    }
  }

  void starPlayEmoji(Msg msg) {
    if (msg.number! > -1) {
      var mic = roomWheatMap[msg.number];
      if (mic != null && mic.user != null) {
        roomWheatMap[msg.number!] = mic.copyWith(
          emojiPath: msg.msg,
          type: msg.type,
          number: msg.msg,
        );
        notifyListeners();
      }
    }
  }

  ///更新房间背景
  void updateRoomBG(SCRoomThemeListRes res) {
    var roomTheme = RoomTheme(
      expireTime: res.expireTime,
      id: res.id,
      themeStatus: res.themeStatus,
      themeBack: res.themeBack,
    );
    currenRoom?.roomProps?.setRoomTheme(roomTheme);
    notifyListeners();
  }

  void updateRoomSetting(RoomSetting roomSetting) {
    currenRoom?.roomProfile?.setRoomSetting(roomSetting);
    notifyListeners();
  }

  Map<num, GlobalKey<State<StatefulWidget>>> seatGlobalKeyMap = {};

  void bindTargetKey(num index, GlobalKey<State<StatefulWidget>> targetKey) {
    seatGlobalKeyMap[index] = targetKey;
  }

  GlobalKey<State<StatefulWidget>>? getSeatGlobalKeyByIndex(String userId) {
    ///需要有人的座位
    num index = userOnMaiInIndex(userId);
    if (index > -1) {
      return seatGlobalKeyMap[index];
    }
    return null;
  }

  ///播放音乐
  void startAudioMixing(String localPath, int cycle) {
    if (localPath.isEmpty) {
      return;
    }
    engine?.startAudioMixing(
      filePath: localPath,
      loopback: false,
      cycle: cycle,
    );
  }

  void adjustRecordingSignalVolume(int volume) {
    engine?.adjustRecordingSignalVolume(volume);
  }
}
