import 'dart:collection';
import 'dart:convert';
import 'dart:math';

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

import 'defines.dart';

/// 设备事件监听器
class DeviceEventListener {
  late final String _uniqueKey;

  /// 唯一建
  String get uniqueKey => _uniqueKey;

  /// 接受的状态集合
  ///
  /// - null 表示接受所有状态
  ///
  /// - [] 表示不接受任何状态
  final List<int>? accpetStatusList;

  /// 回调函数
  final DeviceEventCallback callback;

  DeviceEventListener({
    this.accpetStatusList,
    required this.callback,
  }) {
    _uniqueKey = _generateUniqueId(this);
  }

  static String _generateUniqueId(DeviceEventListener obj) {
    final suffix = Random().nextInt(1000).toString().padLeft(3, '0');
    final prefix = obj.hashCode;
    final ms = DateTime.now().millisecond;
    return "${prefix}_${ms}_$suffix";
  }
}

/// 设备事件中心
class DeviceEventCenter {
  DeviceEventCenter._();

  static final DeviceEventCenter instance = DeviceEventCenter._();

  final _listenerMap = <String, DeviceEventListener>{};
  bool _busy = false;

  /// 添加监听
  void addListener(DeviceEventListener listener) {
    // if (_busy) {
    //   Future.delayed(const Duration(milliseconds: 10), () {
    //     addListener(listener);
    //   });
    // } else {
    //   _listenerMap[listener.uniqueKey] = listener;
    // }
    _listenerMap[listener.uniqueKey] = listener;
  }

  /// 移除监听
  void removeListener(DeviceEventListener listener) {
    // if (_busy) {
    //   Future.delayed(const Duration(milliseconds: 10), () {
    //     removeListener(listener);
    //   });
    // } else {
    //   _listenerMap.remove(listener.uniqueKey);
    // }
    _listenerMap.remove(listener.uniqueKey);
  }

  /// 通知事件
  void emit(String jsonText) {
    LogUtil.write("@EVENT Received! $jsonText");
    final res = jsonDecode(jsonText);
    final int status = res["STATUS"];
    final dynamic data = res["DATA"];
    _distributeEvent(status, data);
  }

  void _distributeEvent(int status, Map<String, dynamic>? data) {
    _busy = true;
    final keys = _listenerMap.keys.toList();
    final copyKeys = List<String>.generate(keys.length, (index) => keys[index]);
    for (final key in copyKeys) {
      final listener = _listenerMap[key];
      if (listener == null) continue;

      if (listener.accpetStatusList == null) {
        listener.callback.call(status, data);
        continue;
      }

      if (listener.accpetStatusList!.isEmpty) {
        // 不处理
        continue;
      }

      if (listener.accpetStatusList!.contains(status)) {
        listener.callback.call(status, data);
      }
    }
    _busy = false;
  }
}
