//
//  OffcnIMSDKiOS.m
//  OffcnIMSDKiOS
//
//  Created by vockey on 2018/10/16.
//  Copyright © 2018年 中公教育. All rights reserved.
//

#import "OffcnIMSDKiOS.h"
#import "OffcnBaseNetworking.h"
#import "ZYJRealReachability.h"
#import "SDGeneralDefine.h"
#import "OffcnNetworkExecutor.h"
#import "OffcnUploadManager.h"
#import "SDGeneralTool.h"
#import "DataSafe.h"
#import "NSString+MD5.h"
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#import "OffcnIMZYJFMDBHandler.h"

@interface OffcnIMSDKiOS ()


@end

@implementation OffcnIMSDKiOS

static OffcnIMSDKiOS *liveTelecastSDK;
+ (OffcnIMSDKiOS *)defaultService{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        liveTelecastSDK = [[OffcnIMSDKiOS alloc] init];
    });
    return liveTelecastSDK;
}
-(instancetype)init{
    self = [super init];
    if (self) {
        
    }
    return self;
}
-(void)setIsTest:(BOOL)isTest{
    if (isTest) {
        [[OffcnBaseNetworking sharedInstance] setServiceType:2];
    }else{
        [[OffcnBaseNetworking sharedInstance] setServiceType:3];
    }
    _isTest = isTest;
}

#pragma mark - 使用RealReachability监听网络状态
-(void)startNotifierUseRealReachability{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkChanged:)                                            name:ZYJkRealReachabilityChangedNotification object:nil];
    
    GLobalRealReachability.hostForPing = @"api.live.offcncloud.com";
    GLobalRealReachability.pingTimeout = 10;
    [GLobalRealReachability startNotifier];
    
    ReachabilityStatus status = [GLobalRealReachability currentReachabilityStatus];
    [self realNetworkingStatus:status];
}
- (void)networkChanged:(NSNotification *)notification
{
    ZYJRealReachability *reachability= (ZYJRealReachability *)notification.object;
    ReachabilityStatus status= [reachability currentReachabilityStatus];
    [self realNetworkingStatus:status];
}
-(void)realNetworkingStatus:(ReachabilityStatus)status{
    KWeakSelf
    switch (status){
        case RealStatusUnknown:
        case RealStatusNotReachable:
        {
            [OffcnNetworkExecutor requesImgJsonWithUrlStr:@"https://api.live.offcncloud.com" Finished:^(BOOL success, id response, NSString *message) {
                if (success) {
                    weakSelf.OffcnReachabilityStatus = OffcnSDKReachabilityStatusViaWiFi;
                    if (weakSelf.reachabilityStatusCallBack) {
                        weakSelf.reachabilityStatusCallBack(OffcnSDKReachabilityStatusViaWiFi);
                    }
                }else{
                    weakSelf.OffcnReachabilityStatus = OffcnSDKReachabilityStatusNotReachable;
                    if (weakSelf.reachabilityStatusCallBack) {
                        weakSelf.reachabilityStatusCallBack(OffcnSDKReachabilityStatusNotReachable);
                    }
                }
            }];
            break;
        }
        case RealStatusViaWWAN:
        {
            self.OffcnReachabilityStatus = OffcnSDKReachabilityStatusViaWWAN;
            if (self.reachabilityStatusCallBack) {
                self.reachabilityStatusCallBack(OffcnSDKReachabilityStatusViaWWAN);
            }
            break;
        }
        case RealStatusViaWiFi:
        {
            self.OffcnReachabilityStatus = OffcnSDKReachabilityStatusViaWiFi;
            if (self.reachabilityStatusCallBack) {
                self.reachabilityStatusCallBack(OffcnSDKReachabilityStatusViaWiFi);
            }
            break;
        }
        default:
            break;
    }
}

