//
//  NetService.m
//  Gengmei
//
//  Created by Thierry on 1/5/15.
//  Copyright (c) 2015 Wanmeichuangyi. All rights reserved.
//

#import "WMNetService.h"
#import "GMHTTPSessionManager.h"
#import "Utils.h"

@implementation WMNetService

+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    static id instance = nil;
    dispatch_once(&onceToken, ^{
        instance = [[[self class] alloc] init];
    });

    return instance;
}

- (void)sendRequestWithURLString:(NSString *)URLString
                      parameters:(id)parameters
                          method:(HttpMethod)method
                         success:(HttpSuccessBlock)success
                          failed:(HttpFailedBlock)failed {
    [self startRequestWithNetworking: _networking URLString:URLString parameters:parameters method:method success:success failed:failed];
}


- (void)sendUploadTaskRequestWithData:(NSData *)data
                             fileName:(NSString *)fileName
                                 name:(NSString*)name
                                  url:(NSString*)url
                             mineType:(NSString *)mineType
                           parameters:(NSDictionary *)parameters
                              success:(HttpSuccessBlock)success
                               failed:(HttpFailedBlock)failed {
    NSString *resultUrl = nil;
    resultUrl = [url stringByAppendingString:_urlCommonParameters];
    NSString * URLString = [[NSURL URLWithString:resultUrl relativeToURL:[NSURL URLWithString:_apiHost]] absoluteString];
    [self startUploadTaskRequestWithData:data fileName:fileName name:name URLString:URLString mineType:mineType parameters:parameters success:success failed:failed];
}

#pragma mark - pravite method
- (void)startRequestWithNetworking:(AFHTTPSessionManager*)networking
                         URLString:(NSString *)URLString
                       parameters:(id)parameters
                           method:(HttpMethod)method
                          success:(HttpSuccessBlock)success
                           failed:(HttpFailedBlock)failed{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    if (self.beforeAction) {
        _beforeAction();
    }
    
    NSString *fullUrlString = [NSString stringWithFormat:@"%@%@%@", self.apiHost, URLString, self.urlCommonParameters];
    
    if (method == HttpMethodGet) {
        [networking GET:fullUrlString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
            [self successWithTask:task responseObject:responseObject success:success];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [self failureWithTask:task error:error failed:failed];
        }];
        
    }else if (method == HttpMethodPost){
        [networking POST:fullUrlString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
            [self successWithTask:task responseObject:responseObject success:success];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [self failureWithTask:task error:error failed:failed];
        }];
        
    }else if (method == HttpMethodDelete){
        [networking DELETE:fullUrlString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
            [self successWithTask:task responseObject:responseObject success:success];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [self failureWithTask:task error:error failed:failed];
        }];
        
    }else if (method == HttpMethodPatch){
        [networking PATCH:fullUrlString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
            [self successWithTask:task responseObject:responseObject success:success];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [self failureWithTask:task error:error failed:failed];
        }];
        
    }else if (method == HttpMethodPut){
        [networking PUT:fullUrlString parameters:parameters success:^(NSURLSessionDataTask *task, id responseObject) {
            [self successWithTask:task responseObject:responseObject success:success];
        } failure:^(NSURLSessionDataTask *task, NSError *error) {
            [self failureWithTask:task error:error failed:failed];
        }];
    }
}

- (void)startUploadTaskRequestWithData:(NSData *)data
                              fileName:(NSString *)fileName
                                  name:(NSString*)name
                             URLString:(NSString*)URLString
                              mineType:(NSString *)mineType
                            parameters:(NSDictionary *)parameters
                               success:(HttpSuccessBlock)success
                                failed:(HttpFailedBlock)failed{

    NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:URLString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        //没有指定name的时候,name不能为空，默认填充 @"file" 即可
        [formData appendPartWithFileData:data name:name fileName:fileName mimeType:mineType];
    } error:nil];
    request.timeoutInterval = 30;
    if (self.beforeUploadAction) {
        NSDictionary *httpHeader = self.beforeUploadAction();
        [request setValue:[httpHeader objectForKey:@"Cookie"] forHTTPHeaderField:@"Cookie"];
    }
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    });
    NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:NULL completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) {
        if (error) {
            [self failureWithTask:nil error:error failed:failed];
        } else {
            [self successWithTask:nil responseObject:responseObject success:success];
        }
    }];
    
    [uploadTask resume];
    
}


#pragma mark - deal with successTask and FailedTask
- (void)successWithTask:(NSURLSessionDataTask *)task
         responseObject:(id)responseObject
                success:(HttpSuccessBlock)success{
    
    dispatch_async(dispatch_get_main_queue(), ^{
        if (success) {
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            success(responseObject);
            if (self.handleResponse) {
                _handleResponse(responseObject);
            }
        }
    });
}

- (void)failureWithTask:(NSURLSessionDataTask *)task
                  error:(NSError *)error
                 failed:(HttpFailedBlock)failed{
    
    dispatch_async(dispatch_get_main_queue(), ^{
        if (failed) {
            [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
            NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response;
            NSURLRequest *request = task.originalRequest;
            
            NSInteger statusCode = response.statusCode;
            NSString *errorStr = [NSString stringWithFormat:@"%@ %ld: %@ %@",request.URL.path, (long)statusCode, [error localizedFailureReason],[error localizedDescription]];
            // TODO: 可以根据不同的statusCode返回不同的提示
            if(statusCode == HttpStatusCodeUnauthorized){
                [[NSNotificationCenter defaultCenter] postNotificationName:_loginExpiredName object:nil];
            } else {
                errorStr = [NSString stringWithFormat:@"网络错误: %ld", statusCode];
                debugLog(@"%@", errorStr);
            }
            failed(errorStr);
        }
    });
}

#pragma mark - setter

- (void)setApiHost:(NSString *)apiHost{
    _apiHost = apiHost;
    _networking = [GMHTTPSessionManager shareInstanceWithApiHost:_apiHost];
}

@end
