//
//  BTDataProcessVC.m
//  Unity-iPhone
//
//  Created by leon on 2021/2/3.
#import "BTDataProcess.h"
#import "IOSPlatformSDK.h"
#include "Game.h"

#import "MYFactoryManager.h"

#import "LEONBLManager.h"

#import "ShoesInfo.h"
#import "GameInfo.h"
#import "CacheTool.h"

//#define NSLog(format, ...) printf("TIME:%s FILE:%s(%d行) FUNCTION:%s %s\n",__TIME__, [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, __PRETTY_FUNCTION__, [[NSString stringWithFormat:(format), ##__VA_ARGS__] UTF8String])
@interface BTDataProcess ()
{
@private
Game *game;
Game *viceDeviceGame;
}

//蓝牙弹窗
@property (strong, nonatomic)SearchDeviceViewController * searchDeviceVC;
//蓝牙外设数据源
@property (strong, nonatomic)NSMutableArray  * deviceArray;

//好友列表弹窗
@property (strong, nonatomic)FriendsListViewController * friendsListVC;


//定时查询设备状态
@property(nonatomic,weak)NSTimer * timer;

//鞋子信息
@property(nonatomic,strong)ShoesInfo * shoes_info;
//当局游戏信息
@property(nonatomic,strong)GameInfo * game_info;

//
@property(nonatomic,assign)BOOL isPopUp;

@end

@implementation BTDataProcess

#pragma mark ===============================================>> 单例
static BTDataProcess* instance = nil;
+(instancetype)sharedInstance{
     return [[self alloc] init];
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
  static dispatch_once_t onceToken;
  dispatch_once(&onceToken, ^{
      instance = [super allocWithZone:zone];
  });
  return instance;
}
- (instancetype)init{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [super init];
        //游戏数据初始化
        [self initData];
    });
    return instance;
}

#pragma mark ===============================================>> private
-(void)initData{
    
    self.shoes_info = [ShoesInfo new];
    self.shoes_info.gameModel = NO; //默认游戏模式关
    self.shoes_info.timestamp = [AlgorithmTool returnTimestamp];//跳转游戏时候刷新一个新的时间戳
    
    self.game_info = [GameInfo new];
    self.game_info.isBackGround = NO; //后台模式
    NSLog(@"self.game_info = %d %d %d %d %d %d %d",self.game_info.step,self.game_info.jump,self.game_info.crouch,self.game_info.tick,self.game_info.paper,self.game_info.scissors,self.game_info.rock);
    
    
    //监听 趣动 app group 消息 ==>> 好友邀请信息
    CFStringRef invite = (__bridge CFStringRef)@"INVITE_NOTIFICATION";
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                    NULL,
                                    inviteFriends,
                                    invite,
                                    NULL,
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
    
    //监听 趣动 app group 消息 ==>> 断开蓝牙
    CFStringRef strRef = (__bridge CFStringRef)@"DISCONNECT_BLE";
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
                                    NULL,
                                    disConnectBle,
                                    strRef,
                                    NULL,
                                    CFNotificationSuspensionBehaviorDeliverImmediately);
    //监听程序 退到 后台
    [CUS_NOTIFICATIONCENTER addObserver:self selector:@selector(enterBackground) name:UIApplicationDidEnterBackgroundNotification object:nil];
    //监听程序 返回 前台
    [CUS_NOTIFICATIONCENTER addObserver:self selector:@selector(willEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];

}

-(void)enterBackground{
    NSLog(@"leon UIApplicationDidEnterBackgroundNotification");
    self.game_info.isBackGround = YES;
}

-(void)willEnterForeground{
    
    NSLog(@"leon UIApplicationWillEnterForegroundNotification");
    
    // 发送app group通知
    NSString * notificaitonName = @"GAME_ENTERFOREGROUND";
    CFStringRef strRef = (__bridge CFStringRef)notificaitonName;
    CFNotificationCenterRef notification = CFNotificationCenterGetDarwinNotifyCenter ();
    CFNotificationCenterPostNotification(notification, strRef, NULL,NULL, YES);
    
    self.game_info.isBackGround = NO;
    
    NSLog(@"程序从后台返回 重连蓝牙 peripheral.state = %ld %ld",LEManager.peripheral.state,LEManager.vicePeripheral.state);
    
    //主副设备：deviceType  游戏种类：game_type  mac地址：macAddress
    self.game_info.deviceType = DEVICETYPE_MAIN;
    self.game_info.game_type = (GAME_TYPE)[[CacheTool getGameType] intValue];
    self.game_info.vibrate = [CacheTool getGameVibrate];
    self.game_info.debug = [CacheTool getGameDebug];
    
    self.shoes_info.macAddress = [CacheTool getGameMac];
    self.shoes_info.viceMacAddress = @"";

    //开启自动重连
    [self newCentralManagerOrScan];

}

//返回趣动同时断开主副设备链接
void disConnectBle (CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
    NSLog(@"趣动 通知断开蓝牙");
    [instance disConnedctBle:0];
    [instance disConnedctBle:1];
}