#pragma mark - 操作事件
//发送消息
-(void)sendMsgWithMsg_fromID:(NSString *)msg_fromID msg_toID:(NSString *)msg_toID msg_type:(OffcnSDKMsgType)msg_type text:(NSString *)text filePath:(NSString *)filePath Finished:(void(^)(BOOL success,OffcnIMSendMsgModel *sendMsgModel,NSString *errorMessage))finished ProgressPercent:(void(^)(NSString *key, float percent))progressPercent{
    
    KWeakSelf
    NSString *tidStr = [NSString stringWithFormat:@"%@_%@",msg_toID,[SDGeneralTool getNowSSSTimeTimestamp]];
    
    if (msg_type == OffcnSDKMsgTypeText) {
        if (!text || !text.length) {
            text = @"";
        }
        
        OffcnIMMsgModel *MsgModel = [[OffcnIMMsgModel alloc] init];
        OffcnIMBodyModel *BodyModel = [[OffcnIMBodyModel alloc] init];
        BodyModel.msg_from = msg_fromID;
        BodyModel.msg_to = msg_toID;
        BodyModel.msg_type = msg_type;
        BodyModel.tid = tidStr;
        MsgModel.msg = text;
        BodyModel.msg = MsgModel;
        BodyModel.isSentSuccess = 0;
        BodyModel.bymyself = 1;
        BodyModel.isRead = 0;
        
        [[OffcnIMZYJFMDBHandler sharedInstance] insertChatInfoToFMDBWithModel:BodyModel];
        [[OffcnIMZYJFMDBHandler sharedInstance] chatlistCacheInfo:BodyModel callback:nil];
        
        
        NSMutableDictionary *dataDic = [NSMutableDictionary dictionaryWithObject:text forKey:@"msg"];
        [OffcnNetworkExecutor requestSendMsgWithMsg_fromID:msg_fromID msg_toID:msg_toID msg_type:msg_type tid:tidStr msg:dataDic Finished:^(BOOL success, OffcnIMSendMsgModel *sendMsgModel, BaseResponse *baseResponse) {
            
            finished(success,sendMsgModel,baseResponse.errorMessage);
        }];
    }else{
        if (!filePath || !filePath.length) {
            filePath = @"";
        }
        
        OffcnIMBodyModel *BodyModel = [[OffcnIMBodyModel alloc] init];
        BodyModel.msg_from = msg_fromID;
        BodyModel.msg_to = msg_toID;
        BodyModel.msg_type = msg_type;
        BodyModel.tid = tidStr;
        BodyModel.isSentSuccess = 0;
        BodyModel.bymyself = 1;
        BodyModel.isRead = 0;
        [[OffcnIMZYJFMDBHandler sharedInstance] insertChatInfoToFMDBWithModel:BodyModel];
        [[OffcnIMZYJFMDBHandler sharedInstance] chatlistCacheInfo:BodyModel callback:nil];
        
        [[OffcnUploadManager defaultService] uploadToQNFilePath:filePath Finished:^(BOOL success, id  _Nonnull response, NSString * _Nonnull errorMessage) {
            if (success) {
                NSString *urlStr = @"";
                if (response) {
                    urlStr = [NSString stringWithFormat:@"%@",response];
                }
                
                NSString *md5Str = [urlStr md5Encrypt];
                
                NSMutableDictionary *dataDic = [NSMutableDictionary dictionary];
                
                if (msg_type == OffcnSDKMsgTypePicture) {
                    NSString *nameStr = [NSString stringWithFormat:@"%@_%@",msg_toID,[SDGeneralTool getNowSSSTimeTimestamp]];
                    NSString *extStr = [filePath pathExtension];
                    UIImage *image1 = [UIImage imageWithContentsOfFile:filePath];
                    CGSize imgSize = image1.size;
                    long long folderSize = [weakSelf fileSizeAtPath:filePath];
                    
                    [dataDic setObjectOnSafe:urlStr forKey:@"url"];
                    [dataDic setObjectOnSafe:nameStr forKey:@"name"];
                    [dataDic setObjectOnSafe:md5Str forKey:@"md5"];
                    [dataDic setObjectOnSafe:@"" forKey:@"thumb_url"];
                    [dataDic setObjectOnSafe:extStr forKey:@"ext"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithFloat:imgSize.width] forKey:@"w"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithFloat:imgSize.height] forKey:@"h"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithLongLong:folderSize] forKey:@"size"];
                }else if (msg_type == OffcnSDKMsgTypeAudio){
                    NSInteger dur = (NSInteger)[weakSelf audioDurationFromUrl:filePath];
                    NSString *extStr = [filePath pathExtension];
                    long long folderSize = [weakSelf fileSizeAtPath:filePath];
                    
                    [dataDic setObjectOnSafe:[NSNumber numberWithInteger:dur] forKey:@"dur"];
                    [dataDic setObjectOnSafe:md5Str forKey:@"md5"];
                    [dataDic setObjectOnSafe:urlStr forKey:@"url"];
                    [dataDic setObjectOnSafe:extStr forKey:@"ext"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithLongLong:folderSize] forKey:@"size"];
                }else if (msg_type == OffcnSDKMsgTypeVideo){
                    NSDictionary *dic = [weakSelf getVideoInfoWithSourcePath:filePath];
                    NSInteger dur = [[dic objectForKeyOnSafe:@"duration"] integerValue];
                    NSString *extStr = [filePath pathExtension];
                    long long fileSize = [[dic objectForKeyOnSafe:@"fileSize"] longLongValue];
                    CGSize size = [weakSelf getVideoSizeWithSourcePath:filePath];
                    
                    [dataDic setObjectOnSafe:[NSNumber numberWithInteger:dur] forKey:@"dur"];
                    [dataDic setObjectOnSafe:md5Str forKey:@"md5"];
                    [dataDic setObjectOnSafe:urlStr forKey:@"url"];
                    [dataDic setObjectOnSafe:@"" forKey:@"cover_url"];
                    [dataDic setObjectOnSafe:extStr forKey:@"ext"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithLongLong:fileSize] forKey:@"size"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithFloat:size.width] forKey:@"w"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithFloat:size.height] forKey:@"h"];
                }else if (msg_type == OffcnSDKMsgTypeFile){
                    NSString *nameStr = [NSString stringWithFormat:@"%@_%@",msg_toID,[SDGeneralTool getNowSSSTimeTimestamp]];
                    NSString *extStr = [filePath pathExtension];
                    long long folderSize = [weakSelf fileSizeAtPath:filePath];
                    
                    [dataDic setObjectOnSafe:nameStr forKey:@"name"];
                    [dataDic setObjectOnSafe:md5Str forKey:@"md5"];
                    [dataDic setObjectOnSafe:urlStr forKey:@"url"];
                    [dataDic setObjectOnSafe:extStr forKey:@"ext"];
                    [dataDic setObjectOnSafe:[NSNumber numberWithLongLong:folderSize] forKey:@"size"];
                }
                
                OffcnIMMsgModel *MsgModel = [[OffcnIMMsgModel alloc] init];
                OffcnIMBodyModel *BodyModel = [[OffcnIMBodyModel alloc] init];
                BodyModel.msg_from = msg_fromID;
                BodyModel.msg_to = msg_toID;
                BodyModel.msg_type = msg_type;
                BodyModel.tid = tidStr;
                BodyModel.isSentSuccess = 0;
                BodyModel.bymyself = 1;
                BodyModel.isRead = 0;
                if (msg_type == 1) {
                    MsgModel.msg = [dataDic objectForKeyOnSafe:@"msg"];
                }else{
                    MsgModel.dur = [[dataDic objectForKeyOnSafe:@"dur"] longLongValue];
                    MsgModel.name = [dataDic objectForKeyOnSafe:@"name"];
                    MsgModel.md5 = [dataDic objectForKeyOnSafe:@"md5"];
                    MsgModel.url = [dataDic objectForKeyOnSafe:@"url"];
                    MsgModel.thumb_url = [dataDic objectForKeyOnSafe:@"thumb_url"];
                    MsgModel.cover_url = [dataDic objectForKeyOnSafe:@"cover_url"];
                    MsgModel.ext = [dataDic objectForKeyOnSafe:@"ext"];
                    MsgModel.w = [[dataDic objectForKeyOnSafe:@"w"] longLongValue];
                    MsgModel.h = [[dataDic objectForKeyOnSafe:@"h"] longLongValue];
                    MsgModel.size = [[dataDic objectForKeyOnSafe:@"size"] longLongValue];
                }
                BodyModel.msg = MsgModel;
                [[OffcnIMZYJFMDBHandler sharedInstance] updateChatInfoIsSendStatusToFMDBWithModel:BodyModel isSuccess:nil];
                [[OffcnIMZYJFMDBHandler sharedInstance] chatlistCacheInfo:BodyModel callback:nil];
                
                [OffcnNetworkExecutor requestSendMsgWithMsg_fromID:msg_fromID msg_toID:msg_toID msg_type:msg_type tid:tidStr msg:dataDic Finished:^(BOOL success, OffcnIMSendMsgModel *sendMsgModel, BaseResponse *baseResponse) {
                    
                    finished(success,sendMsgModel,baseResponse.errorMessage);
                }];
            }else{
                finished(success,nil,errorMessage);
            }
        } ProgressPercent:^(NSString *key, float percent) {
            
            progressPercent(key,percent);
        }];
    }
}

