import 'dart:async';
import 'dart:isolate';
import 'dart:ui';

import 'package:anchor_collect_flutter/congifs.dart';
import 'package:anchor_collect_flutter/utils/dialog_utils.dart';
import 'package:anchor_collect_flutter/utils/empty_utils.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:isar/isar.dart';

import '../controllers/ble_service.dart';

typedef void EventCallback(args, args2);

// 这个SendPort是前面主线程的
createNewIsolateContext(SendPort sendPort) async {
  print("子线程开始");

  /// 子线程的ReceivePort创建
  ReceivePort subThreadPort = ReceivePort();

  /// 这是把子线程的ReceivePort的sendPort给了主线程 用于通信
  sendPort.send(subThreadPort.sendPort);

  subThreadPort.listen((message) async {
    print("子线程收到的消息 $message");
    if (message is String) {
      /// 收到主线程让关闭接口的消息 就关闭 正确的话后面是在接受不到消息了
      if (message == "close receiveport") {
        sendPort.send('closed');
        subThreadPort.close();
      }
    } else if (message is List<int>) {
      print('message is List<int>');
      await BleService.to.writeData(message);
    }
  });

  ///

  //第4步: 注意callback这个函数执行环境就会变为newIsolate, 所以创建的是一个newIsolateReceivePort
  // ReceivePort newIsolateReceivePort = ReceivePort();
  // //第5步: 获取newIsolateSendPort, 有人可能疑问这里为啥不是直接让全局newIsolateSendPort赋值，注意这里执行环境不是rootIsolate
  // SendPort newIsolateSendPort = newIsolateReceivePort.sendPort;
  // //第6步: 特别需要注意这里，这里是利用rootIsolateSendPort向rootIsolate发送消息，只不过发送消息是newIsolate的SendPort, 这样rootIsolate就能拿到newIsolate的SendPort
  // rootIsolateSendPort.send(['connect success from new isolate', newIsolateSendPort]);
}

class RfidPlugin {
  static const MethodChannel _methodChannel = MethodChannel('flutter_rfid_plugin');

  static const EventChannel _eventChannel = EventChannel('flutter_rfid_plugin/event');

  static EventCallback? scanCallback, connectCallback, inventoryCallback;

  late StreamSubscription<dynamic> _streamSubscription;

  static String rfidTagTemp = '';
  static bool isInventory = false;

  late Isolate _isolat;
  late ReceivePort rootIsolateReceivePort;

  ///子线程
  late SendPort newIsolateSendPort;

  ///主线程
  late SendPort rootIsolateSendPort;

  RfidPlugin() {
    // establishConn();
    _streamSubscription = _eventChannel.receiveBroadcastStream().listen((event) async {
      if (kDebugMode) {
        print('event:${event.toString()}');
      }
      if (event is String) {
      } else if (event is Map<dynamic, dynamic>) {
        final Map<dynamic, dynamic> map = event;

        switch (map['key']) {
          case 'DISCONNECTED':
            Config.isConnect = false;
            RfidPlugin.isInventory = false;
            stopInventory();
            DialogUtils.showToast('蓝牙已断开');
            break;
          case 'Device':
            ///返回扫描的设备名
            if (map['value'] != null) {
              String bluetoothName = map['value'];
              if (kDebugMode) {
                print('Received Device name: $bluetoothName');
              }
              if (scanCallback != null) {
                scanCallback!(bluetoothName, '');
              } else {
                DialogUtils.showToast('缺少扫描设备回调');
              }
              // rootIsolateSendPort.send(bluetoothData);
              // await BleService.to.writeData(bluetoothData);
            }
            break;
          case 'InventoryData':
            print('why:InventoryData:${map['value']}');
            if (inventoryCallback != null) {
            print('why:inventoryCallback');
              inventoryCallback!(map['value'], '');
            } else {
              DialogUtils.showToast('缺少盘点回调');
            }
            break;
          case 'get_version':
            if (map['get_version_status'] == '0') {
              // map['value_RM70XX_VERSION'];
              // map['value_RM70XX_SERIAL_VERSION'];
              // map['value_VERSION'];
              if(map['value_SERIAL_VERSION']=='-2'){
                Config.isConnect = false;
                DialogUtils.showToast('蓝牙连接失败');
              }else{
                if(connectCallback!=null) {
                  connectCallback!('','');
                }
              }

            } else {
              DialogUtils.showWarningDialog('连接蓝牙失败');
            }
            break;
        }
      }
    }, onError: errorEventListen, onDone: doneEventListen);
  }