//趣动or点击游戏内断开按钮 ==>> 断开蓝牙
-(void)disConnedctBle:(int)type{
    
    //是点击button主动断开
    if (type == 0){
        self.shoes_info.macAddress = @"";
    }else if (type == 1){
        self.shoes_info.viceMacAddress = @"";
    }
    [LEManager cancelPeripheralConnection:type];
    
}

//趣动 ==>> 通知邀请好友
void inviteFriends (CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo){
        
    NSLog(@"IOS_SKD 回调好友邀请信息 GetInviteInfo ===>>  %@",userInfo);

    //group.com.Oujia.AppAndGame 沙河数据
    NSUserDefaults* userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.Oujia.AppAndGame"];
    //趣动传过来的 invite json字符串转字典
    NSString * string = [userDefault objectForKey:@"invite"];
    if (string == nil) {
        [PopupView showCusHUDA:@"邀请参数为空"];
        return;
    }
    NSData * data = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSDictionary * inviteDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    if (inviteDict!=nil){
        //字典取值
        NSDictionary * invite = [inviteDict objectForKey:@"invite"];
        NSDictionary * user =  [invite objectForKey:@"user"];
        //user字典 -> 字符串 -> Char
        NSData * userData = [NSJSONSerialization dataWithJSONObject:user options:NSJSONWritingPrettyPrinted error:nil];
        NSString * userString =  [[NSString alloc] initWithData:userData encoding:NSUTF8StringEncoding];
        const char * userChar =[userString UTF8String];
        //info字符串 -> Char
        NSString * infoString = invite[@"info"];
        const char * infoChar =[infoString UTF8String];
        NSLog(@"IOS_SKD 回调好友邀请信息 GetInviteInfo ===>>  %s , %s",userChar,infoChar);
        [[IOSPlatformSDK sharedInstance] bridgingInvite:0 userChar:userChar infoChar:infoChar];
    }
    
}

#pragma mark ===============================================>> public method
-(void)startWithUrl:(NSURL*)url{//
    
    if (url==nil){
        return;
    }
    NSString * urlString = [url absoluteString];
    NSArray * stringArr = [urlString componentsSeparatedByString:@"//"];
    if (stringArr == nil || stringArr.count<2){
        return;
    }
    NSString * arr2 = stringArr[1];
    NSString* finsalString = [arr2 stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSDictionary * urlDict = [AlgorithmTool dictionaryWithJsonString:finsalString];
    NSLog(@"Schemes_Url转码的dict ========= %@",urlDict);
    //缓存用户信息数据
    [IOS_NSUSERDEFAULT setObject:urlDict forKey:IOSSDK_USERINFO];
    [IOS_NSUSERDEFAULT synchronize];
    
    //界面还没加载完毕 弹窗会导致奔溃
//    //检查有没有好友邀请信息
//    const char * userChar = [[CacheTool getInviteUser] UTF8String];
//    const char * infoChar =[[CacheTool getInviteInfo] UTF8String];
//    if (infoChar!=nil&&strlen(infoChar)>1) {
//        [[IOSPlatformSDK sharedInstance] bridgingInvite:0 userChar:userChar infoChar:infoChar];
//    }
  
    //主副设备：deviceType  游戏种类：game_type  mac地址：macAddress
    self.game_info.deviceType = DEVICETYPE_MAIN;
    self.game_info.game_type = (GAME_TYPE)[[CacheTool getGameType] intValue];
    self.game_info.vibrate = [CacheTool getGameVibrate];
    self.game_info.debug = [CacheTool getGameDebug];

    //重置mac
    self.shoes_info.macAddress = [CacheTool getGameMac];
    self.shoes_info.viceMacAddress = @"";
    
    //链接蓝牙
    [self newCentralManagerOrScan];
    
}

//unity call instance弹出蓝牙搜索框
-(void)searchBLEAction:(int)type{
    
    //初始化蓝牙CBCentralManager
    [self newCentralManagerOrScan];

    //搜索蓝牙外设弹窗
    if (self.searchDeviceVC!=nil){
        self.searchDeviceVC=nil;
    }
    self.searchDeviceVC = [SearchDeviceViewController new];
    self.isPopUp = YES;
    [[UIApplication sharedApplication].keyWindow addSubview:self.searchDeviceVC.view];
    
    //点击searchVC的tableViewCell链接选中的蓝牙
    __weak __typeof(self)weakself = self;
    self.searchDeviceVC.connectDeviceBlock = ^(CBPeripheral * peripheral){
        //主副设备：deviceType  游戏种类：game_type  mac地址：macAddress
        weakself.game_info.game_type = (GAME_TYPE)[[CacheTool getGameType] intValue];
        weakself.game_info.deviceType = (DEVICE_TYPE)type;
        if (type == 0) {
            weakself.shoes_info.macAddress = peripheral.identifier.UUIDString;
        }else if (type ==1){
            weakself.shoes_info.viceMacAddress = peripheral.identifier.UUIDString;
        }
        [weakself connectBLEManagerData:peripheral];
    };
    
    self.searchDeviceVC.closeBlock = ^{
        weakself.isPopUp = NO;
    };
    
}

//unity call instance弹出 好友列表 搜索框 (int code, char * info)
-(void)showInviteFriend:(int)code inviteInof:(NSString*)inviteInof{
            
    //搜索蓝牙外设弹窗
    if (self.friendsListVC!=nil){
        self.friendsListVC=nil;
    }
    self.friendsListVC = [FriendsListViewController new];
    self.isPopUp = YES;
    [[UIApplication sharedApplication].keyWindow addSubview:self.friendsListVC.view];
    
    [MBProgressHUD showHUDAddedTo:self.friendsListVC.view animated:YES];
    [HTTPDataProcession getFriendsList:^(int code, const char *jsonString, NSMutableArray *dataArr){
        NSLog(@"IOS_SKD 回调好友列表 GetUserFriends 数组 ===> %@",dataArr);
        self.friendsListVC.friendsArray = dataArr;
        //主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:self.friendsListVC.view animated:YES];
            [self.friendsListVC reloadData];
        });
        
    }];
    
    //点击searchVC的tableViewCell链接选中的蓝牙
    __weak __typeof(self)weakself = self;
    self.friendsListVC.inviteFriendBlock = ^(UserFriendsModel *model){
        [HTTPDataProcession inviteFriends:model.trans_id inviteInfo:inviteInof inviteDataBlock:^(NSString *jsonString){
//            NSLog(@"IOS_SKD 回调点击邀请好友事件 InviteFriend ===>>");
            dispatch_async(dispatch_get_main_queue(), ^{
            [PopupView showCusHUDA:jsonString];
            });
        }];
    };
    
    self.friendsListVC.closeBlock = ^{
//        NSLog(@"设置 weakself.isPopUp = NO");
        weakself.isPopUp = NO;
    };
    //
}


