import 'dart:async';
import 'dart:convert';

import 'package:fis_common/index.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/web_parameter_helpler.dart';
import 'package:flyinsono/managers/interfaces/device.dart';
import 'package:flyinsono/managers/interfaces/remote_controller.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/pages/remote_controller/state.dart';
import 'package:flyinsono/rpc.dart';
import 'package:fis_common/event/event_type.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:flyinsono/views/common/device_live/device_live_detail/state.dart';
import 'package:flyinsono/views/desktop/remote_maintenance/widgets/apiinfo.dart';
import 'package:flyinsono/views/desktop/remote_maintenance/widgets/probe.dart';
import 'package:get/get.dart';

class RemoteControllerController extends FControllerBase {
  RemoteControllerController();
  final state = RemoteControllerState();
  final liveConsultationManager = Get.find<ILiveConsultationManager>();
  final remoteControllerManager = Get.find<IRemoteControllerManager>();
  final deviceManager = Get.find<IDeviceManager>();
  late final FEventHandler<bool>? stopEventHandler = FEventHandler<bool>();

  void onTap() {}
  Timer? _heartbeatTimer;
  bool _receivedNotification = false;
  bool ignoreAllGestures = false;
  // @override
  // void onInit() {
  //   super.onInit();
  // }

  @override
  void onReady() {
    super.onReady();
    _initParameters().then((value) => _initData());
  }

  @override
  void dispose() {
    _heartbeatTimer?.cancel();
    if (state.deviceCode.isNotNullOrEmpty) {
      deviceManager.exitLiveRoom(state.deviceCode);
    }
    remoteControllerManager.onDeviceDisconnectRemote
        .removeListener(_onDeviceDisconnectRemote);
    remoteControllerManager.onProbeApplicationSettingResponse
        .removeListener(_onProbeAndApplicationDataChange);
    super.dispose();
  }

  void _initData() {
    remoteControllerManager.onDeviceDisconnectRemote
        .addListener(_onDeviceDisconnectRemote);
    remoteControllerManager.onProbeApplicationSettingResponse
        .addListener(_onProbeAndApplicationDataChange);
    liveConsultationManager.onDeviceParametersNotification
        .addListener(onDeviceParametersNotification);
    Future.delayed(Duration(milliseconds: 2000), () {
      if (_receivedNotification) {
        return;
      }
      var notifaction =
          liveConsultationManager.cacheDeviceParametersNotification;
      if (notifaction != null) {
        onDeviceParametersNotification(this, notifaction);
      }
    });
  }

  void _onProbeAndApplicationDataChange(
      Object a, ProbeApplicationSettingResponseNotification e) async {
    print(e.toJson());
    getUltrasoundParameters();
  }

  /// 设备端断开连接的通知
  _onDeviceDisconnectRemote(
      Object a, DeviceDisconnectRemoteControlNotification e) {
    //router.back();
  }

  /// 检查设置直播设备状态
  ///
  /// remarks: 1表示正常，0表示失败；2表示需要重载webview
  Future<int> checkLiveDeviceState() async {
    try {
      final code = state.deviceCode;

      // 直播信息变更or不在直播中
      // 重新进入直播
      final liveInfo = await deviceManager.enterLiveRoom(code);
      if (liveInfo != null) {
        // 进入直播成功
        // 更新设备直播信息
        if (state.deviceExtendInfoDTO != null) {
          state.deviceExtendInfoDTO!.liveInfo = liveInfo;
        }
        // state.isOldPlatform = liveInfo.isOldPlatform;
        return 2; // 通知webview reload
      }
    } catch (e) {
      //
    }
    return 0;
  }

  ///开启远程控制心跳
  Future<void> startHeartbeat() async {
    _heartbeatTimer = Timer.periodic(
      Duration(seconds: 10),
      (timer) {
        remoteConnectHeartRateSendOnce();
      },
    );
  }

  /// 远程连接的心跳 (发送一次)
  Future<void> remoteConnectHeartRateSendOnce() async {
    final result = await rpc.device.remoteConnectHeartRateAsync(
      RemoteConnectHeartRateRequest(
        token: Store.user.token,
        isNeedSyn: true,
      ),
    );
  }

  // 初始化数据
  void _initDataState() {
    state.currentSelectedMode = "";
    state.allModes = []; // 所有模式
    state.availableModeInfos = []; // 选中模式 及可选模式
    state.allFunctionInfos = []; // 第一页的数据 所有function
    state.allKeyBoardApiInfos = []; // 第一页的数据 所有keyBoard
    state.secondPageInfos = []; // 参数第二页的数据
    state.secondPageSelectInfos = []; // 参数第二页的下拉数据
    state.thirdPageInfos = []; // 参数第三页的数据
    state.forthPageInfos = []; // 参数第四页的数据
    state.fifthPageInfos = []; // 参数第五页的数据
  }

  void onDeviceParametersNotification(
      Object sender, DeviceParametersNotification e) async {
    _receivedNotification = true;
    if (e.isResponse) {
      state.deviceCode = e.deviceCode ?? '';
      initRemoteControllerData();
      stopEventHandler?.emit(this, true);
      Store.app.busy = false;
    }
  }

