//
//  ZTNetworkTools.m
//
//  Created by Company on 2020/6/2.
//  Copyright © 2020 Company. All rights reserved.
//

#import "ZTNetworkTools.h"
//#import "ZJUserInfoManager.h"
#import "Data.h"
#import <CommonCrypto/CommonDigest.h>
#import "AESCipher.h"
#import <sys/utsname.h>

@interface ZTNetworkTools () <NSCopying, NSMutableCopying>

@end

@implementation ZTNetworkTools

#pragma mark - 全局访问点
static ZTNetworkTools* _tools = nil;

+ (instancetype)shared {
    
    static dispatch_once_t onceToken ;
    dispatch_once(&onceToken, ^{
        
        _tools = [[super allocWithZone: NULL] init] ;
        // 设置回掉数据支持的数据类型
        _tools.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/plain",@"text/json",@"text/html",@"text/javascript",@"text/xml",@"application/json",@"application/json;charset=UTF-8",@"*/*", nil];
    }) ;
    return _tools ;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    return [ZTNetworkTools shared];
}

- (id)copyWithZone:(NSZone *)zone{
    return [ZTNetworkTools shared];
}

- (id)mutableCopyWithZone:(NSZone *)zone{
    return [ZTNetworkTools shared];
}

#pragma mark - AFN 封装
// AFN初步封装
// GET 请求
- (void)getWithAction: (TQNetwortGetAction)action parameters:(id)parameters success: (void(^)(id response))success failure:(void(^)(NSError * error)) failure{
    // get 请求
    NSString *urlString = [ServerHost stringByAppendingPathComponent: [self convertGetActionToString:action]];
    
    NSDictionary *params = [self setRequestParams: parameters];
    
    [self GET: urlString parameters: params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"%@ - %@", [self convertGetActionToString:action] ,responseObject);
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(error);
    }];
}

//支付get请求
- (void)getWithPayAction: (TQNetwortGetAction)action parameters:(id)parameters success: (void(^)(id response))success failure:(void(^)(NSError * error)) failure{
    // get 请求
    NSString *urlString = [ServerHost stringByAppendingPathComponent: [self convertGetActionToString:action]];
    
    NSDictionary * params = [self setRequestParams: parameters];
    
    [self GET: urlString parameters: params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(error);
    }];
}


// POST 请求
- (void)postWithAction: (TQNetwortPostAction)action parameters:(id)parameters success: (void(^)(id response))success failure:(void(^)(NSError * error)) failure{
    
    [self postWithAction:(TQNetwortPostAction)action parameters:(id)parameters fileDic:@{}.mutableCopy progress:nil success:success failure:failure];
}

// POST 请求
- (void)postWithAction: (TQNetwortPostAction)action parameters:(id)parameters fileDic:(NSMutableDictionary *)fileDic progress:(void(^)(id progress))progress success:(void(^)(id response))success failure:(void(^)(NSError * error)) failure{
    // post 请求
    NSString *urlString = [ServerHost stringByAppendingPathComponent: [self convertPostActionToString:action]];
    
    urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    
    NSDictionary *params = [self setRequestParams: parameters];
    [self POST: urlString parameters: params headers:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        success(responseObject);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        failure(error);
    }];
}


+ (NSString *)dicToJson:(NSDictionary *)params{
    
    NSArray * keyArr = params.allKeys;
    
    NSArray * newArr = [keyArr sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        
        return [obj1 compare:obj2 options:NSLiteralSearch];
        //return [obj1 compare:obj2];
    }];
    
    NSMutableString * string = [NSMutableString string];
    
    for (int j = 0; j< newArr.count;j++) {
        
        if (j == 0) {
            [string appendFormat:@"%@=%@&",newArr[j],[params objectForKey:newArr[j]]];
        }
        else{
            [string appendFormat:@"%@=%@&",newArr[j],[params objectForKey:newArr[j]]];
        }
    }
    
    string = [string substringToIndex:string.length-1].mutableCopy;
    
    return string;
}

/// 请求动作
/// @param action GET 动作枚举
- (NSString*) convertGetActionToString: (TQNetwortGetAction) action {
    switch(action) {
        
        case userInfo:
            return @"/app/v1/location/user/info";
        case appServiceInfo:
            return @"/app/v1/novel/info";
        case getIPAPayConfig:
            return @"/app/v1/location/user/pay-config";
        default:
            return @"";
    }
}

/// 请求动作
/// @param action POST 动作枚举
- (NSString*) convertPostActionToString: (TQNetwortPostAction) action {
    switch(action) {
        case touristLogin:
            return @"/app/v1/auth/tourist-login";
            //支付验证
        case iosIPAVerifyReceipt:
            return @"/app/v1/location/pay/ios-verify-receipt";
        case logCollection:
            return @"/logCollection/log/v1/userLogCollection";
        default:
            return @"";
    }
}

// POST 请求
- (void)postWithLogCollection: (TQNetwortPostAction)action parameters:(id) parameters success: (void(^)(id *response))success failure:(void(^)(NSError * error)) failure {
    
    // post 请求
    NSString *urlString = [ServerReport stringByAppendingPathComponent: [self convertPostActionToString:action]];
    
    NSDictionary *dic= parameters;
    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingFragmentsAllowed error:nil];
    NSString *jsonString =[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"ZJAESCommonjsonString成功了 %@", jsonString);
    
    NSString *encryptStr = aesEncryptString(jsonString, aesKey);

    NSMutableDictionary *mutaDict = @{}.mutableCopy;

    NSDictionary *ddd = [self setRequestParams: mutaDict];
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    
    NSString *aaa = @"";
    for (NSString *key in ddd.allKeys) {
        NSString *bb = [key stringByAppendingFormat:@"=%@", ddd[key]];
        aaa = [aaa stringByAppendingFormat:@"&%@", bb];
    }
    
    NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString: [urlString stringByAppendingFormat:@"?%@", aaa]  parameters:nil error:nil];
    req.timeoutInterval= 10;
    [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [req setValue:@"application/json" forHTTPHeaderField:@"Accept"];

    [req setHTTPBody:[encryptStr dataUsingEncoding: NSUTF8StringEncoding]];
    NSLog(@"ZJAESCommonDecrypt----成功了 %@", [encryptStr dataUsingEncoding: NSUTF8StringEncoding]);
//    NSLog(@"NSJSONSerialization成功了%@", dd);
    [[manager dataTaskWithRequest:req uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        NSLog(@"post成功了%@", responseObject);
    }] resume];
}

//支付验证
// POST 请求
- (void)postWithBodyAction: (TQNetwortPostAction)action parameters:(id) parameters body: (id)body success: (void(^)(NSDictionary *response))success failure:(void(^)(NSError * error)) failure {
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    
    // post 请求
    NSString *urlString = [ServerHost stringByAppendingPathComponent: [self convertPostActionToString:action]];
    //
    NSMutableDictionary *mutaDict = ((NSDictionary *)parameters).mutableCopy;

    NSDictionary *ddd = [self setRequestParams: mutaDict];
    
    NSString *aaa = @"";
    for (NSString *key in ddd.allKeys) {
        NSString *bb = [key stringByAppendingFormat:@"=%@", ddd[key]];
        aaa = [aaa stringByAppendingFormat:@"&%@", bb];
    }
    
    NSMutableURLRequest *req = [[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString: [urlString stringByAppendingFormat:@"?%@", aaa]  parameters:nil error:nil];
    req.timeoutInterval= 10;
    [req setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [req setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    //    NSMutableData *postBodyData = [NSMutableData data];
    
    NSDictionary *dic= body;
    NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
    
    NSString *dd = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingFragmentsAllowed error:nil];
    //    [postBodyData appendData:[@"key=value" dataUsingEncoding:NSUTF8StringEncoding]];
    [req setHTTPBody:data];
    
    NSLog(@"NSJSONSerialization成功了%@", dd);
    [[manager dataTaskWithRequest:req uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id  _Nullable responseObject, NSError * _Nullable error) {
        NSLog(@"post成功了%@", responseObject);
        if ([[responseObject valueForKey:@"status"] intValue] == 200) {
            success(responseObject);
        } else {
            failure(error);
            NSLog(@"post失败了%@",error);
        }
    }] resume];
}


- (NSDictionary*)setRequestParams: (NSDictionary *)params {
    
    NSMutableDictionary * dict = (NSMutableDictionary *)[params mutableCopy];
    [dict setValue: @(UIScreen.mainScreen.bounds.size.height) forKey: @"h"];
    [dict setValue: @(UIScreen.mainScreen.bounds.size.width) forKey: @"w"];
    
    [dict setValue: [[self deviceName] stringByReplacingOccurrencesOfString: @" " withString:@"-"] forKey: @"model"];
    
    // version code
    [dict setValue: [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] forKey: @"vc"];
    // version name
    [dict setValue: @"QuickCleaner" forKey: @"vn"];
    // platform
    [dict setValue: @"ios" forKey: @"platform"];
    
    [dict setValue: @"AppStore" forKey: @"source"];
    [dict setValue: @"behavior" forKey: @"module"];
    
    // UID
    Data *data = [[Data alloc] init];
    // idfa
    if ([[data Read] objectForKey:@"idfa"]) {
         [dict setValue: [[data Read] objectForKey:@"idfa"] forKey: @"idfa"];
    }
    
    NSString *uid = [[data Read] objectForKey:@"uid"];
    if (uid != nil) { [dict setValue: uid forKey: @"uid"]; }
//    // token
    NSString *token = [[data Read] objectForKey:@"token"];
    if (token != nil) { [dict setValue: token forKey: @"token"]; }
    
    //唯一标识符
    NSString *identifierForVendor = [[data Read] objectForKey:@"Identifier"];;
    [dict setValue: identifierForVendor forKey: @"device"];
    
    NSLog(@"identifierForVendor info == %@", identifierForVendor);
    // 获取BundleID
    [dict setValue: [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"] forKey: @"pkg"];
    
    // 设置时间戳
    NSTimeInterval today = [[NSDate date] timeIntervalSince1970] * 1000;
    NSString *intervalString = [NSString stringWithFormat:@"%.0f", today];
    [dict setValue: intervalString forKey: @"ts"];
    
    if (ICUserManager.shared.network != nil) {
        [dict setValue: ICUserManager.shared.network forKey: @"ntt"];
    }
    
    [dict setValue: @"Safari" forKey: @"ua"];
    [dict setValue: UIDevice.currentDevice.systemVersion forKey:@"svn"];
    
    //appLs
    [dict setValue: @"71b221c60431edfa" forKey: @"appLs"];
    
    // LANGUAGE //lang=en_US
    NSString *language = [[NSLocale preferredLanguages] firstObject];
    if ([language containsString: @"zh"]) {
        [dict setValue: @"zh_CN" forKey: @"lang"];
    } else {
        [dict setValue: @"en_US" forKey: @"lang"];
    }
    [dict addEntriesFromDictionary:[self signParams:dict]];
    
    NSLog(@"parameters info == %@", dict);
    return dict;
}

#pragma mark -- 排序
- (NSDictionary *)signParams:(NSDictionary *)params{
    
    NSArray * keyArr = params.allKeys;
    
    NSArray * newArr = [keyArr sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {
        
        return [obj1 compare:obj2 options:NSLiteralSearch];
    }];
    
    NSMutableString * String = [NSMutableString string];
    
    for (int j = 0; j < newArr.count ; j++) {
        if (j == 0) {
            [String appendFormat:@"%@",[params objectForKey:newArr[j]]];
        } else{
            [String appendFormat:@"%@",[params objectForKey:newArr[j]]];
        }
    }
    
    String = [String substringToIndex:String.length].mutableCopy;
        
    NSString * fristSalt = [self stringToMD5:[NSString stringWithFormat:@"%@%@", String, @"HXHJ4KDL1QPFHGA0"]];
    NSString * secondSalt = [self stringToMD5:[NSString stringWithFormat:@"%@%@", fristSalt, @"ZJQJQ66AH9COTXSU"]];
    NSString * rusult  = [secondSalt substringToIndex:16];
    
    return @{@"sign":rusult};
}



- (NSString *)stringToMD5:(NSString *)str {
    
    // 1.首先将字符串转换成UTF-8编码, 因为MD5加密是基于C语言的,所以要先把字符串转化成C语言的字符串
    const char *fooData = [str UTF8String];
    
    // 2.然后创建一个字符串数组,接收MD5的值
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    // 3.计算MD5的值, 这是官方封装好的加密方法:把我们输入的字符串转换成16进制的32位数,然后存储到result中
    CC_MD5(fooData, (CC_LONG)strlen(fooData), result);
    
    /*
     第一个参数:要加密的字符串
     第二个参数: 获取要加密字符串的长度
     第三个参数: 接收结果的数组
     */
    
    // 4.创建一个字符串保存加密结果
    NSMutableString *saveResult = [NSMutableString string];
    // 5.从result 数组中获取加密结果并放到 saveResult中
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [saveResult appendFormat:@"%02x", result[i]];
    }
    // x表示十六进制，%02X  意思是不足两位将用0补齐，如果多余两位则不影响
    /*
     这里返回的是32位的加密字符串，有时我们需要的是16位的加密字符串，其实仔细观察即可发现，16位的加密字符串就是这个字符串中见的部分。我们只需要截取字符串即可（[saveResult substringWithRange:NSMakeRange(7, 16)]）
     */
    return saveResult; //[saveResult substringWithRange:NSMakeRange(0, 15)];
}


- (NSString*) deviceName
{
    struct utsname systemInfo;

    uname(&systemInfo);

    NSString* code = [NSString stringWithCString:systemInfo.machine
                                        encoding:NSUTF8StringEncoding];

    static NSDictionary* deviceNamesByCode = nil;

    if (!deviceNamesByCode) {

        deviceNamesByCode = @{@"i386"      : @"Simulator",
                              @"x86_64"    : @"Simulator",
                              @"iPod1,1"   : @"iPod Touch",        // (Original)
                              @"iPod2,1"   : @"iPod Touch",        // (Second Generation)
                              @"iPod3,1"   : @"iPod Touch",        // (Third Generation)
                              @"iPod4,1"   : @"iPod Touch",        // (Fourth Generation)
                              @"iPod7,1"   : @"iPod Touch",        // (6th Generation)
                              @"iPhone1,1" : @"iPhone",            // (Original)
                              @"iPhone1,2" : @"iPhone",            // (3G)
                              @"iPhone2,1" : @"iPhone",            // (3GS)
                              @"iPad1,1"   : @"iPad",              // (Original)
                              @"iPad2,1"   : @"iPad 2",            //
                              @"iPad3,1"   : @"iPad",              // (3rd Generation)
                              @"iPhone3,1" : @"iPhone 4",          // (GSM)
                              @"iPhone3,3" : @"iPhone 4",          // (CDMA/Verizon/Sprint)
                              @"iPhone4,1" : @"iPhone 4S",         //
                              @"iPhone5,1" : @"iPhone 5",          // (model A1428, AT&T/Canada)
                              @"iPhone5,2" : @"iPhone 5",          // (model A1429, everything else)
                              @"iPad3,4"   : @"iPad",              // (4th Generation)
                              @"iPad2,5"   : @"iPad Mini",         // (Original)
                              @"iPhone5,3" : @"iPhone 5c",         // (model A1456, A1532 | GSM)
                              @"iPhone5,4" : @"iPhone 5c",         // (model A1507, A1516, A1526 (China), A1529 | Global)
                              @"iPhone6,1" : @"iPhone 5s",         // (model A1433, A1533 | GSM)
                              @"iPhone6,2" : @"iPhone 5s",         // (model A1457, A1518, A1528 (China), A1530 | Global)
                              @"iPhone7,1" : @"iPhone 6 Plus",     //
                              @"iPhone7,2" : @"iPhone 6",          //
                              @"iPhone8,1" : @"iPhone 6S",         //
                              @"iPhone8,2" : @"iPhone 6S Plus",    //
                              @"iPhone8,4" : @"iPhone SE",         //
                              @"iPhone9,1" : @"iPhone 7",          //
                              @"iPhone9,3" : @"iPhone 7",          //
                              @"iPhone9,2" : @"iPhone 7 Plus",     //
                              @"iPhone9,4" : @"iPhone 7 Plus",     //
                              @"iPhone10,1": @"iPhone 8",          // CDMA
                              @"iPhone10,4": @"iPhone 8",          // GSM
                              @"iPhone10,2": @"iPhone 8 Plus",     // CDMA
                              @"iPhone10,5": @"iPhone 8 Plus",     // GSM
                              @"iPhone10,3": @"iPhone X",          // CDMA
                              @"iPhone10,6": @"iPhone X",          // GSM
                              @"iPhone11,2": @"iPhone XS",         //
                              @"iPhone11,4": @"iPhone XS Max",     //
                              @"iPhone11,6": @"iPhone XS Max",     // China
                              @"iPhone11,8": @"iPhone XR",         //
                              @"iPhone12,1": @"iPhone 11",         //
                              @"iPhone12,3": @"iPhone 11 Pro",     //
                              @"iPhone12,5": @"iPhone 11 Pro Max", //

                              @"iPad4,1"   : @"iPad Air",          // 5th Generation iPad (iPad Air) - Wifi
                              @"iPad4,2"   : @"iPad Air",          // 5th Generation iPad (iPad Air) - Cellular
                              @"iPad4,4"   : @"iPad Mini",         // (2nd Generation iPad Mini - Wifi)
                              @"iPad4,5"   : @"iPad Mini",         // (2nd Generation iPad Mini - Cellular)
                              @"iPad4,7"   : @"iPad Mini",         // (3rd Generation iPad Mini - Wifi (model A1599))
                              @"iPad6,7"   : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1584)
                              @"iPad6,8"   : @"iPad Pro (12.9\")", // iPad Pro 12.9 inches - (model A1652)
                              @"iPad6,3"   : @"iPad Pro (9.7\")",  // iPad Pro 9.7 inches - (model A1673)
                              @"iPad6,4"   : @"iPad Pro (9.7\")"   // iPad Pro 9.7 inches - (models A1674 and A1675)
                              };
    }

    NSString* deviceName = [deviceNamesByCode objectForKey:code];

    if (!deviceName) {
        // Not found on database. At least guess main device type from string contents:

        if ([code rangeOfString:@"iPod"].location != NSNotFound) {
            deviceName = @"iPod Touch";
        }
        else if([code rangeOfString:@"iPad"].location != NSNotFound) {
            deviceName = @"iPad";
        }
        else if([code rangeOfString:@"iPhone"].location != NSNotFound){
            deviceName = @"iPhone";
        }
        else {
            deviceName = @"Unknown";
        }
    }

    return deviceName;
}

@end
