import 'dart:async';

import 'package:vnote_device_plugin/events/event_type.dart';
import 'package:vnote_device_plugin/utils/logger.dart';

import '../consts/status.dart';
import '../events/defines.dart';
import '../events/event_center.dart';
import '../models/device.dart';
import '../vnote_device_plugin_platform_interface.dart';

/// 设备搜寻器
class DeviceSearcher {
  /// 设备类型
  final String type;

  /// 搜索失败事件
  final failEvent = FEventHandler<String?>();

  /// 搜索成功事件
  final successEvent = FEventHandler<DeviceInfo>();

  /// 搜索超时事件
  final timeoutEvent = FEventHandler<void>();

  late final _listener = DeviceEventListener(
    accpetStatusList: [
      VDeviceEventStatus.DEVICE_SEARCH_START,
      VDeviceEventStatus.DEVICE_SEARCH_STOP,
      VDeviceEventStatus.BLE_DEVICE_FOUND,
      VDeviceEventStatus.BLE_DEVICE_NOT_FOUND,
    ],
    callback: _onEventCallback,
  );

  final _statusHandlers = <int, DeviceEventStatusCallback>{};

  bool _busy = false;

  Completer<void>? _startCompleter;
  Completer<void>? _stopCompleter;

  DeviceSearcher(this.type) {
    _initCallbackMap();
  }

  void init() {
    _log("Init");
    DeviceEventCenter.instance.addListener(_listener);
  }

  void dispose() {
    _log("Dispose");
    DeviceEventCenter.instance.removeListener(_listener);
  }

  Future<void> start() async {
    _busy = true;

    _startCompleter = Completer<void>();

    _log("Start");

    /// 12导心电需要特殊搜索
    if (type == "twelveheart") {
      await VnoteDevicePluginPlatform.instance.callAction(
        "SEARCH_START_BT",
        {"TYPE": type},
      );
    } else {
      await VnoteDevicePluginPlatform.instance.callAction(
        "SEARCH_START",
        {"TYPE": type},
      );
    }

    await _startCompleter!.future;
    _startCompleter = null;
  }

  Future<void> stop() async {
    _stopCompleter = Completer<void>();

    _log("Stop");

    await VnoteDevicePluginPlatform.instance.callAction(
      "SEARCH_STOP",
      {"TYPE": type},
    );
    await _stopCompleter!.future;
    _stopCompleter = null;

    _busy = false;
  }

  void _onEventCallback(int status, Map<String, dynamic>? e) {
    final callback = _statusHandlers[status];
    callback?.call(e);
  }

  void _initCallbackMap() {
    _statusHandlers[VDeviceEventStatus.DEVICE_SEARCH_START] = _onStartCallback;
    _statusHandlers[VDeviceEventStatus.DEVICE_SEARCH_STOP] = _onStopCallback;
    _statusHandlers[VDeviceEventStatus.BLE_DEVICE_FOUND] = _onFoundCallback;
    _statusHandlers[VDeviceEventStatus.BLE_DEVICE_NOT_FOUND] =
        _onNotFoundCallback;
  }

  void _onStartCallback(Map<String, dynamic>? data) {
    _log("Start callback");
    _startCompleter?.complete();
  }

  void _onTimeoutCallback() {
    _log("Timeout callback");
    _busy = false;
    timeoutEvent.emit(this, null);
  }

  void _onStopCallback(Map<String, dynamic>? data) {
    _log("Stop callback");
    if (_stopCompleter == null) {
      // 搜索超时
      if (_busy) {
        _onTimeoutCallback();
      }
    } else {
      // 主动停止搜索完成
      _stopCompleter?.complete();
    }
  }

  void _onFoundCallback(Map<String, dynamic>? data) {
    _log("Found");
    _busy = false;
    //  {"STATUS":104,"DATA":{"BLE_NAME":"IR Thermo","BLE_PRODUCT_NAME":"体温计(家测宝)","MAC":"44:A6:E5:16:62:33","MODEL":"DT-8836","TYPE":"temp"}}
    if (data != null) {
      final device = DeviceInfo.fromEventData(data);
      _log(
          "BleName: ${device.bleName}, ProductName: ${device.productName}, Model: ${device.model}, Mac: ${device.mac}");
      successEvent.emit(this, device);
    }
  }

  void _onNotFoundCallback(Map<String, dynamic>? data) {
    final message = data?["MSG"] ?? "ERROR";
    _log("Error: $message");
    failEvent.emit(this, message); // TODO:
  }

  void _log(String content) {
    LogUtil.write("DeviceSearcher[$type] $content.");
  }
}
