import 'package:fis_common/event/event_type.dart';
import 'package:fis_common/js_plateform/js_platform.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_measure/utils/prompt_box.dart';
import 'package:fis_ui/index.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/services/entity/local_setting.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/common_util.dart';
import 'package:flyinsono/architecture/utils/web_parameter_helpler.dart';
import 'package:flyinsono/managers/interfaces/entities/consultation_member.dart';
import 'package:flyinsono/managers/interfaces/live_course.dart';
import 'package:flyinsono/managers/interfaces/device.dart';
import 'package:flyinsono/managers/interfaces/entities/live_course_membel.dart';
import 'package:flyinsono/managers/interfaces/flyinsono_college.dart';
import 'package:flyinsono/pages/main/home/controller.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:fis_common/index.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'controllers/media_controller.dart';
import 'controllers/member_listeners.dart';
import 'index.dart';
import 'widgets/device_select.dart';
import 'package:universal_html/html.dart' as html;

class LiveCourseController extends GetxController {
  late final MemberListenerController memberListenerController;
  late final MediaController mediaController;
  final flyinsonoCollegeManager = Get.find<IFlyinsonoCollegeManager>();
  final liveCourseManager = Get.find<ILiveCourseManager>();
  final FEventHandler<String> onClearCanavsHandler = FEventHandler<String>();
  final FEventHandler<String> onReceiveData = FEventHandler<String>();
  final memberChange = FEventHandler();
  final state = LiveCourseState();
  bool isExit = false;
  List<String>? initBoardDatas;
  LiveCourseController() {
    memberListenerController = MemberListenerController(this);
    mediaController = MediaController(this);
  }

  @override
  void onInit() {
    _initDatas();
    super.onInit();
  }

  @override
  void onReady() {
    super.onReady();
  }

  @override
  void onClose() {
    mediaController.dispose();
    memberListenerController.dispose();
    if (FPlatform.isWindows || FPlatform.isMacOS) {
      rpc.platform.stopTrainningPush();
    }
    super.onClose();
  }

  @override
  void dispose() {
    super.dispose();
  }

  ///超声机分享
  Future<void> ultrasoundShare() async {
    final deviceManager = Get.find<IDeviceManager>();
    var liveProtocol = state.liveCourse?.liveProtocol;
    var deviceInfo =
        await deviceManager.getUserDevicePagedList(1, 100, isOnline: true);
    if (deviceInfo == null) {
      return;
    }
    List<DeviceExtendInfoDTO> devices;
    if (liveProtocol == TransactionStatusEnum.TRTC) {
      devices = deviceInfo.pageData ?? [];

      /// 暂时不做屏蔽
      // devices = deviceInfo.pageData
      //         ?.where((element) => element.supportRtc)
      //         .toList() ??
      //     [];
    } else {
      devices = deviceInfo.pageData ?? [];
    }
    if (devices.isEmpty) {
      PromptBox.toast(i18nBook.college.noAvailableDevice.t);
      return;
    }
    router.dialog(
      () => DeviceSelectDialog(
        devices: devices,
        onOk: (code) async {
          state.deviceCode = code;
          state.isLocalDesktopShare = false;
          state.isDeviceShare = true;
          var existMember = state.liveCourseMembers.firstWhereOrNull(
              (element) => element.memberType == LiveMemberEnum.Device);
          if (existMember != null &&
              code == existMember.id &&
              existMember.channelInfos != null) {
            PromptBox.toast(i18nBook.college.sharing.t);
            router.back();
            return;
          }
          state.isLoadingDevice = true;
          await liveCourseManager.setShareInLiveCourse(
            state.courseCode,
            code,
            currentShareType: CourseShareType.US,
          );
          if ((FPlatform.isMacOS || FPlatform.isWindows) && state.isTeacher) {
            logger.i('switchPushMode : TranningPushEnum.Window');
            rpc.platform.switchPushMode(TranningPushEnum.Window);
          }
          router.back();
        },
      ),
    );
  }

