import 'package:fis_common/logger/logger.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/interfaces/entities/consultation_member.dart';
import 'package:flyinsono/managers/interfaces/entities/live_consultation.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/managers/interfaces/rtmp_mock_rtc.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/live_consultation/controller.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/live_consultation/state.dart';
import 'package:get/get.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_i18n/i18n.dart';

class MemberListeners {
  LiveConsultationController controller;
  LiveConsulationState get state => controller.state;
  final liveConsultationManager = Get.find<ILiveConsultationManager>();
  MemberListeners(this.controller);

  ///监听成员状态变化
  void addListeners() {
    //接受邀请
    liveConsultationManager.onAcceptConsultation
        .addListener(_onMemberAcceptConsultation);
    //拒绝邀请
    liveConsultationManager.onRejectConsultation
        .addListener(_onMemberRejectApplayConsultation);
    //成员启用或关闭静音
    liveConsultationManager.onMemberMute.addListener(_onMemberMute);
    //成员启用或关闭摄像头
    liveConsultationManager.onSwitchVideoPlay.addListener(_onSwitchVideoPlay);
    liveConsultationManager.onLeaveConsultation.addListener(_onMemberLeave);
    liveConsultationManager.onJoinInConsultation
        .addListener(_onMemberJoin); // 受邀者进入房间
    liveConsultationManager.onNetworkErrConsultation
        .addListener(_onMemberNetworkError);
    liveConsultationManager.onJoinConsultation
        .addListener(_onMemberJoin); // 房间固定成员进入房间
    liveConsultationManager.onChangeConsultation
        .addListener(_onConsultationChange);
    liveConsultationManager.onCloseConsultationDueToChange
        .addListener(_onCloseConsultation);
    liveConsultationManager.onCancelInvitingConsultation
        .addListener(_onCancelInviting);
    liveConsultationManager.onCloseConsultation
        .addListener(_onCloseConsultation);
  }

  void dispose() {
    liveConsultationManager.onCancelInvitingConsultation
        .removeListener(_onCancelInviting);
    liveConsultationManager.onAcceptConsultation
        .removeListener(_onMemberAcceptConsultation);
    liveConsultationManager.onRejectConsultation
        .removeListener(_onMemberRejectApplayConsultation);
    liveConsultationManager.onMemberMute.removeListener(_onMemberMute);
    liveConsultationManager.onSwitchVideoPlay
        .removeListener(_onSwitchVideoPlay);
    liveConsultationManager.onJoinInConsultation.removeListener(_onMemberJoin);
    liveConsultationManager.onNetworkErrConsultation
        .removeListener(_onMemberNetworkError);
    liveConsultationManager.onJoinConsultation.removeListener(_onMemberJoin);
    liveConsultationManager.onChangeConsultation
        .removeListener(_onConsultationChange);
    liveConsultationManager.onCloseConsultationDueToChange
        .removeListener(_onCloseConsultation);
    liveConsultationManager.onCloseConsultation
        .removeListener(_onCloseConsultation);
  }

  void _onMemberAcceptConsultation(Object sender, LiveConsultation e) {
    var memberStatus = state.memberStatus;
    var acceptMembers = e.memberLiveDatas ?? [];
    if (acceptMembers.isEmpty) {
      logger.e(
          'ConsultationController _onRejectApplayConsultation error: acceptMember is null');
      return;
    }
    var accepter = acceptMembers[0];
    var accepterId = accepter.id ?? '';
    var member = memberStatus[accepterId];
    if (member != null) {
      state.memberStatus.update(accepterId, (value) {
        value.status = MemberStatus.Accepted;
        return value;
      });
    } else {
      memberStatus[accepterId] = accepter;
    }
  }

  ///成员拒绝
  void _onMemberRejectApplayConsultation(Object sender, LiveConsultation e) {
    var memberStatus = state.memberStatus;
    var rejectorMembers = e.memberLiveDatas ?? [];
    if (rejectorMembers.isEmpty) {
      logger.e(
          'ConsultationController _onRejectApplayConsultation error: rejectorMember is null');
      return;
    }
    var rejector = rejectorMembers[0];
    var member = memberStatus[rejector.id];
    if (member != null) {
      state.memberStatus.update(rejector.id!, (value) {
        value.status = MemberStatus.Rejected;
        return value;
      });
    }
  }