// 用户信息标记已读
-(void)markMsgReadWithMsg_fromID:(NSString *)msg_fromID msg_toID:(NSString *)msg_toID msg_seq:(NSInteger)msg_seq Finished:(void(^)(BOOL success,id response,NSString *errorMessage))finished{
    
    [OffcnNetworkExecutor requestMarkMsgReadWithMsg_fromID:msg_fromID msg_toID:msg_toID msg_seq:msg_seq Finished:^(BOOL success, id response, BaseResponse *baseResponse) {
        
        finished(success,response,baseResponse.errorMessage);
    }];
}

//获取会话未读消息列表
-(void)getSessionUnreadMsgWithFromID:(NSString *)fromID toID:(NSString *)toID Finished:(void(^)(BOOL success,OffcnIMUnreadMsgModel *unreadMsgModel,NSString *errorMessage))finished{
    
    [OffcnNetworkExecutor requestGetSessionUnreadMsgWithFromID:fromID toID:toID Finished:^(BOOL success, OffcnIMUnreadMsgModel *unreadMsgModel, BaseResponse *baseResponse) {
        
        finished(success,unreadMsgModel,baseResponse.errorMessage);
    }];
}

//获取用户最近会话记录
-(void)getRecentSessionsWithAccid:(NSString *)accid Finished:(void(^)(BOOL success,OffcnIMRecentMsgModel *recentMsgModel,NSString *errorMessage))finished{
    
    [OffcnNetworkExecutor requestGetRecentSessionsWithAccid:accid Finished:^(BOOL success, OffcnIMRecentMsgModel *recentMsgModel, BaseResponse *baseResponse) {
        
        finished(success,recentMsgModel,baseResponse.errorMessage);
    }];
}