//每重新开始一局游戏
-(void)gameStartInitData{
        
    //当局游戏持续时间
    self.game_info.firstTime = [NSDate date];

    //游戏模式 ==>> 回调剑波sdk数据
    self.shoes_info.gameModel = YES;
    
    //读写到特征后 添加测试弹窗
    dispatch_async(dispatch_get_main_queue(), ^{
        [DebugViewInstance notificationStartGame];
    });
    
}

//每结束一局游戏
-(void)gameEndInitData{
    self.shoes_info.gameModel = NO;
    if ([self.game_info.debug intValue] == 1) {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(),^{
            [DebugViewInstance uploadpPlistFile];
        });
    }
}

//监听unity通知震动
-(void)vibrationAction:(int)type duration:(int)duration leftOrRight:(int)leftOrRight{
    if ([self.game_info.vibrate intValue] == 1) {
        [BTDataSendInstance vibration:(DEVICE_TYPE)type duration:duration leftOrRight:leftOrRight];
    }
}


#pragma mark ===============================================>> leon Ble manager
//自己封装的蓝牙类
-(void)newCentralManagerOrScan{
    
    if (LEManager.centralManager == nil && LEManager.peripheral == nil && LEManager.vicePeripheral == nil){
        NSLog(@" ====================>> 未初始化 centralManager 直接开始初始化");
        [LEManager initCBCentralManager];
    }else{
        [self ifHasLinks];
    }
    
    //每次 initCBCentralManager 走以下回调
    LEManager.stateUpdateBlock = ^(CBCentralManager *  central){
        switch(central.state){
            case 0:
                NSLog(@"当前的蓝牙状态 ===>> CBCentralManagerStateUnknown");
                break;
            case 1:
                NSLog(@"当前的蓝牙状态 ===>> CBCentralManagerStateResetting");
                break;
            case 2:
                NSLog(@"当前的蓝牙状态 ===>> CBCentralManagerStateUnsupported");
                break;
            case 3:
                NSLog(@"当前的蓝牙状态 ===>> CBCentralManagerStateUnauthorized");
                break;
            case 4:{
                NSLog(@"当前的蓝牙状态 ===>> 蓝牙已关闭");
                if (LEManager.peripheral!=nil){
                    [[IOSPlatformSDK sharedInstance] bridgingDeviceAction:DEVICETYPE_MAIN
                                                name:LEManager.peripheral.name
                                             address:LEManager.peripheral.identifier.UUIDString
                                              status:CONNECT_LOST
                                         electricity:0];
                }
                
                if (LEManager.vicePeripheral!=nil){
                    [[IOSPlatformSDK sharedInstance] bridgingDeviceAction:DEVICETYPE_VICE
                                                name:LEManager.vicePeripheral.name
                                             address:LEManager.vicePeripheral.identifier.UUIDString
                                              status:CONNECT_LOST
                                         electricity:0];
                }
                
            }
                break;
            case 5:{
                NSLog(@"当前的蓝牙状态 ===>> 蓝牙已开启");//蓝牙已开启
                [self ifHasLinks];
            }
                break;
            default:
                break;
        }
        
    };
    
    [self.deviceArray removeAllObjects];
    
    //发现蓝牙
    LEManager.discoverPeripheralBlock = ^(CBCentralManager * _Nonnull central, CBPeripheral * _Nonnull peripheral, NSDictionary * _Nonnull advertisementData, NSNumber * _Nonnull RSSI){
        //        NSLog(@"扫描发现蓝牙设备advertisementData =  %@",advertisementData);
        NSString *advertiseName = [advertisementData objectForKey:CBAdvertisementDataLocalNameKey];
//        NSLog(@"advertisementData ========= %@ %@",peripheral.name,advertiseName);
        
                peripheral.advertiseName = advertiseName;

                if ([advertiseName hasPrefix:@"SH_"]||[advertiseName hasPrefix:@"fun_"]||[advertiseName hasPrefix:@"Fun_"]||[advertiseName hasPrefix:@"FUN_"]){//SH_DANCE BLE_LOOP  Shoes_4530 Shoes_2A74

//                    NSLog(@"主设备扫描发现有效的蓝牙设备 =============== %@   identifier == %@",peripheral.name,peripheral.identifier.UUIDString);

                    if (self.deviceArray.count == 0){//数据源为0
                            [self.deviceArray addObject:peripheral];
                            //判断扫描到外设之后是否要链接蓝牙
                            [self judgeConnect:peripheral];
                    }else{

                            BOOL isExist = NO;
                            for (int i = 0; i < self.deviceArray.count; i++){
                                CBPeripheral *per = [self.deviceArray objectAtIndex:i];
                                if ([per.identifier.UUIDString isEqualToString:peripheral.identifier.UUIDString]){
                                    isExist = YES;
                                    [self.deviceArray replaceObjectAtIndex:i withObject:peripheral];
                                }
                            }
                            if (!isExist){
                                [self.self.deviceArray addObject:peripheral];
                                //判断扫描到外设之后是否要链接蓝牙
                                [self judgeConnect:peripheral];
                            }
                    }

                    //数据回调给 搜索蓝牙弹窗
                    self.searchDeviceVC.deviceArray = self.deviceArray;
                    [self.searchDeviceVC reloadData];

            }

     };

}

