//
//  ZCBaseRequestManager.m
//  UniversalApp
//
//  Created by 凯朱 on 2019/6/11.
//  Copyright © 2019 徐阳. All rights reserved.
//

#import "ZCBaseRequestManager.h"
#import "YQNetworking.h"
#import "Reachability.h"
static  NSString *const kRequestFaildMessage = @"网络请求失败,请稍后重试";
static  NSString *const kWithoutNetworkMessage = @"客户端无有效的网络连接";

@interface ZCBaseRequestManager()
{
    NSString *_qnToken;//保存七牛token
}
@end


@implementation ZCBaseRequestManager
/**
 发起网络请求
 
 @param url url
 @param method 请求方式
 @param params 参数
 @param finished 完成回调
 */
+(void)requestWithUrl:(NSString *)url method:(ZCRequestMethod)method params:(NSDictionary *)params finished:(ZCRequiredFinished)finished{
    [YQNetworking configHttpHeader:@{@"token":kSTRING(kTokenInfo.token)}];
    [YQNetworking setupTimeout:20];
    if (method == GET) {
        [YQNetworking getWithUrl:url refreshRequest:NO cache:NO params:params progressBlock:nil successBlock:^(id response) {
            [self handleResultWithResponse:response error:nil finished:finished];
        } failBlock:^(NSError *error) {
            [self handleResultWithResponse:nil error:error finished:finished];
        }];
    }else{
        [YQNetworking postWithUrl:url refreshRequest:NO cache:NO params:params progressBlock:nil successBlock:^(id response) {
            [self handleResultWithResponse:response error:nil finished:finished];
        } failBlock:^(NSError *error) {
            [self handleResultWithResponse:nil error:error finished:finished];
        }];
    }
}


#pragma mark - ————— 图片上传 <表单专用> —————
/**
 上传表单图片数据 - publicCell专用
 
 @param dataArray 表单数据源
 @param finished 数据源
 */
+(void)uploadFilesWithDataArray:(NSArray *)dataArray finished:(void(^)(BOOL isSuccessed,NSString *message))finished{
    //1.检查是否有图片上传
    __block NSInteger count = 0;
    [dataArray enumerateObjectsUsingBlock:^(NSArray *sections, NSUInteger idx, BOOL * _Nonnull stop) {
        [sections enumerateObjectsUsingBlock:^(ZCPublicCellModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
            NSArray *photos = [ZCTool arrayWithJsonStr:model.content];
            if (model.type == ZCEnumPublicCellTypeSelectPhoto && photos.count > 0) {
                count ++;
            }
        }];
    }];
    
    if (count == 0) {
        if (finished) finished(YES,@"");
        return;
    }
    
    //有图片上传,先获取七牛token
    [self getQnTokenWithFinished:^(BOOL isSuccessed,NSString *qiNiuToken ,NSString * _Nonnull code, NSString * _Nonnull message) {
        //获取token失败
        if (isSuccessed == NO) {
            if (finished) finished(NO,message);
            return;
        }
        
        //2.获取成功 - 上传图片
        [dataArray enumerateObjectsUsingBlock:^(NSArray *sections, NSUInteger idx, BOOL * _Nonnull stop) {
            [sections enumerateObjectsUsingBlock:^(ZCPublicCellModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
                NSArray *photos = [ZCTool arrayWithJsonStr:model.content];
                if (model.type != ZCEnumPublicCellTypeSelectPhoto || photos.count == 0) {
                    return;
                }
                
                //3.看下本地是否有该图片信息
                NSMutableArray *imageDatas = [[NSMutableArray alloc] init];
                //新的图片集合 - 记录网络图片先
                NSMutableArray *newPhotos = [[NSMutableArray alloc] init];
                [photos enumerateObjectsUsingBlock:^(NSString *imagePath, NSUInteger idx, BOOL * _Nonnull stop) {
                    
                    NSString *fullPath = [NSString stringWithFormat:@"%@/%@",kFileCacheDirectory,imagePath];
                    NSData *imageData = [NSData dataWithContentsOfFile:fullPath];
                    if (imageData) {
                        [imageDatas addObject:imageData];
                    }else{
                        [newPhotos addObject:imagePath];
                    }
                }];
                
                //4.本地没有该图片,有可能图片被删除,有可能已经是上传成功后服务器地址,这里不做处理回调成功
                if (imageDatas.count == 0){
                    count --;
                    if (count == 0) {
                        if (finished) finished(YES,@"非本地图片");
                        *stop = YES;
                    }
                }
                //5.调用七牛服务上传图片
                [self uploadFilesWithFileDatas:imageDatas finished:^(BOOL isSuccessed, NSArray *filePaths, NSString * _Nonnull code, NSString * _Nonnull message) {
                    if (isSuccessed == NO) {
                        if (finished) finished(NO,message);
                        //清空七牛token
                        [UserManager sharedUserManager].qiNiuToken = @"";
                        *stop = YES;
                        return;
                    }
                    count --;
                    [newPhotos addObjectsFromArray:filePaths];
                    
                    //将已经上传完成的控件的值更新 - 用于提交
                    model.content = [ZCTool objectToJson:newPhotos];
                    
                    if (count == 0) {
                        if (finished) finished(YES,message);
                        //清空七牛token
                        [UserManager sharedUserManager].qiNiuToken = @"";
                        *stop = YES;
                    }
                }];
            }];
        }];
    }];
}

