//
//  RNSprtModule.m
//  qm-hardwarekit
//
//  Created by 夏迎霖 on 2017/11/30.
//  Copyright © 2017年 Marc Shilling. All rights reserved.
//

#import "RNSprtModule.h"

extern BabyBluetooth *baby;

//for issc
static NSString *const kWriteCharacteristicUUID_cj = @"49535343-8841-43F4-A8D4-ECBE34729BB3";
static NSString *const kReadCharacteristicUUID_cj = @"49535343-1E4D-4BD9-BA61-23C647249616";
static NSString *const kServiceUUID_cj = @"49535343-FE7D-4AE5-8FA9-9FAFD205E455";

// Properties是特征的属性，可以看出FF01具有读的权限，FF02具有读写的权限。特征拥有的权限类别有如下几种：
static NSString *const kFlowControlCharacteristicUUID = @"ff03";
static NSString *const kWriteCharacteristicUUID = @"ff02";
static NSString *const kReadCharacteristicUUID = @"ff01";
static NSString *const kServiceUUID = @"ff00";


#define FOUNDED @"Bluetooth.device.founded"
#define DISCOUNT @"Bluetooth.discount"
#define OFF @"Bluetooth.off"
#define OVER @"Bluetooth.discovery.over"
#define BONDED  @"Bluetooth.device.bonded"


@implementation RNSprtModule




// 连接蓝牙设备
RCT_REMAP_METHOD(connect,
                 address: (NSString*)address
                 resolver: (RCTPromiseResolveBlock)resolve
                 reject: (RCTPromiseRejectBlock)reject){
    if(nil == baby) return;
    [self babyDelegate];
    CBPeripheral* per = [baby retrievePeripheralWithUUIDString:address];
    if(per) {
        [baby cancelPeripheralConnection: per];
        [baby setFilterOnConnectToPeripherals:^BOOL(NSString *peripheralName, NSDictionary *advertisementData, NSNumber *RSSI) {
            NSLog(@"%@ --------------------------- %@",peripheralName, @([peripheralName hasPrefix:@"POS"]));
            return [peripheralName hasPrefix:@"POS"];
        }];
    }
    
    //2 扫描、连接
    [baby
     setBlockOnDiscoverToPeripherals:^(CBCentralManager *central, CBPeripheral *peripheral, NSDictionary *advertisementData, NSNumber *RSSI) {
         if([address isEqualToString:[peripheral.identifier UUIDString]]) {
             baby
             .having(peripheral)
             .connectToPeripherals()
             .discoverServices()
             .discoverCharacteristics()
             .readValueForCharacteristic()
             .discoverDescriptorsForCharacteristic()
             .readValueForDescriptors()
             .begin();
             
             [baby AutoReconnect:peripheral];
             return;
         }
     }];
    baby
    .scanForPeripherals()
    .begin();
    
    [self Time];
    resolve(@{@"value" : @(true)});
    //    }
}

// 断开连接
RCT_EXPORT_METHOD(disconnect:(NSString *)address){
    [baby cancelScan];
    if(nil != baby) {
        NSArray* array = [baby findConnectedPeripherals];
        if(0 == [array count]){
            NSMutableDictionary *dic = [NSMutableDictionary dictionary];
            [dic setObject:address forKey:@"address"];
            [dic setObject:@(0) forKey:@"bondState"];
            CBPeripheral* per = [baby retrievePeripheralWithUUIDString:address];
            [baby AutoReconnectCancel:per];
            [[NSNotificationCenter defaultCenter] postNotificationName:DISCOUNT object: [self to:per]];
        }
        for (int i = 0; i < array.count; ++i) {
            CBPeripheral* peripheral = array[i];
            if([address isEqualToString: [peripheral.identifier UUIDString]]){
                [baby cancelPeripheralConnection: peripheral];
                [baby AutoReconnectCancel: peripheral];
                NSLog(@"%@ 执行断开连接", peripheral.name);
            }
        }
    } else {
        NSLog(@"id=%@ 执行断开失败[未找到连接的对象]", address);
    }
}


// 文本内容居中
RCT_EXPORT_METHOD(printAlignCenter){
    [SPRTPrint printAlignCenter];
}


// 文本内容左对齐
RCT_EXPORT_METHOD(printAlignLeft){
    [SPRTPrint printAlignLeft];
}

// 文本标题字体
RCT_EXPORT_METHOD(fontTitle){
    [SPRTPrint setAsciiWordFormat:0 bold:YES doubleHeight:YES doubleWidth:YES underline:NO];
}



// 文本内容字体
RCT_EXPORT_METHOD(fontContent){
    [SPRTPrint setAsciiWordFormat:0 bold:NO doubleHeight:NO doubleWidth:NO underline:NO];
}


// 文本内容右对齐
RCT_EXPORT_METHOD(printAlignRight){
    [SPRTPrint printAlignRight];
}

RCT_EXPORT_METHOD(printlnText:(NSString *)text){
    [SPRTPrint printTxt:[text stringByAppendingString: @"\n"]];
}

RCT_EXPORT_METHOD(printText:(NSString *)text){
    [SPRTPrint printTxt:text];
}

RCT_EXPORT_METHOD(printQrCode:(NSString *)text) {
    [SPRTPrint drawQrCode:5 startY:5 textStr:text roateNum:0 verNum:3 lelNum:10];
}

RCT_EXPORT_METHOD(lineWrap:(NSInteger) number) {
    for (NSInteger index = number; index >= 0 ; --index) {
        [SPRTPrint printTxt: @"\n"];
    }
}

RCT_EXPORT_METHOD(lineSplit) {
    [SPRTPrint printTxt: @"--------------------------------\n"];
}