  ///开启录制
  Future<void> startRecording() async {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      liveCourseManager.startRecording(state.courseCode);
    }
  }

  ///停止录制
  void stopRecording() {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      liveCourseManager.stopRecording();
    }
  }

  ///退出直播课
  Future<void> exitLiveCourse([bool isShellClose = false]) async {
    try {
      CommonUtil.throttle(
        () {
          print("LiveCourseController exitLiveCourse");
          sendInteractiveBoardData('', isClear: true);
          liveCourseManager.leaveLiveCourse(state.courseCode);
          exitCurrentPage(isShellClose);
          if (state.isLocalDesktopShare) {
            liveCourseManager.setShareInLiveCourse(
              state.courseCode,
              Store.user.code,
              currentShareState: CourseShareStates.Closed,
            );
          }
        },
        durationTime: 2000,
      );
    } catch (e) {
      await exitCurrentPage(isShellClose);
    }
  }

  ///退出
  Future<void> exitCurrentPage([bool isShellClose = false]) async {
    print("是否开启了第二窗口：${LocalSetting.ins.isUseSecondWindow!}");
    if (kIsMobile) {
      router.back();
      return;
    }
    if (state.isDeviceShare || state.isLocalDesktopShare) {
      await stopDeviceShare();
    }
    if (isShellClose) {
      await rpc.platform.closeLiveConsultation();
    } else if (Store.user.code == state.courseDetail!.teacherCode) {
      logger.i('teacher start stopTrainningPush');
      await rpc.platform.stopTrainningPush();
      logger.i('teacher end stopTrainningPush');
      if (LocalSetting.ins.isUseSecondWindow!) {
        JSPlateForm.closeSlaveWindow();
      } else {
        router.back();
      }
      logger.i('teacher closeSlaveWindow');
    } else if ((FPlatform.isWindows || FPlatform.isMacOS) &&
        LocalSetting.ins.isUseSecondWindow!) {
      JSPlateForm.closeSlaveWindow();
    } else if (FPlatform.isPureWeb && Store.app.enableNewTab) {
      html.window.close();
    } else {
      router.back(id: kIsMobile ? null : NavIds.HOME);
      try {
        final _navController = Get.find<HomeNavigatorController>();
        _navController.subBack();
      } catch (e) {}
    }
  }

  ///设置音量
  void setVolume(int value, {AudioTypeEnum type = AudioTypeEnum.Speaker}) {
    if (FPlatform.isMacOS || FPlatform.isWindows) {
      var targetValue = value / 100;
      rpc.platform.adjustAudioVoice(type, targetValue);
    }
  }

  ///桌面共享
  Future<void> desktopShare() async {
    if ((FPlatform.isMacOS || FPlatform.isWindows) && state.isTeacher) {
      rpc.platform.switchPushMode(TranningPushEnum.Screen);
    }
    mediaController.startScreenCapture();
    state.isLocalDesktopShare = true;
    await liveCourseManager.setShareInLiveCourse(
      state.courseCode,
      Store.user.code,
    );
  }

  ///设置摄像头是否打开
  void setVideoOpend(bool isOpened) {
    liveCourseManager.setVideoLiveCourse(state.courseCode, isOpened);
  }

  ///设置静音
  void setAudioOpend(bool isMute) {
    liveCourseManager.setMemberMute(state.courseCode, isMute);
    mediaController.setAudioMute(isMute, Store.user.code);
  }

  ///设置静音
  void setAudioMute(bool isMute, String userCode) {
    mediaController.setAudioMute(isMute, userCode);
  }

  Future<void> _initDatas() async {
    try {
      var parameters = router.getParams(NavIds.HOME) ?? {};
      if (parameters.isEmpty) {
        parameters = router.getParams() ?? {};
      }
      if (parameters.isEmpty) {
        parameters = ParameterHelper.parasmeters;
      }
      if (parameters.containsKey('courseCode')) {
        state.courseCode = parameters["courseCode"]!;
        _loadCourseInfos();
      }
    } catch (e) {
      logger.e('LiveCourseController _initData ex:', e);
    }
  }

  ///发送白板数据
  void sendInteractiveBoardData(String value, {bool isClear = false}) {
    try {
      rpc.education.sendCourseInteractiveBoardDataAsync(
        SendLiveInteractiveBoardDataRequest(
          roomId: state.courseCode,
          token: Store.user.token,
          boardData: value,
          isClear: isClear,
        ),
      );
    } catch (e) {
      print(e);
    }
  }

  Future<void> _loadCourseInfos() async {
    state.courseDetail =
        await liveCourseManager.getCourseInfo(state.courseCode);
    if (state.courseDetail?.experts
            ?.any((element) => element.code == Store.user.code) ??
        false) {
      ///小班化成员加入课程
      state.liveCourse =
          await liveCourseManager.joinLiveCourse(state.courseCode);
    } else if (state.courseDetail!.teacherCode == Store.user.code) {
      if (state.courseDetail!.status == CourseStatusEnum.Approved) {
        ///老师开始课程
        state.liveCourse =
            await liveCourseManager.initiateLiveCourse(state.courseCode);
      } else {
        ///老师重新加入课程
        state.liveCourse =
            await liveCourseManager.joinLiveCourse(state.courseCode);
      }
    } else {
      ///普通成员观看课程
      var studentLivePullUrlResult =
          await liveCourseManager.getCoursePullUrl(state.courseCode);
      state.pullUrl = studentLivePullUrlResult.rtmpPullUrl;
    }
    if (state.liveCourse != null) {
      var members = state.liveCourse!.memberLiveDatas ?? [];
      var liveCourseMembers = members
          .map((e) => FLiveCourseMember.fromDto(e).fixMergedVideoOutputSize())
          .toList();
      int index = 0;
      for (var courseMember in liveCourseMembers) {
        courseMember.index = index;
        index++;
      }
      var localMember = liveCourseMembers
          .firstWhereOrNull((element) => element.id == Store.user.code);
      if (localMember != null) {
        localMember.memberStatus = MemberStatus.Joined;
        liveCourseMembers.remove(localMember);
        liveCourseMembers.insert(0, localMember);
      }

      if (state.liveCourse!.deviceLiveDatas?.isNotEmpty ?? false) {
        liveCourseMembers.add(
            FLiveCourseMember.fromDto(state.liveCourse!.deviceLiveDatas!.first)
                .fixMergedVideoOutputSize());
      }
      state.liveCourseMembers = liveCourseMembers;
      if (state.liveCourseMembers
          .any((element) => element.id == Store.user.code)) {
        mediaController.init();
      }
      if (Store.app.enableNewTab && FPlatform.isPureWeb) {
        Store.user.initNotificationConfig(type: WSType.Course);
      }
    }
  }

  Future<void> stopDeviceShare() async {
    try {
      await liveCourseManager.setShareInLiveCourse(
        state.courseCode,
        state.isLocalDesktopShare ? Store.user.code : state.deviceCode!,
        currentShareType: state.isLocalDesktopShare
            ? CourseShareType.Window
            : CourseShareType.US,
        currentShareState: CourseShareStates.Closed,
      );
      mediaController.stopScreenCapture();
      state.mainChannel = null;
      state.isLocalDesktopShare = false;
      state.isDeviceShare = false;
    } catch (e) {
      logger.e('LiveCourseController stopDeviceShare ex', e);
    }
  }
}