#pragma mark - ————— 批量上传图片到七牛服务器 —————
/**
 批量上传图片到七牛服务器
 
 @param fileDatas 图片数据源
 @param finished 完成回调
 */
+(void)uploadMultFileToQiNiuServiceWithFileDatas:(NSArray *)fileDatas finished:(ZCRequiredFinished)finished{
    
    NSString *qiNiuToken = kSTRING([UserManager sharedUserManager].qiNiuToken);
    if (qiNiuToken.length == 0) {
        [self getQnTokenWithFinished:^(BOOL isSuccessed,NSString *qiNiuToken ,NSString * _Nonnull code, NSString * _Nonnull message) {
            //获取token失败
            if (isSuccessed == NO) {
                if (finished) finished(isSuccessed,nil,@"",message);
                return;
            }
            
            //获取到token - 上传到七牛
            [self uploadFilesWithFileDatas:fileDatas finished:^(BOOL isSuccessed, id  _Nonnull result, NSString * _Nonnull code, NSString * _Nonnull message) {
                [UserManager sharedUserManager].qiNiuToken = @"";
                if (finished) finished(isSuccessed,result,code,message);
            }];
        }];
    }else{
        [self uploadFilesWithFileDatas:fileDatas finished:^(BOOL isSuccessed, id  _Nonnull result, NSString * _Nonnull code, NSString * _Nonnull message) {
            //清空七牛token
            [UserManager sharedUserManager].qiNiuToken = @"";
            if (finished) finished(isSuccessed,result,code,message);
        }];
    }
}

/**
 上传图片
 */
+(void)uploadFilesWithFileDatas:(NSArray *)fileDatas finished:(ZCRequiredFinished)finished{
    
    NSString *qiNiuToken = kSTRING([UserManager sharedUserManager].qiNiuToken);
    //记录上传张数
    NSMutableArray *filePaths = [[NSMutableArray alloc] init];
    
    //获取成功,调用七牛上传服务
    QNUploadManager *upManager = [[QNUploadManager alloc] init];
    [fileDatas enumerateObjectsUsingBlock:^(NSData *data, NSUInteger idx, BOOL * _Nonnull stop) {
        
        // 上传的key - 文件名
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyyMMddHHmmss";
        NSString *str = [formatter stringFromDate:[NSDate date]];
        int y = 100000 +  (arc4random() % 100001);
        NSString *fileName = [NSString stringWithFormat:@"zcMerchantApp/%d%@.jpg", y , str];
        
        [upManager putData:data key:fileName token:qiNiuToken
                  complete: ^(QNResponseInfo *info, NSString *filePath, NSDictionary *resp) {
                      //任何一张上传失败,返回失败
                      if (info.ok == NO) {
                          if (finished) finished(NO,nil,@"",@"图片上传失败");
                          *stop = YES;
                      }
                      //成功上传一张
                      [filePaths addObject:filePath];
                      NSLog(@"======= %@上传完成",fileName);
                      //全部上传完成
                      if (idx == fileDatas.count - 1) {
                          if (finished) finished(YES,filePaths,@"0",@"图片上传成功");
                      }
                  } option:nil];
    }];
}