  Future<void> _getGsonData() async {
    List<ApiInfo> lastModes = []; // 最后默认的模式,和老版本一样放在列表最后面
    List<ApiInfo> decreaseInfos = []; // 和老版本一样放在KeyBoard列表最后面
    List<ApiInfo> lastFunctionInfos = []; // 这是为了和老版本一样 放在function列表最后面

    UltrasoundSystem? ultrasoundSystem = state.probeData.isNotEmpty
        ? UltrasoundSystem.fromJson(state.probeData)
        : null; // 这部分是当前探头和应用
    state.currentProbe = ultrasoundSystem?.activeProbe ?? ''; // 当前探头
    state.currentApply = ultrasoundSystem?.activeApplication ?? ''; // 当前应用

    state.allProbeDatas = ultrasoundSystem?.probes ?? []; // 当前能切换的探头列表

    state.allApplyDatas = state.allProbeDatas
            .firstWhereOrNull((element) => element.name == state.currentProbe)
            ?.applicationInfos ??
        []; // 当前探头下的所有应用

    ApiInfo apiInfo = ApiInfo.fromJson(state.descriptionData ?? {}); // 这是模式和参数的

    final List<ApiInfo> keyboardChildren = apiInfo.children
            ?.where((child) => child.description == 'Keyboard')
            .toList()
            .first
            .children ??
        []; // 获取的Keyboard数据

    final List<ApiInfo> touchScreenChildren = apiInfo.children
            ?.where((child) => child.description == 'Touch Screen')
            .toList()
            .first
            .children ??
        []; // 获取的Touch Screen数据

    state.currentSelectedMode = touchScreenChildren
            .firstWhereOrNull((element) => element.displayValue == "Checked")
            ?.description ??
        '';

    final List<ApiInfo> functionChildren = touchScreenChildren
            .firstWhereOrNull((element) => element.description == 'Functions')
            ?.children ??
        []; // 获取的Functions数据
    int _totalPage = 1; // 一共多少页数

    ///  这部分是模式
    for (var i in keyboardChildren) {
      if (ModesDescription.items.contains(i.description)) {
        if (i.description == 'Harmonic') {
          i.description = 'HAR';
        }

        state.allModes.add(i);
      }
      if (['Auto', 'Freeze'].contains(i.description)) {
        lastModes.add(i);
      }
      if (KeyboardDescription.items.contains(i.description)) {
        if (!(i.valuesMapString ?? '').contains('Decrease')) {
          state.allKeyBoardApiInfos.add(i);
        } else {
          decreaseInfos.add(i);
        }
      }
    }
    // 处理所有模式的
    state.allModes.addAll(lastModes);

    /// 处理的第一页的内容 function数据
    for (var i in functionChildren) {
      var descriptionList = i.description.toString().split(':');
      String description = '';
      if (descriptionList.length == 1) {
        description = descriptionList[0];
        i.description = description;
      } else {
        description = descriptionList[1];
      }
      if (FunctionDescription.items.contains(description)) {
        if (i.displayValue != 'Unchecked')
          lastFunctionInfos.add(i);
        else {
          state.allFunctionInfos.add(i);
        }
      }
    }
    state.allFunctionInfos.addAll(lastFunctionInfos);
    // 处理的第一页内容
    state.allKeyBoardApiInfos.addAll(decreaseInfos);

    /// 这部分是参数
    for (ApiInfo i in touchScreenChildren) {
      if (ModesDescription.items.contains(i.description)) {
        state.availableModeInfos.add(i);
      }

      if (i.description == state.currentSelectedMode) {
        for (ApiInfo j in i.children ?? []) {
          // 第二页的数据按照老版本上面的数据判断Toggle或者非左右变化的数据
          if ((j.valuesMapString ?? '').contains('Toggle') ||
              ![0, 2, null].contains(
                  changeValuesMapStringToValuesMap(j.valuesMapString)
                      ?.length)) {
            /// 这部分是第二页的数据
            if ((j.valuesMapString ?? '').contains('Toggle')) {
              state.secondPageInfos.add(j);
            } else {
              state.secondPageSelectInfos.add(j);
            }
          }

          if (changeValuesMapStringToValuesMap(j.valuesMapString)?.length ==
              2) {
            /// 这部分是左右组件的 第三页的数据
            state.thirdPageInfos.add(j);
          }

          /// SGC的显示逻辑 第四页的数据
          if (j.description?.split(':')[0] == 'SGC' &&
              (i.description == 'HAR' || i.description == 'B')) {
            for (ApiInfo m in j.children ?? []) {
              // m.description = 'SGC-${m.description?.split(':')[0]}';
              state.forthPageInfos.add(m);
            }
          }

          /// TGC的显示逻辑 第五页的数据
          if (j.description?.split(':')[0] == 'TGC' &&
              (i.description == 'HAR' || i.description == 'B')) {
            for (ApiInfo m in j.children ?? []) {
              state.fifthPageInfos.add(m);
            }
          }
        }
      }
    }
    if (state.secondPageInfos.length != 0) {
      _totalPage += 1;
    }
    if (state.thirdPageInfos.length != 0) {
      _totalPage += 1;
    }
    if (state.forthPageInfos.length != 0) {
      _totalPage += 1;
    }
    if (state.fifthPageInfos.length != 0) {
      _totalPage += 1;
    }
    state.totalPage = _totalPage;
  }