// 获取会话历史消息列表
-(void)getSessionHistoryMsgWithFromID:(NSString *)fromID toID:(NSString *)toID msg_seq:(NSString *)msg_seq Finished:(void(^)(BOOL success,OffcnIMHistoryMsgModel *historyMsgModel,NSString *errorMessage))finished{
    
   [OffcnNetworkExecutor requestGetSessionHistoryMsgWithFromID:fromID toID:toID msg_seq:msg_seq Finished:^(BOOL success, OffcnIMHistoryMsgModel *historyMsgModel, BaseResponse *baseResponse) {
       
       finished(success,historyMsgModel,baseResponse.errorMessage);
   }];
}

// 注册用户设备
-(void)registerDevicesWithAccid:(NSString *)accid device_token:(NSString *)device_token Finished:(void(^)(BOOL success,id response,NSString *errorMessage))finished{
    
    [OffcnNetworkExecutor requestRegisterDevicesWithAccid:accid device_token:device_token Finished:^(BOOL success, id response, BaseResponse *baseResponse) {
        
        finished(success,response,baseResponse.errorMessage);
    }];
}

// 注销用户设备
-(void)unregisterDevicesWithAccid:(NSString *)accid device_token:(NSString *)device_token Finished:(void(^)(BOOL success,id response,NSString *errorMessage))finished{
    
    [OffcnNetworkExecutor requestUnregisterDevicesWithAccid:accid device_token:device_token Finished:^(BOOL success, id response, BaseResponse *baseResponse) {
        
        finished(success,response,baseResponse.errorMessage);
    }];
}





