import 'dart:async';
import 'dart:io';

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/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';

import '../congifs.dart';
import '../rfid/rfid_plugin.dart';

typedef void DiscoveredCallback(args);
typedef void ConnectCallback(args);

class BleService extends GetxService {
  static BleService get to => Get.find();

  late DiscoveredCallback? discoveredCallback;
  late ConnectCallback? connectCallback;

  late BluetoothService selectService;
  late BluetoothCharacteristic _writeCharacteristic;
  late BluetoothCharacteristic _notifyCharacteristic;

  //
  RxList<ScanResult> scanResults = <ScanResult>[].obs;
  RxBool isScanning = false.obs;

  bool isConnect = false;

  late StreamSubscription<List<ScanResult>> _scanResultsSubscription;
  late StreamSubscription<bool> _isScanningSubscription;

  late StreamSubscription<BluetoothConnectionState>
      _connectionStateSubscription;

  late StreamSubscription<List<int>> _lastValueSubscription;
  late StreamSubscription<List<int>> _valueReceivedSubscription;

  Future<BleService> init() async {
    _isScanningSubscription = FlutterBluePlus.isScanning.listen((state) {
      isScanning.value = state;
    });

    _scanResultsSubscription = FlutterBluePlus.scanResults.listen((results) {
      // for (var element in results) {
      //   if (!EmptyUtils.isStrNotEmpty(element.device.platformName)) {
      //     tempList.remove(element);
      //   }
      // }
      scanResults.value = results;
    }, onError: (e) {
      DialogUtils.showToast('扫描错误');
    });
    return this;
  }

  // 切换扫描状态
  Future<void> toggleScan() async {
    // discoveredCallback = callback;
    if (isScanning.value) {
      stopScan();
    } else {
      await scanDevices();
    }
  }

  // 扫描设备
  Future<void> scanDevices() async {
    // 检查权限
    bool permissionsGranted = await requestBlePermissions();
    if (!permissionsGranted) {
      DialogUtils.showToast('请授予所有必要的权限');
      return;
    }
    // 扫描开始时，设置 isScanning 为 true
    isScanning.value = true;

    try {
      // android is slow when asking for all advertisments,
      // so instead we only ask for 1/8 of them
      int divisor = Platform.isAndroid ? 8 : 1;
      await FlutterBluePlus.startScan(
          timeout: const Duration(seconds: 15),
          continuousUpdates: true,
          continuousDivisor: divisor);
    } catch (e) {
      DialogUtils.showToast('扫描错误');
    }

    ///扫描10秒
    Future.delayed(const Duration(seconds: 15), () async {
      FlutterBluePlus.stopScan();
      isScanning.value = false;
      DialogUtils.dismissDialog();
    });
  }

  stopScan() {
    FlutterBluePlus.stopScan();
    isScanning.value = false;
  }

  bool isFirst = false;

  // 连接设备
  Future<void> connectToDevice(int index, ConnectCallback callback) async {
    connectCallback = callback;
    var selectedDevice = scanResults[index].device; // 设置当前选中的设备

    // 在连接设备之前，停止扫描
    await FlutterBluePlus.stopScan();
    isScanning.value = false; // 设置 isScanning 为 false

    DialogUtils.showLoadingDialog('正在连接到 ${selectedDevice.advName}');
    _connectionStateSubscription = selectedDevice.connectionState
        .listen((BluetoothConnectionState state) async {
      if (state == BluetoothConnectionState.disconnected) {
        isConnect = false;
      } else if (state == BluetoothConnectionState.connected) {
        if (Platform.isAndroid) {
          await selectedDevice.requestMtu(512);
        }
        List<BluetoothService> services =
            await selectedDevice.discoverServices();
        services.forEach((service) {

          if (!service.serviceUuid.toString().contains('000180')) {
            selectService = service;

            var characteristics = service.characteristics;
            for (BluetoothCharacteristic c in characteristics) {
              if (c.properties.write) {
                _writeCharacteristic = c;
              }
              if (c.properties.notify) {
                _notifyCharacteristic = c;
                c.setNotifyValue(true);

                _valueReceivedSubscription = c.onValueReceived.listen((value) async {
                  if (value.isNotEmpty) {
                    if (!isFirst) {
                      isFirst = true;
                      getVersion();
                      // RfidPlugin.getVersion().then((value) {
                      //   Config.version=value;
                      //   print('Version: $value');
                      // });
                    }
                  }
                  if (value.isEmpty) return;
                  RfidPlugin.pushRemoteRFIDData(value);
                });
              }
            }
          }
        });

        if (connectCallback != null) {
          connectCallback!('');
        }

        DialogUtils.dismissDialog();
      } else if (state == BluetoothConnectionState.connecting) {
        isConnect = false;
        DialogUtils.showToast('正在连接');
      }
    });

    // 连接设备
    await selectedDevice.connect().catchError((onError) {
      DialogUtils.dismissDialog();
      DialogUtils.showToast('连接设备失败$onError');
    });
  }

  getVersion(){
    RfidPlugin.getVersion();
  }

// 写入数据
  Future<void> writeData(List<int> data) async {
    await _writeCharacteristic.write(data);
  }

  // 检查权限
  Future<bool> requestBlePermissions() async {
    var isLocationGranted = await Permission.locationWhenInUse.request();
    print('checkBlePermissions, isLocationGranted=$isLocationGranted');

    var isBleScanGranted = await Permission.bluetoothScan.request();
    print('checkBlePermissions, isBleScanGranted=$isBleScanGranted');
    //
    var isBleConnectGranted = await Permission.bluetoothConnect.request();
    print('checkBlePermissions, isBleConnectGranted=$isBleConnectGranted');
    //
    var isBleAdvertiseGranted = await Permission.bluetoothAdvertise.request();
    print('checkBlePermissions, isBleAdvertiseGranted=$isBleAdvertiseGranted');

    return isLocationGranted == PermissionStatus.granted &&
        isBleScanGranted == PermissionStatus.granted &&
        isBleConnectGranted == PermissionStatus.granted &&
        isBleAdvertiseGranted == PermissionStatus.granted;
  }

  dipose() {
    _isScanningSubscription.cancel();
    _scanResultsSubscription.cancel();
  }
}
