import 'dart:async';
import 'dart:math';

import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/interfaces/appointment_consultation.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/server_config_manager.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/controller/real_time_consultation_controller.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:flyinsono/views/desktop/real_time_consultation/widgets/add_participants.dart';
import 'package:get/get.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_lib_media_rt/implementations/trtc/channel.dart';

class MembersController {
  LiveConsultationController controller;
  LiveConsulationState get state => controller.state;
  RealTimeConsultationController get realTimeConsultationController =>
      controller.realTimeConsultationController!;
  ILiveConsultationManager get liveConsultationManager =>
      controller.liveConsultationManager;
  MembersController(this.controller);

  Timer? _heartbeatTimer; //会诊心跳

  Timer? _timer; //会诊计时
  int _errorTimes = 0;

  ///添加会诊成员
  Future<void> addConsultationMember([List<String>? mobileUserCodes]) async {
    List<String> userCodes = [];

    if (mobileUserCodes != null) {
      userCodes = mobileUserCodes;
    } else {
      userCodes = realTimeConsultationController
          .state.applicationInfo.participantsTotal;
    }
    await liveConsultationManager.inviteInLiveConsultationAsync(
      state.liveConsultation.consultationCode ?? '',
      userCodes,
      state.liveConsultation.roomNo,
    );
    Map<String, ConsultationMember> members = {};
    for (var code in userCodes) {
      if (!state.memberStatus.containsKey(code)) {
        var userInfo = realTimeConsultationController
            .state.allSelectableParticipants
            .firstWhereOrNull((element) => element.itemCode == code);
        members[code] = ConsultationMember(
          id: code,
          headImageToken: userInfo?.image,
          name: userInfo?.name ?? '',
          status: MemberStatus.Calling,
          sortLevel: 2,
        );
      }
    }
    state.memberStatus.addAll(members);
  }

  ///添加成员
  Future<void> addMember() async {
    realTimeConsultationController.state.currentConsultationCode =
        state.selectedConsultationCode;
    router.dialog(
      () => AddParticipantsPage(
        confirmCallback: addConsultationMember, //回调刷新参与人员UI
        controller: realTimeConsultationController,
      ),
    );
  }

  ///再次呼叫
  Future<void> callAgain(String targetId) async {
    final result = await liveConsultationManager.inviteInLiveConsultationAsync(
      state.liveConsultation.consultationCode ?? '',
      [targetId],
      state.liveConsultation.roomNo,
    );
    var resultCode = result.consultationCode ?? '';
    if (resultCode.isNotEmpty) {
      logger.i('callAgain $targetId success');
      state.memberStatus.update(targetId, (value) {
        value.status = MemberStatus.Calling;
        return value;
      });
    } else {
      logger.i('callAgain $targetId failed');
    }
  }

  ///取消呼叫
  Future<void> cancelCall(String targetCode) async {
    var result = await liveConsultationManager
        .cancelInvitingInLiveConsultationAsync(
            state.liveConsultation.consultationCode ?? '', [targetCode]);
    final consultationCode = result.consultationCode ?? '';
    if (consultationCode.isNotEmpty) {
      state.memberStatus.update(targetCode, (value) {
        value.status = MemberStatus.Cancel;
        return value;
      });
    }
  }

  ///初始化待会诊病人列表
  Future<void> initWaitInLineForConsultationOatients() async {
    try {
      if (state.consultationDetail.expertUserCode != Store.user.code) {
        return;
      }
      final appointmentConsultationManager =
          Get.find<IAppointmentConsultation>();
      final consultationPageDatas = await appointmentConsultationManager
          .findCanSwitchConsultationsAsync(state.selectedConsultationCode);
      state.waitInLineForConsulationPatients = consultationPageDatas;
    } catch (e) {
      logger.e(
          'LiveConsultationController _initWaitInLineForConsultationOatients',
          e);
    }
  }

  ///开启会诊心跳
  Future<void> startHeartbeat() async {
    int heartbeatSerconds = Store.user.liveConsultationRateSeconds ?? 10;
    logger.i('_startHeartbeat by id:${state.selectedConsultationCode}');
    liveConsultationManager
        .consultationHeartRateSendOnce(state.selectedConsultationCode);
    logger
        .i('_startHeartbeat by id:${state.selectedConsultationCode},first end');

    /// 最小安全间隔时间为 10s
    int safeHeartbeatSeconds = max(heartbeatSerconds, 10);
    _heartbeatTimer = Timer.periodic(
      Duration(seconds: safeHeartbeatSeconds),
      (timer) async {
        try {
          var result = await liveConsultationManager
              .consultationHeartRateSendOnce(state.selectedConsultationCode);
          print(result);
          if (_errorTimes != 0) {
            ///网络断开后恢复网络，重新加载超声机画面
            ConsultationMember? member = state.memberStatus.values
                .toList()
                .firstWhereOrNull((e) => e.memberType == LiveMemberEnum.Device);

            if (member != null) {
              var deviceInfo = member.videoDeviceInfos?.firstWhere((element) =>
                  element.videoDeviceSourceType ==
                  VideoDeviceSourceTypeEnum.Desktop);
              if (deviceInfo != null &&
                  state.playChannels.containsKey(deviceInfo.videoDeviceId)) {
                var channel =
                    state.playChannels[deviceInfo.videoDeviceId]?.channel;
                if (channel is TrtcPlayChannel) {
                  Future.delayed(Duration(seconds: 3), () {
                    channel.playStateChanged.emit(this, true);
                  });
                }
              }
            }
            _errorTimes = 0;
          }
        } on JsonRpcException catch (e) {
          _errorTimes++;
          if (_errorTimes >= ServerConfigManager.consultationTimeoutTimes) {
            controller.leaveConsultation();
          }
          //833是会诊已结束的错误码
          if (e.code == 833 || e.data?.code == 833) {
            controller.leaveConsultation();
          } else {
            PromptBox.toast(i18nBook.common.networkQualityWarning.t);
          }
        } catch (e) {
          logger.e('LiveConsultationManager heartRateAsync:', e);
        }
      },
    );
    _timer = Timer.periodic(
      Duration(seconds: 1),
      (timer) {
        if (state.seconds == 59) {
          state.seconds = 0;
          state.minute++;
        } else {
          state.seconds++;
        }
      },
    );
  }

  Future<void> destroyMemory() async {
    _heartbeatTimer?.cancel();
    _heartbeatTimer = null;
    _timer?.cancel();
    _timer = null;
  }
}