/**
 获取七牛上传服务token
 */
+(void)getQnTokenWithFinished:(ZCRequiredFinished)finished{
    //已经保存了token
    __block NSString *qiNiuToken = kSTRING([UserManager sharedUserManager].qiNiuToken);
    if (qiNiuToken.length > 0) {
        if (finished) finished(YES,qiNiuToken,@"0",@"获取token成功");
        return;
    }
    //没有token去获取
    NSString *url = [NSString stringWithFormat:@"%@%@",URL_main,URL_get_qnToken];
    [self requestWithUrl:url method:POST params:@{} finished:^(BOOL isSuccessed, id  _Nonnull result, NSString * _Nonnull code, NSString * _Nonnull message) {
        if (isSuccessed == NO) {
            if (finished) finished(isSuccessed,result,code,message);
            return;
        }
        
        //保存token
        qiNiuToken = kSTRING(result[@"data"][@"token"]);
        [UserManager sharedUserManager].qiNiuToken = qiNiuToken;
        //获取成功
        if (finished) finished(isSuccessed,qiNiuToken,code,message);
    }];
}

/**
 处理网络请求结果
 
 @param response 响应体
 @param error 错误
 */
+(void)handleResultWithResponse:(id)response error:(NSError *)error
                       finished:(ZCRequiredFinished)finished{
    BOOL isSessionOut =  [kSTRING(error.localizedDescription) containsString:@"401"];
    //请求错误
    if (error && !isSessionOut) {
        NSString *message = [self getNetworkErrorMessageWith:error.code];
        if (finished) finished(NO,@"",@"",message);
        return;
    }
    
    //会话过期
    if (isSessionOut) {
        //清理token缓存
        [[NSUserDefaults standardUserDefaults] setObject:@"" forKey:@"merchant_token"];
        [[UserManager sharedUserManager] clearUserInfo];
        kShowToast(@"登录已过期,请重新登录");
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            KPostNotification(KNotificationLoginStateChange, @NO);
        });
        return;
    }
    
    //校验数据格式
    if (response == nil || ![response isKindOfClass:[NSDictionary class]]) {
        if (finished) finished(NO,response,@"",kRequestFaildMessage);
        return;
    }
    //校验code码是否正常
    NSString *code = response[@"Code"];
    if (code.length == 0) {
        code = kSTRING(response[@"status"]);
    }
    NSString *message = kSTRING(response[@"Message"]);
    if (message.length == 0) {
        message = kSTRING(response[@"msg"]).length > 0 ? kSTRING(response[@"msg"]):kRequestFaildMessage;
    }
    
    if (![code isEqualToString:@"OK"] && ![code isEqualToString:@"1"]) {
        if (finished) finished(NO,response,code,message);
        return;
    }

    //请求成功回调
    if (finished) finished(YES,response,code,message);
}

/**
 解析错误码
 
 @param code 返回提示
 */
+(NSString *)getNetworkErrorMessageWith:(NSInteger)code{
    NSString *errorMesg = kRequestFaildMessage;
    if(![self checkNetWork])//没有网络
    {
        return kWithoutNetworkMessage;
    }
    
    switch (code) {
        case -1001://NSURLErrorTimedOut
            errorMesg = @"网络请求超时";
            break;
        case -1005://NSURLErrorNetworkConnectionLost
            errorMesg = @"网络连接异常";
            break;
        case -1011://NSURLErrorBadServerResponse
            errorMesg = @"服务忙,请稍后再试";
            break;
        case -999://请求被取消了不提示
            errorMesg = @"";
            break;
    }
    return errorMesg;
}

#pragma mark -
#pragma mark - ================<网络、其他校验>===============
/**
 网络检查
 
 @return YES-有网络 NO-无网络
 */
+(BOOL)checkNetWork{
    
    BOOL isHaveNet = YES;
    Reachability *r = [Reachability reachabilityWithHostName:URL_main];
    switch ([r currentReachabilityStatus]) {
        case NotReachable:{
            isHaveNet = NO;
            break;
        }
        case ReachableViaWiFi: case ReachableViaWWAN:{
            isHaveNet = YES;
            break;
        }
        default:{
            break;
        }
    }
    return isHaveNet;
}

@end