  ///收到某个成员静音的通知
  void _onMemberMute(Object sender, ConsultationMember e) {
    var id = e.id ?? '';
    var mute = e.mute;
    if (state.memberStatus.containsKey(id)) {
      state.memberStatus.update(id, (value) {
        value.mute = mute;
        return value;
      });
    }
  }

  ///切换视频播放
  void _onSwitchVideoPlay(Object sender, ConsultationMember e) {
    var id = e.id ?? '';
    var videoOpend = e.videoOpend;
    if (state.memberStatus.containsKey(id)) {
      state.memberStatus.update(id, (value) {
        value.videoOpend = videoOpend;
        return value;
      });
    }
  }

  ///成员离开
  void _onMemberLeave(Object sender, LiveConsultation e) {
    var members = e.memberLiveDatas ?? [];
    if (members.isEmpty) {
      return;
    }
    var member = members[0];
    var memberStatus = state.memberStatus;
    if (memberStatus.containsKey(member.id)) {
      memberStatus.update(member.id!, (value) {
        value.status = MemberStatus.Left;
        return value;
      });
    }
  }

  ///成员加入
  void _onMemberJoin(Object sender, LiveConsultation e) {
    if (e.memberLiveDatas == null || e.memberLiveDatas!.isEmpty) {
      return;
    }
    ConsultationMember member = e.memberLiveDatas![0];
    String targetMemberId = member.id ?? '';
    var members = state.memberStatus;
    if (members.containsKey(targetMemberId)) {
      LiveMemberEnum curMemberType = LiveMemberEnum.User;
      members.update(targetMemberId, (value) {
        value.status = MemberStatus.Joined;
        value.mergedChannel = member.mergedChannel;
        curMemberType = value.memberType;
        if (member.consultationDeviceInfo != null) {
          value.videoDeviceInfos =
              member.consultationDeviceInfo!.videoDeviceOutputList ?? [];
          value.mergedVideoOutputHeight = member.mergedVideoOutputHeight;
          value.mergedVideoOutputWidth = member.mergedVideoOutputWidth;

          print(
              'value : ${value.mergedVideoOutputHeight} ${value.mergedVideoOutputWidth}');
          print(
              'target : ${member.mergedVideoOutputHeight} ${member.mergedVideoOutputWidth}');
          controller.mediaController.cameraDeviceInfo = value.videoDeviceInfos!
              .firstWhereOrNull((element) =>
                  element.videoDeviceSourceType ==
                  VideoDeviceSourceTypeEnum.Camera);
        }
        return value;
      });

      /// 如果是 RTMP ，需要发送虚拟【加入房间】事件
      if (curMemberType == LiveMemberEnum.Device) {
        controller.loadingController.stopLoading();
        Get.find<IRtmpMockRtcManager>().updateDevice(LiveConsultationMember(
            id: member.id,
            videoDeviceInfos:
                member.consultationDeviceInfo!.videoDeviceOutputList ?? [],
            memberType: member.memberType,
            mergedChannel: member.mergedChannel,
            mergedVideoOutputHeight: member.mergedVideoOutputHeight,
            mergedVideoOutputWidth: member.mergedVideoOutputWidth,
            mute: member.mute,
            videoOpend: member.videoOpend));
      }
    } else {
      member.status = MemberStatus.Joined;
      members.addAll(<String, ConsultationMember>{targetMemberId: member});
    }
  }

  ///成员网络异常
  void _onMemberNetworkError(Object sender, LiveConsultation e) {
    if (e.memberLiveDatas == null || e.memberLiveDatas!.isEmpty) {
      return;
    }
    var member = e.memberLiveDatas![0];
    var targetMemberId = member.id ?? '';
    var members = state.memberStatus;
    if (members.containsKey(targetMemberId)) {
      members.update(targetMemberId, (value) {
        value.status = MemberStatus.NetError;
        return value;
      });
    }
  }

  ///切换会诊
  void _onConsultationChange(Object sender, LiveConsultation e) {
    controller.reload(e);
  }

  ///关闭会诊
  void _onCloseConsultation(Object sender, LiveConsultation e) {
    if (e.consultationCode == controller.state.selectedConsultationCode) {
      PromptBox.toast(i18nBook.errorCodes.errorCode833.t);
      controller.leaveConsultation();
    }
  }

  void _onCancelInviting(Object sender, LiveConsultation e) {
    var targetMemberId = e.userCode ?? '';
    var members = state.memberStatus;
    if (members.containsKey(e.userCode)) {
      members.update(targetMemberId, (value) {
        value.status = MemberStatus.Cancel;
        return value;
      });
    }
  }
}
