//
//  JXBleManager.h
//  JXPrinter
//
//  Created by 贾俊伟 on 2021/3/26.
//

#import <Foundation/Foundation.h>
#import <CoreBluetooth/CoreBluetooth.h>
#import "JXPrinterEnums.h"

@class JXBleManager, JXPrinterInfo;

#define SERVICE_UUID @"49535343-FE7D-4AE5-8FA9-9FAFD205E455"
// 提供只写的特征
#define WRITE_CHAR_UUID @"49535343-8841-43F4-A8D4-ECBE34729BB3"
// 提供通知的特征
#define NOTIFI_CHAR_UUID @"49535343-1E4D-4BD9-BA61-23C647249616"

NS_ASSUME_NONNULL_BEGIN

@protocol JXBleManagerDelegate <NSObject>

@optional

/**
 * 手机蓝牙状态更新
 * @param central 中心设备对象
 */
- (void)manager:(JXBleManager *)manager centralManagerDidUpdateState:(CBCentralManager *)central;

/**
 * 发现蓝牙打印机
 * @param manager JXBleManager
 * @param peripheral 已发现的蓝牙打印机对象
 * @param advertisementData advertisementData
 * @param RSSI RSSI
 * @param address MAC地址 可能为空字符串
 */
- (void)manager:(JXBleManager *)manager didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI address:(NSString *)address;

/**
 * 扫描超时
 */
- (void)scanTimeout:(JXBleManager *)manager;

/**
 * 已成功连接打印机
 */
- (void)manager:(JXBleManager *)manager didConnectPeripheral:(CBPeripheral *)peripheral;

/**
 * 已断开打印机
 */
- (void)manager:(JXBleManager *)manager didDisconnectPeripheral:(CBPeripheral *)peripheral;

/**
 * 连接打印机失败
 */
- (void)didFailToConnectPeripheral;

@end

@interface JXBleManager : NSObject<CBCentralManagerDelegate, CBPeripheralDelegate>

// 扫描到的外设数组
@property (nonatomic, strong) NSMutableArray<CBPeripheral *> *peripherals;
@property (nonatomic, strong) CBCentralManager *centralManager;
@property (nonatomic,   weak) id<JXBleManagerDelegate> delegate;
@property (nonatomic, strong, nullable) CBPeripheral *connectedPeripheral;
@property (nonatomic, strong, nullable) CBCharacteristic *characteristic;
@property (nonatomic, strong, nullable) CBCharacteristic *notifiCharacteristic;
// 使用MTU(默认NO) 按[peripheral maximumWriteValueLengthForType:CBCharacteristicWriteWithoutResponse]的值分包发送数据
@property (assign, nonatomic) BOOL useMTU;
// 设置MTU大小 默认[peripheral maximumWriteValueLengthForType:CBCharacteristicWriteWithoutResponse]
@property (nonatomic, assign) NSInteger MTU;
// 是否过滤没有名字的外设(默认为YES)
@property (assign, nonatomic) BOOL filter;
// 写入数据是否需要有响应，对应CBCharacteristicWriteType的设置。默认值为NO,即有响应
@property (nonatomic, assign) BOOL writeWithoutResponse;

/**
 * 获取蓝牙设备管理单例对象
 * @return instancetype：蓝牙设备管理单例对象
 */
+ (instancetype)bleManager;

// 设置日志输出状态
+ (void)setLogEnable:(BOOL)enable;

/// 可自定义设置uuid
- (void)setDeviceUUIDs:(NSString *)serviceId writeCharacteristicUUID:(NSString *)writeCharId notifyCharacteristicUUID:(NSString *)notifyCharId;

/**
 * 停止扫描
 */
- (void)stopScan;

/**
 * 开始扫描蓝牙设备
 * @param timeout 扫描超时时间
 * @param failure error
 */
- (void)scanPeripheralsWithTimeout:(NSTimeInterval)timeout
                           failure:(nullable void (^)(NSError *error))failure;

/**
 * 开始扫描蓝牙设备
 * @param services 一个CBUUID对象的数组，表示要扫描的服务。
 * @param options  指定扫描选项的可选字典
 * @param timeout  扫描超时时间
 * @param failure  error
 */
- (void)scanPeripheralsWithWithServices:(nullable NSArray<CBUUID *> *)services
                                options:(nullable NSDictionary<NSString *, id> *)options
                                timeout:(NSTimeInterval)timeout
                                failure:(nullable void (^)(NSError *error))failure;

/**
 * 连接蓝牙设备（默认设置60s超时）
 * @param peripheral 蓝牙设备对象
 */
- (void)connectPeripheral:(CBPeripheral *)peripheral;

/**
 * 连接蓝牙设备
 * @param peripheral 蓝牙设备对象
 * @param timeout 超时时间
 */
- (void)connectPeripheral:(CBPeripheral *)peripheral
                  timeout:(NSTimeInterval)timeout;

/**
 * 断开蓝牙连接
 * @param peripheral 蓝牙设备对象
 */
- (void)disconnectPeripheral:(CBPeripheral *)peripheral;

/**
 * 判断是否连接蓝牙打印机
 * @return YES：已经连接   NO：未连接
 */
- (BOOL)isConnectBle;

/**
 * 向蓝牙设备写入二进制数据，自动进行分段发送
 * @param data       要发送的二进制数据
 */
- (void)writeData:(NSData *)data;

/**
 * 写入有返回数据的指令(返回打印机的回复结果，超时返回nil)
 * @param data 要发送的二进制数据
 * @param timeout 查询结果超时时间（s）
 */
- (NSData *)writeWithResponseData:(NSData *)data timeout:(NSInteger)timeout;

/**
 * 清除读取Buffer
 */
- (void)flushReadBuffer;

/**
 * 写入二进制命令(有返回数据的指令)
 * @param cmd 命令缓冲区地址
 * @param length 命令长度
 */
- (NSData *)writeWithResponseCmd:(Byte *)cmd cmdLenth:(NSUInteger)length;

/**
 * 写入二进制命令(有返回数据的指令)
 * @param cmd 命令缓冲区地址
 * @param length 命令长度
 * @param timeout 查询结果超时时间（s）
 */
- (NSData *)writeWithResponseCmd:(Byte *)cmd cmdLenth:(NSUInteger)length timeout:(NSInteger)timeout;

/**
 * 写入二进制命令(有返回数据的指令)
 * @param data 要发送的二进制数据
 * @param response 返回数据
 */
- (void)writeWithResponseData:(NSData *)data response:(void (^)(NSData *data))response;

/**
 * 向外围设备写入字符串信息，自动进行分段发送
 * @param message       要发送的字符串信息
 */
- (void)writeText:(NSString *)message;

/**
 * 向外围设备写入字符串信息，自动进行分段发送
 * @param peripheral 蓝牙设备对象
 * @param message       要发送的字符串信息
 */
- (void)writeToPeripheral:(CBPeripheral *)peripheral message:(NSString *)message;

/**
 * 读取蓝牙打印机状态
 * @param timeout 超时时间
 * @param success 成功回调
 * @param fail    超时时间到,失败回调
 */
- (void)readBlePrintStatus:(NSTimeInterval)timeout
                   success:(void (^)(PrintStatus blePrintStatus))success
                      fail:(void (^)(void))fail;

/**
 * 读取蓝牙打印机宽高和支持指令信息
 */
- (JXPrinterInfo *)requestBlePrinterInfo;

@end

NS_ASSUME_NONNULL_END