#pragma mark ===============================================>>  主设备蓝牙数据
//扫描还是直链
-(void)ifHasLinks{
    
    [LEManager stopScan];
    
//    //已经被系统或者其他APP连接上的设备数组
//    NSArray *arr = [LEManager.centralManager retrieveConnectedPeripheralsWithServices:@[[CBUUID UUIDWithString:@"6E400001-B5A3-F393-E0A9-E50E24DCCA9E"]]];
//
//    if (arr.count>0) {//已经链了一双鞋子了
//
//        NSLog(@" ====================>> 已初始化 centralManager 有已经链接的鞋子");
//        //UUID是外设的服务UUID，满足UUID 的外设就会放在数组中
//        [arr enumerateObjectsUsingBlock:^(CBPeripheral *peripheral, NSUInteger idx, BOOL *stop){
//
//            if ([peripheral.name hasPrefix:@"SH_"]){//SH_DANCE BLE_LOOP  Shoes_4530 Shoes_2A74
//
//              NSLog(@"主设备 已经链接到的 蓝牙设备 =============== %@   identifier == %@",peripheral.name,peripheral.identifier.UUIDString);
//
//                LEManager.peripheral = peripheral;
//
//                [self connectPeripheral:LEManager.peripheral];
//
//            }
//
//        }];
//
//    }else{

        NSLog(@" ====================>> 已初始化 centralManager 直接开扫描");
        [LEManager scanForPeripheralsWithServices:nil options:nil];
        
//    }
    
}

//app跳转 断线重连 从后台返回
-(void)judgeConnect:(CBPeripheral*)peripheral{
    
//    NSLog(@"self.shoes_info.macAddress = %@  peripheral.identifier.UUIDString = %@",self.shoes_info.macAddress,peripheral.identifier.UUIDString);
    if (self.shoes_info.macAddress.length>12 && [peripheral.identifier.UUIDString isEqualToString:self.shoes_info.macAddress]){
        self.game_info.deviceType = DEVICETYPE_MAIN;
        [self connectBLEManagerData:peripheral];
    }
    
    if (self.shoes_info.viceMacAddress.length>12 && [peripheral.identifier.UUIDString isEqualToString:self.shoes_info.viceMacAddress]){
        self.game_info.deviceType = DEVICETYPE_VICE;
        [self connectBLEManagerData:peripheral];
    }//
    
}

