//
//  ZJBaseHttpManager.m
//  HDMall
//
//  Created by Javen on 2017/7/27.
//  Copyright © 2017年 上海勾芒信息科技. All rights reserved.
//

#import "ZJBaseHttpManager.h"
#import "AFNetworking.h"
#import "ZJShowLogView.h"
#import "JSONKit.h"
#import "ZJBaseFileModel.h"
@interface ZJBaseHttpManager ()
@property (nonatomic, strong) AFHTTPSessionManager *manager;

@end
@implementation ZJBaseHttpManager

+ (ZJBaseHttpManager *)shareCilent {
    static ZJBaseHttpManager *cilent;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        cilent = [[ZJBaseHttpManager alloc] init];
        cilent.debugLogEnabled = NO;
    });
    return cilent;
}

- (AFHTTPSessionManager *)manager {
    if (!_manager) {
        _manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:REST_BASE_URL]];
        _manager.responseSerializer = [AFJSONResponseSerializer serializer];
        _manager.requestSerializer = [AFJSONRequestSerializer serializer];
        [_manager.requestSerializer setValue:@"application/json;charset=utf-8"
                          forHTTPHeaderField:@"Content-Type"];
        [_manager.requestSerializer setValue:@"close" forHTTPHeaderField:@"Connection"];
        [_manager.requestSerializer setValue:@"application/json;charset=utf-8"
                          forHTTPHeaderField:@"Accept"];
        _manager.requestSerializer.timeoutInterval = 120.0f;
    }
    return _manager;
}

/**
 设置证书（https）请求需要用到
 */
- (void)setSecurityPolicy {
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    // allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO

    // 如果是需要验证自建证书，需要设置为YES

    securityPolicy.allowInvalidCertificates = YES;

    //validatesDomainName 是否需要验证域名，默认为YES；
    //假如证书的域名与你请求的域名不一致，需把该项设置为NO；如设成NO的话，即服务器使用其他可信任机构颁发的证书，也可以建立连接，这个非常危险，建议打开。
    //置为NO，主要用于这种情况：客户端请求的是子域名，而证书上的是另外一个域名。因为SSL证书上的域名是独立的，假如证书上注册的域名是www.google.com，那么mail.google.com是无法验证通过的；当然，有钱可以注册通配符的域名*.google.com，但这个还是比较贵的。
    //如置为NO，建议自己添加对应域名的校验逻辑。

    securityPolicy.validatesDomainName = NO;
    [_manager setSecurityPolicy:securityPolicy];
}

- (void)POST:(NSString *)URLString
    parameters:(id)parameters
      complete:(void (^)(id responseObject, NSError *error))complete {
    HIDE_KEYBOARD;
    NSString *url = [URLString
        encodeUTF8];
    WS(weakSelf);
    [self.manager POST:url
        parameters:parameters
        progress:nil
        success:^(NSURLSessionDataTask *task,
                  id responseObject) {

            [weakSelf logWithUrl:URLString Method:@"POST" param:parameters respones:responseObject];
            complete(responseObject, nil);
        }
        failure:^(NSURLSessionDataTask *task, NSError *error) {
            complete(nil, error);
            [weakSelf logWithUrl:URLString Method:@"POST" param:parameters respones:error];

        }];
}

- (void)GET:(NSString *)URLString
 parameters:(id)parameters
   complete:(void (^)(id responseObject, NSError *error))complete {
    HIDE_KEYBOARD;
    WS(weakSelf);
    [self.manager GET:URLString
           parameters:parameters
             progress:nil
              success:^(NSURLSessionDataTask *task,
                        id responseObject) {
                  [weakSelf logWithUrl:URLString Method:@"GET" param:parameters respones:responseObject];
                  complete(responseObject, nil);
              }
              failure:^(NSURLSessionDataTask *task, NSError *error) {
                  [weakSelf logWithUrl:URLString Method:@"GET" param:parameters respones:error];
                  complete(nil, error);
              }];
}

- (void)PUT:(NSString *)URLString
    parameters:(id)parameters
      complete:(void (^)(id responseObject, NSError *error))complete {
    HIDE_KEYBOARD;
    WS(weakSelf);
    NSString *url = [URLString
        encodeUTF8];
    [self.manager PUT:url
        parameters:parameters
        success:^(NSURLSessionDataTask *task,
                  id responseObject) {
            [self logWithUrl:URLString Method:@"PUT" param:parameters respones:responseObject];
            complete(responseObject, nil);

        }
        failure:^(NSURLSessionDataTask *task, NSError *error) {
            complete(nil, error);
            [weakSelf logWithUrl:url Method:@"PUT" param:parameters respones:error];

        }];
}

