import 'package:vnote_device_plugin/consts/status.dart';
import 'package:vnote_device_plugin/consts/types.dart';
import 'package:vnote_device_plugin/devices/base.dart';
import 'package:vnote_device_plugin/events/event_type.dart';
import 'package:vnote_device_plugin/models/exams/heart.dart';

/// 心电
class HeartDeviceWorker extends DeviceWorkerBase {
  HeartDeviceWorker({
    required super.model,
    required super.mac,
  }) : super(type: DeviceTypes.HEART);

  @override
  init() {
    super.init();

    injectStatusCallback(
        VDeviceEventStatus.EXAM_HEART_MEASURE_VALUE, _onValueUpdate);
    injectStatusCallback(
        VDeviceEventStatus.EXAM_HEART_CONNECT_ERROR, _onFalloffError);
    injectStatusCallback(
        VDeviceEventStatus.EXAM_HEART_MEASURE_RESULT, _onResult);
    injectStatusCallback(
        VDeviceEventStatus.EXAM_HEART_MEASURE_NOISE, _onNoiseError);
  }

  /// 心率数据更新事件
  final hrValueUpdateEvent = FEventHandler<int>();

  /// ECG数据更新事件
  final ecgValueUpdateEvent = FEventHandler<List<int>>();

  /// 接收结果事件
  final resultReceivedEvent = FEventHandler<HeartExamResult>();

  /// 测量错误事件
  final errorEvent = FEventHandler<String>();

  void _onValueUpdate(Map<String, dynamic>? data) {
    final HeartExamData examData = HeartExamData.fromEventData(data!);
    if (examData.ecgPoints.isNotEmpty) {
      log("Value update; Points size: ${examData.ecgPoints.length}");
      ecgValueUpdateEvent.emit(this, examData.ecgPoints);
    } else if (examData.heartRate > 0) {
      log("Value update; HR: ${examData.heartRate}");
      hrValueUpdateEvent.emit(this, examData.heartRate);
    }
  }

  void _onResult(Map<String, dynamic>? data) {
    final HeartExamResult examData = HeartExamResult.fromEventData(data!);
    log("Result; HR: ${examData.heartRate}, Analysis: ${examData.analysis.join("|")}");
    resultReceivedEvent.emit(this, examData);
  }

  void _onFalloffError(Map<String, dynamic>? data) {
    const String msg = "导联脱落"; // TODO: pick message from data
    log("Falloff: $msg");
    errorEvent.emit(this, msg);
  }

  void _onNoiseError(Map<String, dynamic>? data) {
    const String msg = "EE";
    log("Noise: $msg");
    errorEvent.emit(this, msg);
  }
}