  // 初始化远程控制器的数据
  void initRemoteControllerData() async {
    try {
      busy = true;
      DeviceControlParameterDataDTO? deviceParameters =
          await rpc.device.getControlParametersAsync(
        GetControlParametersRequest(
          token: Store.user.token,
          deviceCode: state.deviceCode,
        ),
      );
      _initDataState();
      print(deviceParameters.probeApplication);
      state.probeData = jsonDecode(deviceParameters.probeApplication ?? '');
      state.descriptionData = jsonDecode(deviceParameters.parameter ?? '');
      if (state.probeData['Probes'].length == 0) {
        state.isSensorDataAvailable = true;
      }
      _getGsonData();
      busy = false;
    } catch (e) {
      print(e);
      logger.e("getControlParametersAsync error", e);
    }
  }

  void getUltrasoundParameters() {
    remoteControllerManager.applyRemoteControlAsync(
      deviceCode: state.deviceCode,
      controllerType: ControlDeviceParameterEnum.Get,
    );
  }

  /// 获取探头和应用
  Future<void> applyProbeApplicationSettingAsync({
    required ControlDeviceParameterEnum controlType,
    ProbeApplicationSettingInfoDTO? probeApplicationSetting,
  }) async {
    final result = await rpc.device.applyProbeApplicationSettingAsync(
      ProbeApplicationSettingRequest(
        controlType: controlType,
        token: Store.user.token,
        probeApplicationSetting: probeApplicationSetting,
        deviceCode: state.deviceCode,
      ),
    );
    print(result);
  }

  Future<void> referParameters({
    required String pathParameterValue,
    required String argsParameterValue,
    required String loopsParameterValue,
    ControlDeviceParameterEnum controllerType =
        ControlDeviceParameterEnum.RunExecuteApi,
  }) async {
    await remoteControllerManager.applyRemoteControlAsync(
      parameters: [
        AdditionParameterDTO(
          parameterName: 'Path',
          parameterType: 'string',
          parameterValue: pathParameterValue,
        ),
        AdditionParameterDTO(
          parameterName: 'Args',
          parameterType: 'string',
          parameterValue: argsParameterValue,
        ),
        AdditionParameterDTO(
          parameterName: 'Loops',
          parameterType: 'string',
          parameterValue: loopsParameterValue,
        ),
      ],
      deviceCode: state.deviceCode,
      controllerType: controllerType,
    );
  }

  /// 获取所有的探头和应用
  Future<ProbeApplicationSettingInfoDTO>
      getProbeApplicationSettingAsync() async {
    final result = await rpc.device.getProbeApplicationSettingAsync(
      GetControlParametersRequest(
        token: Store.user.token,
        deviceCode: state.deviceCode,
      ),
    );
    return result;
  }

  List<Map<String, String?>>? changeValuesMapStringToValuesMap(
    String? valuesMapString,
  ) {
    List<Map<String, String?>>? valuesMap = [];
    if (valuesMapString.isNullOrEmpty) {
      valuesMap = null;
    } else {
      var maps = valuesMapString?.split(';');
      for (var map in maps!) {
        var mapValue = map.split(':');
        valuesMap.add({mapValue[0]: mapValue[1]});
      }
    }

    return valuesMap;
  }

  @override
  void onClose() {
    liveConsultationManager.onDeviceParametersNotification
        .removeListener(onDeviceParametersNotification);
    super.onClose();
  }

  Future<void> _initParameters() async {
    var parameters = router.getParams(NavIds.HOME) ?? {};
    if (parameters.isEmpty || !parameters.containsKey("deviceCode")) {
      parameters = router.getParams() ?? {};
    }
    if (parameters.isEmpty) {
      parameters = ParameterHelper.parasmeters;
    }
    if (parameters.isNotEmpty) {
      var token = parameters['token'] ?? '';
      if (token.isNotEmpty) {
        Store.user.setToken(token);
      }
      var deviceCode = parameters['deviceCode'] ?? '';

      if (deviceCode.isNotEmpty) {
        var isLiveConsultationController =
            parameters['isLiveConsultationController'] == true.toString();
        var consultationCode = parameters['consultationCode'] ?? '';
        state.isLiveConsultationController = isLiveConsultationController;
        state.deviceCode = deviceCode;
        state.consultationCode = consultationCode;
        final liveInfo = await deviceManager.enterLiveRoom(deviceCode);
        DeviceExtendInfoDTO _dto =
            await deviceManager.getDeviceInfo(deviceCode) ??
                DeviceExtendInfoDTO();
        state.deviceExtendInfoDTO = DeviceStateModel(
          _dto,
          liveInfo: liveInfo,
        );
      }
    }
  }
}