#pragma mark ===============================================>> public 链接蓝牙
//搜索弹窗 点击
//链接蓝牙
-(void)connectBLEManagerData:(CBPeripheral*)peripheral{
    
    NSLog(@"peripheral.name ==>>  %@",peripheral.name);
    
    if(instance == NULL || peripheral == NULL){return;}
   
    NSLog(@"BTDataProcess connectPeripheral self.game_info.deviceType ==>> %ld  self.game_info.game_type ==>> %d   mac ==>>  %@",(long)self.game_info.deviceType,self.game_info.game_type,self.shoes_info.macAddress);
                    
    //初始化运轨sdk
    if (self.game_info.deviceType==DEVICETYPE_MAIN){
        
        LEManager.peripheral = peripheral;
        game = new Game(self.game_info.game_type);
        //开始链接动画
        [[MainLoadingView shanreAnimationView] addAnimation];
        
    }else if (self.game_info.deviceType == DEVICETYPE_VICE){
        
        LEManager.vicePeripheral = peripheral;
        viceDeviceGame = new Game(self.game_info.game_type);
        //开始链接动画
        [[ViceLoadingView shanreAnimationView] addAnimation];

    }
            
    //链接蓝牙 此时 LEManager.peripheral || LEManager.vicePeripheral 还未init
    [LEManager connectPeripheral:peripheral options:nil];
    
    //蓝牙连接成功
    LEManager.successfulBlock = ^(CBPeripheral * _Nonnull peripheral){
        
        if (self.shoes_info.macAddress.length>12 && self.shoes_info.viceMacAddress.length == 0){//有主没副
            
            if (LEManager.peripheral.state == CBPeripheralStateConnected){//主设备已经连接上后 停止扫描
                NSLog(@"主设备蓝牙链接成功");
                [LEManager stopScan];
            }
            
        }else if(self.shoes_info.macAddress.length == 0 && self.shoes_info.viceMacAddress.length >12){//没主有副
            
            if (LEManager.vicePeripheral.state == CBPeripheralStateConnected){//副设备已经连接上后 停止扫描
                NSLog(@"副设备蓝牙链接成功");
                [LEManager stopScan];
            }
            
        }else if(self.shoes_info.macAddress.length>12 && self.shoes_info.viceMacAddress.length > 12){//有主有副
            
            if (LEManager.peripheral.state == CBPeripheralStateConnected && LEManager.vicePeripheral.state == CBPeripheralStateConnected){//主和副设备都已经连接上后 停止扫描
                NSLog(@"主设备 和 副设备 蓝牙链接成功");
                [LEManager stopScan];
            }
            
        }
        
    };

    //蓝牙连接失败
    LEManager.connectFailureBlock = ^(NSError * _Nonnull error){
        NSLog(@"蓝牙链接失败");
    };

    //蓝牙连接丢失
    LEManager.disConnectBlock = ^(CBPeripheral * _Nonnull peripheral, NSError * _Nonnull error){
              
        if (LEManager.peripheral!=nil && peripheral==LEManager.peripheral){
            [[IOSPlatformSDK sharedInstance] bridgingDeviceAction:DEVICETYPE_MAIN
                                        name:LEManager.peripheral.name
                                     address:LEManager.peripheral.identifier.UUIDString
                                      status:CONNECT_LOST
                                 electricity:0];
            
                if (self.shoes_info.macAddress.length>12){
                    NSLog(@"主设备 蓝牙链接断开 被动断开 需要重连");
                    [self newCentralManagerOrScan];
                }else{
                    NSLog(@"主设备 蓝牙链接断开 主动断开 不需重连");
                }
            
        }
        
        if (LEManager.vicePeripheral!=nil && peripheral==LEManager.vicePeripheral){
            [[IOSPlatformSDK sharedInstance] bridgingDeviceAction:DEVICETYPE_VICE
                                        name:LEManager.vicePeripheral.name
                                     address:LEManager.vicePeripheral.identifier.UUIDString
                                      status:CONNECT_LOST
                                 electricity:0];
            
                //副设备 断线 手动断开的话不用重连，自动断开的要重连
                if (self.shoes_info.viceMacAddress.length>12){
                    NSLog(@"副设备 蓝牙链接断开 被动断开 需要重连");
                    [self newCentralManagerOrScan];
                }else{
                    NSLog(@"副设备 蓝牙链接断开 主动断开 不需重连");
                }
            
          }
     
    };
    
    //发现服务和特征
    LEManager.discoverCharacteristicsBlock = ^(CBPeripheral * _Nonnull peripheral, CBService * _Nonnull service, NSArray * _Nonnull characteristics, NSError * _Nonnull error){
        
        if (peripheral==LEManager.peripheral){//主设备
            
            for (CBCharacteristic * cha in service.characteristics){
                
                if (cha.properties == 12){//写
                    
                    LEManager.write = cha;
                    //获取到写的特征后才能向 主设备 蓝牙对象写入数据
                    [self startGameModeAndQueryDevideInfo];
                    //链接成功震动一次
                    [BTDataSendInstance vibration:DEVICETYPE_MAIN duration:400 leftOrRight:0];

                    [self initTimer];
                    
                }else if (cha.properties == 16){//读
                    
                    LEManager.read  = cha;
                    [LEManager.peripheral readValueForCharacteristic:cha];
                    [LEManager.peripheral setNotifyValue:YES forCharacteristic:cha];
                    
                }

            }

        }else if (peripheral==LEManager.vicePeripheral){//副设备

            for (CBCharacteristic * cha in service.characteristics){
                
                if (cha.properties == 12){//写

                    LEManager.viceWrite = cha;
                    //获取到写的特征后才能向 副设备 蓝牙对象写入数据
                    [self startGameModeAndQueryDevideInfo];
                    //链接成功震动一次
                    [BTDataSendInstance vibration:DEVICETYPE_VICE duration:400 leftOrRight:0];

                }else if (cha.properties == 16){//读

                    LEManager.viceRead  = cha;
                    [LEManager.vicePeripheral readValueForCharacteristic:cha];
                    [LEManager.vicePeripheral setNotifyValue:YES forCharacteristic:cha];

                }
            }
        }
    };
    
    //读取特征的报文数据
    LEManager.readValueForCharacteristicBlock = ^(CBPeripheral * _Nonnull peripheral, CBCharacteristic * _Nonnull characteristic, NSData * _Nonnull value, NSError * _Nonnull error){
//        NSLog(@"characteristic.value = %@ characteristic.UUID.UUIDString = %@",characteristic.value,characteristic.UUID.UUIDString);

        if ([characteristic.UUID.UUIDString isEqualToString:@"6E400003-B5A3-F393-E0A9-E50E24DCCA9E"]){//判断是不是我们设备
            
            //每收到数据包读取一次蓝牙RSSI 无论1秒内请求多少次rssi值，原生api每秒都最多返回一次RSSI
            [peripheral readRSSI];
            
            //带cmd位的有效数据  计算校验位
            if ([AlgorithmTool verificationRusult:characteristic.value]==YES){
                
                int dataType = [AlgorithmTool dataToChar:[characteristic.value subdataWithRange:NSMakeRange(3, 1)]];//cmd类型
                
                  if (dataType == 4){//鞋子游戏数据
                      
                          if (characteristic.value.length < 64){ return; }

                          //数据丢给算法计算轨迹
                          if (peripheral==LEManager.peripheral&&LEManager.main_read == 0){
                              
//                              NSLog(@"LEManager.main_read = %d",LEManager.main_read);
//                              NSLog(@"主设备 读取特征的报文 游戏数据 %ld dataType = %d %@",(long)type,dataType,characteristic.value);
                              [[MainLoadingView shanreAnimationView] stopAnimation];
                              LEManager.main_read = 1;
                              [self shoseSDK:characteristic.value];
                              
                          }else if (peripheral==LEManager.vicePeripheral&&LEManager.vice_read == 0){

                              [[ViceLoadingView shanreAnimationView] stopAnimation];
                              LEManager.vice_read = 1;
                              [self viceShoseSDK:characteristic.value];
                              
                          }
                      
                  }else if(dataType == -95){//鞋子状态信息
                      
                          if (characteristic.value.length<30){ return; }
                          //嵌入式原始数据解析 --->> 回调蓝牙状态/电量给unity
                          BTDataAnalysis * anly = [BTDataAnalysis new];
                          [anly analysisCharacteristic:characteristic.value peripheral:peripheral];
                      
                  }
                      
             }
            
         }
        
    };

    //蓝牙更新RSSI
    LEManager.rssiBlock = ^(NSNumber * _Nonnull RSSI){
        LEManager.RSSI = RSSI;
    };
    
}