//单个文件的大小
- (long long)fileSizeAtPath:(NSString*)filePath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    }
    return 0;
}
//遍历文件夹获得文件夹大小，返回字节
- (long long)folderSizeAtPath:(NSString*)folderPath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if (![manager fileExistsAtPath:folderPath])
        return 0;
    NSString* fileName = [folderPath copy];
    long long folderSize = 0;
    
    BOOL isdir;
    [manager fileExistsAtPath:fileName isDirectory:&isdir];
    if (isdir != YES) {
        return [self fileSizeAtPath:fileName];
    }
    else
    {
        NSArray * items = [manager contentsOfDirectoryAtPath:fileName error:nil];
        for (int i =0; i<items.count; i++) {
            BOOL subisdir;
            NSString* fileAbsolutePath = [fileName stringByAppendingPathComponent:items[i]];
            
            [manager fileExistsAtPath:fileAbsolutePath isDirectory:&subisdir];
            if (subisdir==YES) {
                folderSize += [self folderSizeAtPath:fileAbsolutePath]; //文件夹就递归计算
            }
            else
            {
                folderSize += [self fileSizeAtPath:fileAbsolutePath];//文件直接计算
            }
        }
    }
    return folderSize; //folderSize/(1024*1024)递归时候会运算两次出错，所以返回字节。在外面再计算
}
-(NSString *)localFileSizeTextWithFolderSize:(long long)size{
//    NSString *sizeText = @"0";
//    if (size >= pow(10, 9)) { // size >= 1GB
//        sizeText = [NSString stringWithFormat:@"%.2fGB", size / pow(10, 9)];
//    } else if (size >= pow(10, 6)) { // 1GB > size >= 1MB
//        sizeText = [NSString stringWithFormat:@"%.2fMB", size / pow(10, 6)];
//    } else if (size >= pow(10, 3)) { // 1MB > size >= 1KB
//        sizeText = [NSString stringWithFormat:@"%.2fKB", size / pow(10, 3)];
//    } else { // 1KB > size
//        sizeText = [NSString stringWithFormat:@"%lldB", size];
//    }
    
    return [NSString stringWithFormat:@"%lld", size];
}
//音频
-(NSTimeInterval)audioDurationFromUrl:(NSString *)url{
    AVURLAsset *audioAsset = nil;
    NSDictionary *dic = @{AVURLAssetPreferPreciseDurationAndTimingKey:@(YES)};
    if ([url hasPrefix:@"http://"] || [url hasPrefix:@"https://"]) {
        audioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:url] options:dic];
    }else{
        audioAsset = [AVURLAsset URLAssetWithURL:[NSURL fileURLWithPath:url] options:dic];
    }
    CMTime audioDuration = audioAsset.duration;
    float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
    return audioDurationSeconds;
}
//视频
-(NSDictionary *)getVideoInfoWithSourcePath:(NSString *)path{
    AVURLAsset *asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];
    CMTime time = [asset duration];
    int seconds = ceil(time.value/time.timescale);

    long long fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil].fileSize;

    return @{@"fileSize" : @(fileSize),
             @"duration" : @(seconds)};
}
-(CGSize)getVideoSizeWithSourcePath:(NSString *)path{
    AVURLAsset *asset = [AVURLAsset assetWithURL:[NSURL fileURLWithPath:path]];
    NSArray *array = asset.tracks;
    CGSize videoSize = CGSizeZero;
    for(AVAssetTrack *track in array){
        if([track.mediaType isEqualToString:AVMediaTypeVideo]){
              videoSize = track.naturalSize;
        }
    }
    
    return videoSize;
}

-(void)dealloc{

}

@end
