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 '../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) {
      List<ScanResult> tempList = List.from(results);
      for (var element in tempList) {
        if (!EmptyUtils.isStrNotEmpty(element.device.platformName)) {
          tempList.remove(element);
        }
      }
      scanResults.value = tempList;
    }, 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;
  }

  // 连接设备
  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;
        if (kDebugMode) {
          print("${selectedDevice.disconnectReason!.code} ${selectedDevice.disconnectReason!.description}");
        }
      } else if (state == BluetoothConnectionState.connected) {
        if (Platform.isAndroid) {
          await selectedDevice.requestMtu(512);
        }
        List<BluetoothService> services = await selectedDevice.discoverServices();
        services.forEach((service) {
          //打印所有服务的 uuid
          if (kDebugMode) {
            print('service uuid: ${service.uuid}');
          }
          if (!service.serviceUuid.toString().contains('000180')) {
            selectService = service;
            //打印 service uuid
            if (kDebugMode) {
              print('service 000180  uuid: ${service.uuid}');
            }
            var characteristics = service.characteristics;
            for (BluetoothCharacteristic c in characteristics) {
              if (c.properties.write) {
                //打印写的特征值 uuid
                if (kDebugMode) {
                  print('write characteristic uuid: ${c.uuid}');
                }
                _writeCharacteristic = c;
              }
              if (c.properties.notify) {
                //打印通知的特征值 uuid
                if (kDebugMode) {
                  print('notify characteristic uuid: ${c.uuid}');
                }
                _notifyCharacteristic = c;
                c.setNotifyValue(true);

                // _lastValueSubscription = c.lastValueStream.listen((value) {
                //   print(value);
                // });
                _valueReceivedSubscription = c.onValueReceived.listen((value) {
                  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');
    });
  }

// 写入数据
  Future<void> writeData(List<int> data) async {
    // if (selectedDevice == null) {
    //   throw Exception('No device connected');
    // }

    await _writeCharacteristic.write(data, allowLongWrite: true);
  }

  // 检查权限
  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();
  }
}