  //特别需要注意:establishConn执行环境是rootIsolate
  void establishConn() async {
    //第1步: 默认执行环境下是rootIsolate，所以创建的是一个rootIsolateReceivePort
    rootIsolateReceivePort = ReceivePort();
    //第2步: 获取rootIsolateSendPort
    rootIsolateSendPort = rootIsolateReceivePort.sendPort;

    // 注册rootIsolateSendPort
    IsolateNameServer.registerPortWithName(rootIsolateSendPort, 'rootIsolateSendPort');
    //第3步: 创建一个newIsolate实例，并把rootIsolateSendPort作为参数传入到newIsolate中，为的是让newIsolate中持有rootIsolateSendPort, 这样在newIsolate中就能向rootIsolate发送消息了
    //注意createNewIsolateContext这个函数执行环境就会变为newIsolate, rootIsolateSendPort就是createNewIsolateContext回调函数的参数
    _isolat = await Isolate.spawn(createNewIsolateContext, rootIsolateSendPort);
    rootIsolateReceivePort.listen((message) {
      if (kDebugMode) {
        print("主线程收到的消息 $message");
      }
      if (message is SendPort) {
        newIsolateSendPort = message;
      } else if (message is List<int>) {
        newIsolateSendPort.send(message);
      }
    });
    //第7步: 通过rootIsolateReceivePort接收到来自newIsolate的消息，所以可以注意到这里是await 因为是异步消息
    //只不过这个接收到的消息是newIsolateSendPort, 最后赋值给全局newIsolateSendPort，这样rootIsolate就持有newIsolate的SendPort
    // var messageList = await rootIsolateReceivePort.first;
    // //第8步，建立连接成功
    // print(messageList[0] as String);
    // newIsolateSendPort = messageList[1] as SendPort;
  }

  static Future<void> initRfid() async {
    await _methodChannel.invokeMethod('init_rfid');
  }

  static Future<String> getVersion() async {
    String version = await _methodChannel.invokeMethod('get_version');
    return version;
  }

  static startScanDevice(EventCallback callback) async {
    scanCallback = callback;
    await _methodChannel.invokeMethod('scan_device');
  }

  static stopScanDevice() async {
    await _methodChannel.invokeMethod('scan_stop');
  }

  static connectDevice(String deviceName, EventCallback callback) async {
    connectCallback = callback;
    Map params = {
      "name": deviceName,
    };
    await _methodChannel.invokeMethod('connect_device', params);
  }

  static disConnectDevice() async {
    await _methodChannel.invokeMethod('disconnect_device');
  }

  static startInventory(EventCallback callback) async {
    print('why:开始盘点');
    inventoryCallback = callback;
    isInventory = true;
    await _methodChannel.invokeMethod('start_inventory');
  }

  static stopInventory() async {
    await _methodChannel.invokeMethod('stop_inventory');
  }

  static Future<void> pushRemoteRFIDData(List<int> readData) async {
    // List<int> readData = await BleService.to.readData();
    Map params = {
      "value": Uint8List.fromList(readData),
    };
    await _methodChannel.invokeMethod('push_data', params);
  }

  errorEventListen(Object obj) {
    final Object e = obj;
    if (kDebugMode) {
      print("错误打印为------$obj");
    }
    throw e;
  }

  doneEventListen() {
    if (kDebugMode) {
      print("flutter响应完成------");
    }
  }

  checkInventory(String rfidTag) {
    if (!EmptyUtils.isStrNotEmpty(rfidTagTemp)) {
      rfidTagTemp = rfidTag;
      List<String> rfids = rfidTag.split(',');
      inventoryCallback!(rfids[0] ?? "", rfids[1] ?? "");
    }
  }
}