#pragma mark ===============================================>> 读取特征后 鞋子打开游戏模式 & 激光开关 &查询鞋子蓝牙状态 & 主设备初始化缓存游戏步数
//init定时器
-(void)initTimer{
    //定时开启游戏模式 & 查询设备信息 & 开启激光检测下蹲
    if (self.timer!=nil){
        [self.timer invalidate];
        self.timer = nil;
    }
    self.timer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(startGameModeAndQueryDevideInfo) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode];
}

//定时发送数据
-(void)startGameModeAndQueryDevideInfo{
    
    //开启游戏模式&查询设备信息 初始化步数数据 （防止读取到的读写为空 延迟0.5s）
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(),^{
        if (self.game_info.isBackGround){//程序在后台
        }else{//程序在前台
            [BTDataSendInstance startGameModel];
            [BTDataSendInstance queryDevideInfo];
            [BTDataSendInstance keepConnect];
        }
    });
    
}

#pragma mark ===============================================>> 主设备 报文数据解析后 -- 调用蓝牙鞋子SDK装换数据 -- ios call unity 更新游戏动作
-(void)shoseSDK:(NSData*)characteristic{
        
//    NSLog(@"characteristic = %@",characteristic);
            
        /********************初始化 运动轨迹算法 SDK *****************/
        NSData * validData= [characteristic subdataWithRange:NSMakeRange(4, characteristic.length-4)];
        Byte * buff = (Byte*)[validData bytes];
        game->GameProcessBuf(buff, (int)validData.length);
        
           
        if (self.shoes_info.gameModel==YES){//当前是游戏模式
            /********************剑波 & 威严 要的图表数据 *****************/
            NSString * message = [NSString stringWithUTF8String:game->getGameDataStr().c_str()];
            [DebugViewInstance debugMessage:message shoesInfo:self.shoes_info];
        }
        
            /******************左右脚动作数据处理 + 回调*****************/
            int length = 10;
            int result[length];
            game->getGameResult(result);
            int motionLeft = result[0];//左脚的动作
            int motionRight = result[1];//右脚的动作
            int motionJump = result[2];//jump
            int motionDown = result[3];//down
            
    //            //无效动作 过滤无效动作会导致步频加速无效
    //            if (motionLeft==-1 && motionRight == -1&& motionJump == -1&& motionDown == -1){
    //                return;
    //            }
                
                //跳跃和蹲下的动作 双脚是同步的
                if (motionJump == MOTION_JUMP||motionJump == MOTION_JUMP_OC||motionJump == MOTION_JUMP_VERTICAL){
                    motionLeft = motionJump;
                    motionRight = motionJump;
                }
            
                if (motionDown == MOTION_DOWN){
                    motionLeft = motionDown;
                    motionRight = motionDown;
                }
                
                /******************当局游戏 鞋子子动作状态数据 缓存*****************/
                self.shoes_info.leftStepStatus =  game->getStepStatus(LEFT_FOOT);
                self.shoes_info.leftStepFreq =  game->getStepFreq(LEFT_FOOT);
                self.shoes_info.leftStepCount =  game->getStepCount(LEFT_FOOT);
                self.shoes_info.rightStepStatus =  game->getStepStatus(RIGHT_FOOT);
                self.shoes_info.rightStepFreq =  game->getStepFreq(RIGHT_FOOT);
                self.shoes_info.rightStepCount =  game->getStepCount(RIGHT_FOOT);
                [self cacheAllMotionCount];
                    
                /******************鞋子动作状态数据 实时回调*****************/
                //左右脚动作：所有游戏都需要回调
                [[IOSPlatformSDK sharedInstance] bridgingMotionAction:DEVICETYPE_MAIN left:motionLeft right:motionRight];
                
                //步频状态：只有跑酷回调
                if (self.game_info.game_type == GAME_TYPE_RUN||self.game_info.game_type == GAME_TYPE_CYCLE){
                    [[IOSPlatformSDK sharedInstance] bridgingStepAction:DEVICETYPE_MAIN leftStatus:self.shoes_info.leftStepStatus rightStatus:self.shoes_info.rightStepStatus leftFrag:self.shoes_info.leftStepFreq rightFrag:self.shoes_info.rightStepFreq];
                }
                
                //人物朝向 只有 三轮车 需要
                if (self.game_info.game_type == GAME_TYPE_CYCLE){
                        int attLength = 3;
                        int left[attLength];
                        int right[attLength];
                         game->getFootAtt(left, right);
                        self.main_nativeAttX = left[0];
    //                        NSLog(@"self.nativeAttX = %d",self.nativeAttX);
                }
    
            /******************脚步交互数据 实时回调*****************/
            int interaction = game->getInteractionCMD();
            if (interaction==-1){
                return;
            }
            //自定义弹窗界面交互
            if (self.isPopUp == YES){
                NSLog(@"BTDataProcess 有效交互动作 ===>> %d",interaction);
                [self.searchDeviceVC getInteraction:interaction];
                [self.friendsListVC getInteraction:interaction];
            }else{
                //游戏界面交互
                [[IOSPlatformSDK sharedInstance] bridgingInteraction:DEVICETYPE_MAIN code:interaction];
            }
                
}

