import 'package:fis_jsonrpc/services/notification.m.dart';
import 'package:flyinsono/managers/interfaces/entities/consultation_member.dart';
import 'package:flyinsono/managers/interfaces/entities/live_course_membel.dart';
import 'package:flyinsono/managers/interfaces/live_course.dart';
import 'package:flyinsono/pages/live_course/controller.dart';
import 'package:flyinsono/pages/live_course/state.dart';
import 'package:get/get.dart';

class MemberListenerController {
  final liveCourseManager = Get.find<ILiveCourseManager>();
  late final LiveCourseController controller;
  LiveCourseState get state => controller.state;
  MemberListenerController(LiveCourseController c) {
    controller = c;
    initListenering();
  }

  void initListenering() {
    liveCourseManager.onJoinLiveCourse.addListener(_onJoinLiveCourse);
    liveCourseManager.onNetworkErr.addListener(_onNetworkErr);
    liveCourseManager.onMute.addListener(_onMute);
    liveCourseManager.onSwitchVideoOpend.addListener(_onSwitchVideoOpend);
    liveCourseManager.onHeartRateLeave.addListener(_onHeartRateLeave);
    liveCourseManager.onHeartRateJoin.addListener(_onHeartRateJoin);
    liveCourseManager.onCloseLiveCourse.addListener(_onCloseLiveCourse);
    liveCourseManager.onBoardDataReceive.addListener(_onBoardDataReceive);
    liveCourseManager.onLeave.addListener(_onMemberLeave);
    liveCourseManager.onChangeShareInLiveCourse
        .addListener(_onChangeShareInLiveCourse);
    liveCourseManager.onCourseStatusChange.addListener(_onCourseStatusChange);
    liveCourseManager.exitDesktopSharing.addListener(_onExitDesktopSharing);
  }

  void dispose() {
    liveCourseManager.onJoinLiveCourse.removeListener(_onJoinLiveCourse);
    liveCourseManager.onNetworkErr.removeListener(_onNetworkErr);
    liveCourseManager.onMute.removeListener(_onMute);
    liveCourseManager.onHeartRateJoin.removeListener(_onHeartRateJoin);
    liveCourseManager.onHeartRateLeave.removeListener(_onHeartRateLeave);
    liveCourseManager.onCloseLiveCourse.removeListener(_onCloseLiveCourse);
    liveCourseManager.onBoardDataReceive.removeListener(_onBoardDataReceive);
    liveCourseManager.onLeave.removeListener(_onMemberLeave);
    liveCourseManager.onChangeShareInLiveCourse
        .removeListener(_onChangeShareInLiveCourse);
    liveCourseManager.onCourseStatusChange
        .removeListener(_onCourseStatusChange);
    liveCourseManager.exitDesktopSharing.removeListener(_onExitDesktopSharing);
  }

  //Server的成员加入
  Future<void> _onJoinLiveCourse(
      Object sender, JoinLiveCourseNotification e) async {
    if (state.courseCode != e.courseCode) {
      return;
    }
    var member = state.liveCourseMembers
        .firstWhereOrNull((element) => element.id == e.joiner!.id);
    FLiveCourseMember liveCourseMember;
    if (member != null) {
      state.liveCourseMembers.remove(member);
      liveCourseMember =
          FLiveCourseMember.fromDto(e.joiner!).fixMergedVideoOutputSize();

      liveCourseMember.index = member.index;
      liveCourseMember.channelInfos = member.channelInfos;
      if (member.channelInfos?.isNotEmpty ?? false) {
        if (liveCourseMember.memberType == LiveMemberEnum.Device &&
            state.mainChannel == null) {
          state.mainChannel = liveCourseMember.channelInfos!.first;
        }
      }
    } else {
      liveCourseMember =
          FLiveCourseMember.fromDto(e.joiner!).fixMergedVideoOutputSize();
      if (e.joiner!.memberType == LiveMemberEnum.Device) {
        ///检查是否已经有channel信息，但是无成员信息
        var deviceId = e.joiner!.videoDeviceInfos!
            .toList()
            .firstWhere((element) =>
                element.videoDeviceSourceType ==
                VideoDeviceSourceTypeEnum.Desktop)
            .videoDeviceId;
        if (deviceId != null) {
          FLiveCourseMember? newMember;
          for (var m in state.liveCourseMembers) {
            if (m.videoDeviceInfos == null) {
              continue;
            }
            var deviceInfo = m.videoDeviceInfos!.firstWhereOrNull(
                (element) => element.videoDeviceId == deviceId);
            if (deviceInfo != null) {
              newMember = m;
            }
          }
          if (newMember != null) {
            state.liveCourseMembers.remove(newMember);
            liveCourseMember.channelInfos = newMember.channelInfos;
          }
        }
      }
    }

    liveCourseMember.memberStatus = MemberStatus.Joined;
    if (liveCourseMember.mergedChannel) {
      state.isMergedMode = true;
    }
    state.liveCourseMembers.insert(0, liveCourseMember);
    state.isLoadingDevice = false;
    controller.memberChange.emit(this, null);
  }