-(void)babyDelegate{
    [baby setBabyOptionsWithScanForPeripheralsWithOptions:nil
                             connectPeripheralWithOptions:@{CBConnectPeripheralOptionNotifyOnConnectionKey : @YES, CBConnectPeripheralOptionNotifyOnDisconnectionKey: @YES}
                           scanForPeripheralsWithServices:nil
                                     discoverWithServices:@[kServiceUUID_cj,kServiceUUID]
                              discoverWithCharacteristics:@[kWriteCharacteristicUUID,kReadCharacteristicUUID,kFlowControlCharacteristicUUID,kWriteCharacteristicUUID_cj, kReadCharacteristicUUID_cj]];
    
    
    [baby setBlockOnReadValueForCharacteristic:^(CBPeripheral *peripheral, CBCharacteristic *characteristic, NSError *error) {
        NSLog(@"enter didUpdateValueForCharacteristic!");
        NSData *data = characteristic.value;
        NSLog(@"read data=%@!",data);
        
        if (error==nil) {
            //调用下面的方法后 会调用到代理的- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
            [peripheral readValueForCharacteristic:characteristic];
        }
        
        if (characteristic == activeFlowControlCharacteristic) {
            NSData * data = [characteristic value];
            NSUInteger len = [data length];
            int bytesRead = 0;
            if (len > 0) {
                unsigned char * measureData = (unsigned char *) [data bytes];
                unsigned char field = * measureData;
                measureData++;
                bytesRead++;
                if(field == 2){
                    unsigned char low  = * measureData;
                    measureData++;
                    mtu =  low + (* measureData << 8);
                }
                if(field == 1){
                    if(credit < 5) {
                        credit += * measureData;
                    }
                }
            }
        }
    }];
    
    
    //设置设备连接成功的委托,同一个baby对象，使用不同的channel切换委托回调
    [baby setBlockOnConnected:^(CBCentralManager *central, CBPeripheral *peripheral) {
        NSLog(@"设备：%@--连接成功",peripheral.name);
        [peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID]]];
        [peripheral discoverServices:@[[CBUUID UUIDWithString:kServiceUUID_cj]]];
        NSMutableDictionary* dic = [self to: peripheral];
        [[NSNotificationCenter defaultCenter] postNotificationName:BONDED object:dic];
        
        //设置已经匹配成功的设备
        NSUserDefaults* ud = [NSUserDefaults standardUserDefaults];
        NSArray* array = [ud objectForKey:BONDED];
        if(array) {
            NSMutableArray* t = [array mutableCopy];
            if ([array containsObject: dic] == NO){
                [t addObject:dic];
            }
            array = [t copy];
        } else {
            array = @[[self to: peripheral]];
        }
        [ud setObject:array forKey:BONDED];
        [ud synchronize];
        //        [baby cancelScan];
    }];
    
    
    
    [baby setBlockOnDiscoverServices:^(CBPeripheral *peripheral, NSError *error) {
        //在这个方法中我们要查找到我们需要的服务  然后调用discoverCharacteristics方法查找我们需要的特性
        //该discoverCharacteristics方法调用完后会调用代理CBPeripheralDelegate的
        for (CBService *service in peripheral.services) {
            if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID]]) {
                cjFlag=0;
                [peripheral discoverCharacteristics:nil forService:service];
            }
            else if ([service.UUID isEqual:[CBUUID UUIDWithString:kServiceUUID_cj]]) {
                cjFlag=1;
                [peripheral discoverCharacteristics:nil forService:service];
            }
        }
    }];
    
    //设置发现设service的Characteristics的委托
    [baby setBlockOnDiscoverCharacteristics :^(CBPeripheral *peripheral, CBService *service, NSError *error) {
        NSLog(@"===service name:%@",service.UUID);
        if (error==nil) {
            
            //在这个方法中我们要找到我们所需的服务的特性 然后调用setNotifyValue方法告知我们要监测这个服务特性的状态变化
            //当setNotifyValue方法调用后调用代理CBPeripheralDelegate的- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
            //有时读写的操作是由一个characteristic完成
            for (CBCharacteristic *characteristic in service.characteristics) {
                if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kWriteCharacteristicUUID]]) {
                    [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                    activeWriteCharacteristic = characteristic;
                } else {
                    if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kReadCharacteristicUUID]]){
                        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                        activeReadCharacteristic = characteristic;
                    }else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kFlowControlCharacteristicUUID]]) {
                        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                        activeFlowControlCharacteristic = characteristic;
                        credit = 0;
                        response = 1;
                    }else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kWriteCharacteristicUUID_cj]]) {
                        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                        activeWriteCharacteristic = characteristic;
                    }else if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kReadCharacteristicUUID_cj]]) {
                        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
                        activeReadCharacteristic = characteristic;
                    }
                }
                activeDevice = peripheral;
            }
            
            
        }
    }];
}





- (void)Time{
    __block int timeOut = 10;
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
    
    dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
    
    dispatch_source_set_event_handler(_timer, ^{
        if(timeOut < 0){ //倒计时结束，关闭
            dispatch_source_cancel(_timer);
            dispatch_async(dispatch_get_main_queue(), ^{
                //设置界面的按钮显示 根据自己需求设置
                [baby cancelScan];
            });
        }else{
            //            int seconds = timeOut % 60;
            timeOut--;
        }
    });
    dispatch_resume(_timer);
}



-(NSMutableDictionary*) to: (CBPeripheral*) peripheral {
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setObject:[NSString stringWithFormat:@"%@",[peripheral.identifier UUIDString]] forKey:@"address"];
    
    
    [dic setObject:peripheral.name ?peripheral.name : @"--" forKey:@"name"];
    [dic setObject:@(peripheral.state == CBPeripheralStateConnected ? 0 : -1) forKey:@"bondState"];
    return dic;
}

@end