#pragma mark ===============================================>>副设备 报文数据解析后 -- 调用蓝牙鞋子SDK装换数据 -- ios call unity 更新游戏动作
-(void)viceShoseSDK:(NSData*)characteristic{
        
        /********************初始化 运动轨迹算法 SDK *****************/
        //游戏数据
        NSData * validData= [characteristic subdataWithRange:NSMakeRange(4, characteristic.length-4)];
        Byte * buff = (Byte*)[validData bytes];
        viceDeviceGame->GameProcessBuf(buff, (int)validData.length);

    
        //当前是游戏模式
//        if (self.shoes_info.gameModel==YES){
                
                /******************左右脚动作数据处理 + 回调*****************/
                int length = 10;
                int result[length];
                viceDeviceGame->getGameResult(result);
                int motionLeft = result[0];//左脚的动作
                int motionRight = result[1];//右脚的动作
                int ivce_motionJump = result[2];//jump
                int ivce_motionDown = result[3];//down
                    
                //跳跃和蹲下的动作 双脚是同步的
                if (ivce_motionJump == MOTION_JUMP||ivce_motionJump == MOTION_JUMP_OC||ivce_motionJump == MOTION_JUMP_VERTICAL){
                    motionLeft = ivce_motionJump;
                    motionRight = ivce_motionJump;
                }
                if (ivce_motionDown == MOTION_DOWN){
                    motionLeft = ivce_motionDown;
                    motionRight = ivce_motionDown;
                }
                
                /******************当局游戏 鞋子子动作状态数据 缓存*****************/
                int leftStepStatus =  viceDeviceGame->getStepStatus(LEFT_FOOT);
                int leftStepFreq =  viceDeviceGame->getStepFreq(LEFT_FOOT);
//                int leftStepCount =  viceDeviceGame->getStepCount(LEFT_FOOT);
                int rightStepStatus =  viceDeviceGame->getStepStatus(RIGHT_FOOT);
                int rightStepFreq =  viceDeviceGame->getStepFreq(RIGHT_FOOT);
//                int rightStepCount =  viceDeviceGame->getStepCount(RIGHT_FOOT);
                
                /******************鞋子动作状态数据 实时回调*****************/
                //左右脚动作：所有游戏都需要回调
                [[IOSPlatformSDK sharedInstance] bridgingMotionAction:DEVICETYPE_VICE left:motionLeft right:motionRight];
            
                //步频：跑酷和三轮车
                if (self.game_info.game_type == GAME_TYPE_RUN||self.game_info.game_type == GAME_TYPE_CYCLE){
                    [[IOSPlatformSDK sharedInstance] bridgingStepAction:DEVICETYPE_VICE leftStatus:leftStepStatus rightStatus:rightStepStatus leftFrag:leftStepFreq rightFrag:rightStepFreq];
                }
             
                //人物朝向：三轮车
                if (self.game_info.game_type == GAME_TYPE_CYCLE){
                        int attLength = 3;
                        int left[attLength];
                        int right[attLength];
                         viceDeviceGame->getFootAtt(left, right);
                        self.vice_nativeAttX = left[0];
                }
            
//        }
    
                /******************脚步交互数据 实时回调*****************/
                int interaction = viceDeviceGame->getInteractionCMD();
                if (interaction==-1){
                    return;
                }
                if (self.isPopUp == YES){//自定义弹窗界面交互
                    }else{
                    //游戏界面交互
                    [[IOSPlatformSDK sharedInstance] bridgingInteraction:DEVICETYPE_VICE code:interaction];
                }
            
}