  void _onNetworkErr(Object sender, NetworkErrCourseNotification e) {
    if (e.courseCode != state.courseCode) {
      return;
    }
    var memberId = e.networkErrMemberInfo!.id;
    var member = state.liveCourseMembers
        .firstWhereOrNull((element) => element.id == memberId);
    if (member != null) {
      state.liveCourseMembers
          .firstWhere((element) => element.id == memberId)
          .memberStatus = MemberStatus.NetError;
      controller.memberChange.emit(this, null);
    }
  }

  void _onMute(Object sender, MuteLiveCourseNotification e) {
    if (e.courseCode != state.courseCode) {
      return;
    }
    var memberId = e.muterInfo!.id;
    var member = state.liveCourseMembers
        .firstWhereOrNull((element) => element.id == memberId);
    if (member != null) {
      state.liveCourseMembers
          .firstWhere((element) => element.id == memberId)
          .mute = e.mute;
      controller.memberChange.emit(this, null);
    }
  }

  void _onHeartRateLeave(Object sender, HeartRateLeaveCourseNotification e) {
    if (e.courseCode != state.courseCode) {
      return;
    }
    var memberId = e.leaverInfo!.id;
    var member = state.liveCourseMembers
        .firstWhereOrNull((element) => element.id == memberId);
    if (member != null) {
      member.memberStatus = MemberStatus.Left;
      member.channelInfos = null;
      controller.memberChange.emit(this, null);
    }
  }

  void _onHeartRateJoin(Object sender, HeartRateJoinCourseNotification e) {
    _onJoinLiveCourse(
      sender,
      JoinLiveCourseNotification(
        courseCode: e.courseCode,
        joiner: e.joiner,
      ),
    );
  }

  void _onCloseLiveCourse(Object sender, CloseLiveCourseNotification e) {
    if (e.courseCode != state.courseCode) {
      return;
    }
    controller.exitCurrentPage();
  }

  void _onSwitchVideoOpend(Object sender, SwitchLiveCourseVideoNotification e) {
    if (e.courseCode != state.courseCode) {
      return;
    }
    var memberId = e.switcherInfo!.id;
    var member = state.liveCourseMembers
        .firstWhereOrNull((element) => element.id == memberId);
    if (member != null) {
      state.liveCourseMembers
          .firstWhere((element) => element.id == memberId)
          .videoOpend = e.opened;
      controller.memberChange.emit(this, null);
    }
  }

  void _onBoardDataReceive(
      Object sender, SendLiveInteractiveBoardDataNotification e) {
    if (e.isClear) {
      controller.onClearCanavsHandler.emit('', e.userCode!);
    } else {
      controller.onReceiveData.emit(this, e.boardData ?? '');
    }
  }

  void _onMemberLeave(Object sender, LeaveLiveCourseNotification e) {
    _onHeartRateLeave(
      this,
      HeartRateLeaveCourseNotification(
        courseCode: e.courseCode,
        leaverInfo: e.leaverInfo,
      ),
    );
  }

  void _onChangeShareInLiveCourse(
      Object sender, ChangeShareInLiveCourseNotification e) {
    var shareInfo = e.shareInfo!;
    state.shareInfo = shareInfo;
    var targetMemberCode = shareInfo.currentShareMemberCode ?? '';
    var targetMember = state.liveCourseMembers
        .firstWhereOrNull((element) => element.id == targetMemberCode);
    if (targetMember == null) {
      return;
    }
    if (shareInfo.currentShareState == CourseShareStates.Opened) {
      ///TODO(Loki):翻译
      state.shareTip =
          "${targetMember.name}正在分享${shareInfo.currentShareType == CourseShareType.US ? "超声机" : "桌面"}";
    } else {
      state.mainChannel = null;
    }
    controller.memberChange.emit(this, null);
  }

  void _onCourseStatusChange(Object sender, CourseStatusNotification e) {
    if (e.status == CourseStatusEnum.HasEnded) {
      controller.exitCurrentPage();
    }
  }

  void _onExitDesktopSharing(Object sender, bool e) {
    controller.stopDeviceShare();
  }
}
