 //
 
 import Alamofire
+import ObjectMapper
 
 class Networker {
     

        else { onError(NetworkerError(value: responseValue, statusCode: statusCode)) }
    }
    
    private static func callNoReponseError(onError: (Error) -> ()) {
        onError(NetworkerError(message: "No response".localized))
    }
    
    private static func requestJSONMultipard(url: String,
                                             method: HTTPMethod,
                                             params: Parameters,
                                             headers: [String: String]? = nil,

                }
        })
    }
    
    /// Check parameters and make request (can be multipart) with JSON Dictionary response
    ///
    /// - Parameters:
    ///   - url: Full url
    ///   - method: HTTP method
    ///   - params: Parameters
    ///   - encoding: Parameters encoding, if not specified use URLEncoding
    ///   - headers: HTTP headers
    ///   - onSuccess: Closure for success response
    ///   - onError: Closure for error response
    private static func requestJSON(url: String,
                                    method: HTTPMethod,
                                    params: Parameters? = nil,
                                    encoding: ParameterEncoding? = nil,
                                    headers: [String: String]? = nil,
                                    onSuccess: @escaping (_ json: JSON, _ statusCode: Int) -> (),
                                    onError: @escaping (Error) -> ()) {
        // If parameters contain NetworkerFile make multipart request
        if let params = params,
            params.values.contains(where: { $0 is NetworkerFile }) {
            requestJSONMultipart(url: url,
                                 method: method,
                                 params: params,
                                 headers: headers,
                                 onSuccess: onSuccess,
                                 onError: onError)
        } else {
            Alamofire.request(url,
                              method: method,
                              parameters: params,
                              encoding: encoding ?? URLEncoding.default,
                              headers: headers).responseJSON { (dataResponse) in
                                handleAlamofireJSONResponse(dataResponse: dataResponse, onSuccess: { (dictionary, statusCode) in
                                    onSuccess(dictionary, statusCode)
                                }, onError: onError)
            }
        }
    }
    
    /// Make request with JSON Dictionary response
    ///
    /// - Parameters:
    ///   - url: Full url
    ///   - method: HTTP method
    ///   - params: Parameters
    ///   - encoding: Parameters encoding, if not specified use URLEncoding
    ///   - headers: HTTP headers
    ///   - completion: Closure with JSON result
    private static func requestJSON(url: String,
                                    method: HTTPMethod,
                                    params: Parameters? = nil,
                                    encoding: ParameterEncoding? = nil,
                                    headers: [String: String]? = nil,
                                    callback: @escaping (NetworkerJSONResult) -> ()) {
        requestJSON(url: url, method: method, params: params, encoding: encoding, headers: headers, onSuccess: { (json, statusCode) in
            callback(NetworkerJSONResult.success(json))
        }) { (error) in
            callback(NetworkerJSONResult.failure(error))
        }
    }
    
    /// Make request with Mappable response
    ///
    /// - Parameters:
    ///   - url: Full url
    ///   - method: HTTP method
    ///   - params: Parameters
    ///   - encoding: Parameters encoding, if not specified use URLEncoding
    ///   - headers: HTTP headers
    ///   - completion: Closure with Mappable result
    private static func requestMappable<T: Mappable>(url: String,
                                        method: HTTPMethod,
                                        params: Parameters? = nil,
                                        encoding: ParameterEncoding? = nil,
                                        headers: [String: String]? = nil,
                                        callback: @escaping (NetworkerMappableResult<T>) -> ()) {
        requestJSON(url: url, method: method, params: params, encoding: encoding, headers: headers, onSuccess: { (json, statusCode) in
            // Run async because JSON parsing can be slow
            DispatchQueue.global().async {
                let object = T(JSON: json)
                DispatchQueue.main.async {
                    if let object = object {
                        let networkerResponse = NetworkerResponse(statusCode: statusCode, value: json, object: object)
                        callback(NetworkerMappableResult.success(networkerResponse))
                    }
                    else {
                        callback(NetworkerMappableResult.failure(NetworkerError(message: "Can't parse response".localized)))
                    }
                }
            }
        }) { (error) in
            callback(NetworkerMappableResult.failure(error))
        }
    }
}