#pragma mark ===============================================>> 懒加载 -- 蓝牙设备数据源
-(NSMutableArray*)deviceArray{
    if (!_deviceArray){
        _deviceArray = [NSMutableArray new];
    }
    return _deviceArray;;
}

#pragma mark ===============================================>> 玩游戏过程中缓存 动作数据 和时间戳 数据存入plist
-(void)cacheAllMotionCount{
    
    //总数
    int total_step_count = game->getMotionCount(STEP_COUNT) - self.game_info.step;
    int total_jump_count = game->getMotionCount(JUMP_COUNT) - self.game_info.jump;
    int total_crouch_count = game->getMotionCount(DOWN_COUNT) - self.game_info.crouch;
    int total_tick_count = game->getMotionCount(KICK_COUNT) - self.game_info.tick;
    int total_paper_count = game->getMotionCount(PAPER_COUNT) - self.game_info.paper;
    int total_scissors_count = game->getMotionCount(SCISSORS_COUNT) - self.game_info.scissors;
    int total_rock_count = game->getMotionCount(ROCK_COUNT) - self.game_info.rock;
//    int total_trample_count = game->getMotionCount(ROCK_COUNT) - self.game_info.trample;

//    NSLog(@"total_ = %d %d %d %d %d %d %d",total_step_count,total_jump_count,total_cro÷uch_count,total_tick_count,total_paper_count,total_scissors_count,total_rock_count);

    //缓存pilst文件
    NSMutableDictionary * motionCountObj = [NSMutableDictionary new];
    [motionCountObj setObject:[NSNumber numberWithInt:total_step_count] forKey:@"step"];
    [motionCountObj setObject:[NSNumber numberWithInt:total_jump_count] forKey:@"jump"];
    [motionCountObj setObject:[NSNumber numberWithInt:total_crouch_count] forKey:@"crouch"];
    [motionCountObj setObject:[NSNumber numberWithInt:total_tick_count] forKey:@"tick"];
    [motionCountObj setObject:[NSNumber numberWithInt:total_paper_count] forKey:@"paper"];
    [motionCountObj setObject:[NSNumber numberWithInt:total_scissors_count] forKey:@"scissors"];
    [motionCountObj setObject:[NSNumber numberWithInt:total_rock_count] forKey:@"rock"];
    [motionCountObj setObject:[NSNumber numberWithInt:0] forKey:@"trample"];

    NSMutableDictionary * movements = [NSMutableDictionary new];
    [movements setObject:motionCountObj forKey:@"movements"];
    //游戏总共经历的时长（秒数）
    NSTimeInterval durationTime = [[NSDate date] timeIntervalSinceDate:self.game_info.firstTime];
    [movements setObject:[NSNumber numberWithInt:durationTime] forKey:@"duration"];
    //时间戳
    [movements setObject: self.shoes_info.timestamp forKey:@"play_group"];
    
    NSDictionary * dict = [NSDictionary dictionaryWithDictionary:movements];
        
    //归档缓存
    [IOS_NSUSERDEFAULT setObject:dict forKey:IOSSDK_MOTIONCOUNT];
    [IOS_NSUSERDEFAULT synchronize];
    
}

@end