- (void)DELETE:(NSString *)URLString
    parameters:(id)parameters
      complete:(void (^)(id responseObject, NSError *error))complete {
    HIDE_KEYBOARD;
    NSString *url = [URLString encodeUTF8];
    WS(weakSelf);

    [self.manager DELETE:url
        parameters:parameters
        success:^(NSURLSessionDataTask *task, id responseObject) {
            [weakSelf logWithUrl:url Method:@"DELETE" param:parameters respones:responseObject];
            complete(responseObject, nil);
        }
        failure:^(NSURLSessionDataTask *task, NSError *error) {
            complete(nil, error);
            [weakSelf logWithUrl:url Method:@"DELETE" param:parameters respones:error];
        }];
}

/** 上传文件 */
- (void)upLoadFiles:(NSArray<ZJBaseFileModel *> *)files
             params:(NSDictionary *)params
          commplete:(void (^__nullable)(NSMutableArray *attachments))complete{
    if (files.count == 0) {
        complete(nil);
        return;
    }
    WS(weakSelf);
    [self.manager POST:@"media/upload/list" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        for (ZJBaseFileModel *file in files) {
            [formData appendPartWithFileData:file.data            //data
                                        name:file.keyName         //接口key值
                                    fileName:file.name       //文件名称，必须有后缀
                                    mimeType:file.mimeType]; //文件类型，后台接受使用
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        if (kIsResponse) {
            complete(responseObject[@"data"]);
            
        } else {
            kFalseHttpTips;
        }
        
        [weakSelf logWithUrl:@"media/upload/list" Method:@"UPLOAD" param:params respones:responseObject];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [MBProgressHUD j_error:@"上传失败" complete:nil];
        [weakSelf logWithUrl:@"media/upload/list" Method:@"UPLOAD" param:params respones:error];
    }];
}



/**
 打印网络请求的详情
 */
- (void)logWithUrl:(NSString *)URLString Method:(NSString *)method param:(NSDictionary *)param respones:(id)response {
    NSString *jsonString = [param JSONStringWithOptions:JKSerializeOptionPretty error:nil];

    NSString *responseString = nil;
    NSString *isSuccess = nil;
    if ([response isKindOfClass:[NSDictionary class]]) {
        responseString = [response JSONStringWithOptions:JKSerializeOptionPretty error:nil];
        isSuccess = @"SUCCESSED";
    } else if ([response isKindOfClass:[NSError class]]) {
        responseString = [response localizedDescription];
        isSuccess = @"FAILED";

        NSString *errorInfo = [NSString stringWithFormat:@"%@ \n %@\n", URLString, responseString];
        NSString *userInfo = [((NSError *) response).userInfo JSONStringWithOptions:JKSerializeOptionPretty error:nil];
        errorInfo = [errorInfo stringByAppendingString:SAFE_STRING(userInfo)];
        [MBProgressHUD j_error:errorInfo complete:nil];
    }

    NSString *line = @"\n<<<<<<<<<<<<<<<<<<<<<\n\nMETHOD  ";
    NSString *end = @"\n>>>>>>>>>>>>>>>>>>>>>\n\n";
    NSString *msg = [line stringByAppendingString:method];

    msg = [msg stringByAppendingString:[NSString stringWithFormat:@"\n\nURL: %@/%@\n\n", REST_BASE_URL, URLString]];
    msg = [msg stringByAppendingString:[NSString stringWithFormat:@"PARAMS: \n%@\n\n", jsonString]];
    
    msg = [msg stringByAppendingString:[NSString stringWithFormat:@"%@\n\n %@\n", isSuccess, responseString]];
    
    msg = [msg stringByAppendingString:end];
    
//    如果开启debug模式，会在主界面弹出每次请求的详情
    CLog(@"%@", msg);
    if (self.debugLogEnabled) {
        WS(weakSelf);
        [ZJShowLogView showWithLog:msg closeLog:^{
            weakSelf.debugLogEnabled = NO;
        }];
    }
    
    
}

@end
