import 'package:fis_common/event/event_type.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:flyinsono/managers/interfaces/remote_controller.dart';
import 'package:flyinsono/notifications/handlers/remote/connect_status_to_client_notification.dart';
import 'package:flyinsono/notifications/handlers/remote/device_disconnect_remote_control_notification_handler.dart';
import 'package:flyinsono/notifications/handlers/remote/device_download_patch_progress_to_user_notification_handler.dart';
import 'package:flyinsono/notifications/handlers/remote/device_printer_result_notification_handler.dart';
import 'package:flyinsono/notifications/handlers/remote/device_reject_remote_control_notification_handler.dart';
import 'package:flyinsono/notifications/handlers/remote/get_remote_log_to_client_handler.dart';
import 'package:flyinsono/notifications/handlers/remote/probe_application_setting_response_notification_handler.dart';
import 'package:flyinsono/notifications/handlers/remote/send_result_to_client_notification_handler.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';

import 'base_manager.dart';

///  远程控制
class RemoteControllerManager extends BaseManager
    implements IRemoteControllerManager {
  /// 连接通知
  final FEventHandler<ConnectStatusToClientNotification>
      onConnectStatusToClient =
      FEventHandler<ConnectStatusToClientNotification>();

  /// 推送包的进度条通知
  final FEventHandler<DeviceDownloadPatchProgressToUserNotification>
      onDeviceDownloadPatchProgressToUser =
      FEventHandler<DeviceDownloadPatchProgressToUserNotification>();

  /// 获取日志的进度条通知
  final FEventHandler<GetRemoteLogToClientNotification> onGetRemoteLogToClient =
      FEventHandler<GetRemoteLogToClientNotification>();

  /// 设备打印机信息结果通知
  final FEventHandler<DevicePrinterResultNotification> onDevicePrinterResult =
      FEventHandler<DevicePrinterResultNotification>();

  /// 系统设置设备端发送的通知
  final FEventHandler<SendResultToClientNotification> onSendResultToClient =
      FEventHandler<SendResultToClientNotification>();

  /// 设备端断开的通知
  final FEventHandler<DeviceDisconnectRemoteControlNotification>
      onDeviceDisconnectRemote =
      FEventHandler<DeviceDisconnectRemoteControlNotification>();

  /// 设备端通知更新探头和应用
  final FEventHandler<ProbeApplicationSettingResponseNotification>
      onProbeApplicationSettingResponse =
      FEventHandler<ProbeApplicationSettingResponseNotification>();

  /// 设备端未开启远程控制
  final FEventHandler<DeviceRejectRemoteControlNotification>
      onDeviceRejectRemoteControl =
      FEventHandler<DeviceRejectRemoteControlNotification>();

  RemoteControllerManager() {
    var connectStatusToClientNotificationHandler =
        Get.find<ConnectStatusToClientNotificationHandler>();
    var deviceDownloadPatchProgressToUserNotificationHandler =
        Get.find<DeviceDownloadPatchProgressToUserNotificationHandler>();
    var getRemoteLogToClientNotificationHandler =
        Get.find<GetRemoteLogToClientNotificationHandler>();
    var devicePrinterResultNotificationHandler =
        Get.find<DevicePrinterResultNotificationHandler>();
    var sendResultToClientNotificationHandler =
        Get.find<SendResultToClientNotificationHandler>();
    var deviceDisconnectRemoteControlNotificationHandler =
        Get.find<DeviceDisconnectRemoteControlNotificationHandler>();
    var probeApplicationSettingResponseNotificationHandler =
        Get.find<ProbeApplicationSettingResponseNotificationHandler>();
    var deviceRejectRemoteControlNotificationHandler =
        Get.find<DeviceRejectRemoteControlNotificationHandler>();

    connectStatusToClientNotificationHandler
        .subscribe(_onConnectStatusToClient);
    deviceDownloadPatchProgressToUserNotificationHandler
        .subscribe(_onDeviceDownloadPatchProgressToUser);
    getRemoteLogToClientNotificationHandler.subscribe(_onGetRemoteLogToClient);
    devicePrinterResultNotificationHandler.subscribe(_onDevicePrinterResult);
    sendResultToClientNotificationHandler.subscribe(_onsendResultToClient);
    deviceDisconnectRemoteControlNotificationHandler
        .subscribe(_onDeviceDisconnectRemote);
    probeApplicationSettingResponseNotificationHandler
        .subscribe(_onProbeApplicationSettingResponse);
    deviceRejectRemoteControlNotificationHandler
        .subscribe(_onDeviceRejectRemoteControlNotificationHandler);
  }

  void _onConnectStatusToClient(ConnectStatusToClientNotification value) {
    onConnectStatusToClient.emit(this, value);
  }

  void _onDeviceDownloadPatchProgressToUser(
      DeviceDownloadPatchProgressToUserNotification value) {
    onDeviceDownloadPatchProgressToUser.emit(this, value);
  }

  void _onGetRemoteLogToClient(GetRemoteLogToClientNotification value) {
    onGetRemoteLogToClient.emit(this, value);
  }

  void _onDevicePrinterResult(DevicePrinterResultNotification value) {
    onDevicePrinterResult.emit(this, value);
  }

  void _onsendResultToClient(SendResultToClientNotification value) {
    onSendResultToClient.emit(this, value);
  }

  void _onDeviceDisconnectRemote(
      DeviceDisconnectRemoteControlNotification value) {
    onDeviceDisconnectRemote.emit(this, value);
  }

  void _onProbeApplicationSettingResponse(
      ProbeApplicationSettingResponseNotification value) {
    onProbeApplicationSettingResponse.emit(this, value);
  }

  void _onDeviceRejectRemoteControlNotificationHandler(
      DeviceRejectRemoteControlNotification value) {
    onDeviceRejectRemoteControl.emit(this, value);
  }

  /// 申请连接/断开请求
  @override
  Future<bool> applyRemoteConnectionAsync({
    required String deviceCode,
    ControlDeviceParameterEnum? controlType,
    String? roomCode,
  }) async {
    bool result = false;
    try {
      result = await rpc.device.applyRemoteConnectionAsync(
        ControlDeviceConnectRequest(
          token: token,
          deviceCode: deviceCode,
          isNeedSyn: true,
          roomCode: roomCode,
          controlType: controlType ?? ControlDeviceParameterEnum.Start,
        ),
      );
    } catch (e) {
      logger.e('RemoteControllerManager applyRemoteConnectionAsync ex:', e);
    }
    return result;
  }

  ///远程控制请求
  Future<bool> applyRemoteControlAsync({
    List<AdditionParameterDTO>? parameters,
    required String deviceCode,
    ControlDeviceParameterEnum? controllerType,
  }) async {
    return await rpc.device.applyRemoteControlAsync(
      ControlDeviceParameterRequest(
        deviceCode: deviceCode,
        controlType: controllerType ?? ControlDeviceParameterEnum.Start,
        parameters: parameters,
        token: token,
        isNeedSyn: true,
      ),
    );
  }
}
