//
//  YHNetRequest.swift
//  galaxy
//
//  Created by EDY on 2023/12/20.
//

import Foundation
import Alamofire
import CryptoSwift
import UIKit

//class YHNetErrorModel {
//    var responseStatusCode: Int = 0
//    var responseStatusCodeStr: String = ""
//    var errResponseMsg: String = ""
//    var errReaponseCode: String = ""
//    var errReaponseTimeOutCode: Int = 0
//    var responseErrorType: NetResponseErrorType = .failType
//}

//定义客户端通用的错误码
public enum YHErrorCode : Int32 {
    case success = 0
    case networkFail = -1
    case unknowError = -10000
    case dictParseError = -10001
    
    public func description() -> String {
        switch self {
        case .success:
            return "成功"
        case .networkFail:
            return "网络不可用"
        case .unknowError:
            return "未知错误"
        case .dictParseError:
            return "字典解析错误"
        default:
            return "未知"
        }
    }
}


public struct YHErrorModel {
    var errorCode : Int32 = YHErrorCode.unknowError.rawValue
    var errorMsg : String = YHErrorCode.unknowError.description()
}

class YHNetRequest: NSObject {
    ///成功回调
    typealias SuccessHandlerType = (([String:Any],Int) ->Void)
    ///失败回调
    typealias FailureHandlerType = ((YHErrorModel) -> Void)
    ///请求类型
    private var requestType: HTTPMethod = .post
    ///  URL
    private var url: String?
    ///  参数
    private var params: [String:Any]?
    ///  成功的回调
    private var success: SuccessHandlerType?
    ///  失败的回调
    private var failure: FailureHandlerType?
    ///  headers 设置
    private var headers: HTTPHeaders?
    ///  数据请求
    private var httpRequest: DataRequest?
    
    override init() {
        super.init()
        
        
        var requestHeader = HTTPHeaders()
        
        requestHeader.add(name:"Conatent-Type",value:"application/json")
        requestHeader.add(name:"Accept",value:"application/json")
        
        
        
        /*
         以下是测试数据 for test hjl
         */
        requestHeader.add(name:"appid",value:"1")
        let dateStr = String(Date().timeIntervalSince1970)
        requestHeader.add(name:"timestamp",value:dateStr)
        
        requestHeader.add(name:"pass",value:"")
        let appkey = "958364f87222c200a72414f492bf0e26"
        let signOrgiString = "appid=" + "1" + "&" + "timestamp=" + dateStr + "&" + "appkey=" + appkey
        let sign = signOrgiString.md5()
        print("sign = \(sign)")
        
        requestHeader.add(name:"sign",value:sign)
//        requestHeader.add(name: "token", value: YHLoginManager.shared.userModel?.token ?? "-") //for test hjl
        
        requestHeader.add(name: "token", value: "eyJpdiI6InhISTlXZjA2cXE5Z2pqMDZDa2NrTkE9PSIsInZhbHVlIjoiR3NkRVR0dVdjWE5GN2N3UmNiU0xobVYzZTR6SXlGXC9XVEhWV0xcL1F1YXVBOU9jRDlFZ2pOanBcL1RBMUVkUDlRQ2xhREx0c3dKeHNJQjMwaVVuYkloZHBiUXQzZkJlS2dTWDJrTE90K2FpM0FDWm10a3FFUGZpdW90TDNscStud0tSenRRV2kyV3JVbEZ6eXppUHZ5ajFQMXpBejh0YUZ4Z0VPZkwwdEtwXC9mNjh4bWQySGpSS2pzVkJ1Y3ZrbGFKdGVsMkhkRXJrTlRHbzkxcVdkcE1yWXRja2xDRHVmRUhhdU9ybkJmXC9VRVJnY2RXeVpXMzZVc2h2eUsxYVRmSXR0QXB1WjVsaDBLTllVOEtKWUhSTE5yNXFvYWlaQzdQSWZ0T0V2VTZwTFJjb25OZGdYbE1lNHZOZ0ZWcWhWWkhnUm8rWGJqSE1Jdm1DY3hlWVliY2F0YkplZFwvQ0pMMndtdHFBQUF0MjJYTFNZYk14Tzh0d0g1K2c2M1U2bXFZY3JUbXptbEhCSXR5R3hFZ0JHNmpXTHgzeTJvc0Z2UXpENk5LOTlBN0VjWE8rNmYzTklBN3d0YVVPb2VyS0lNK3FINUZlTmR6UTlBdENuZEtDKzE3emwxMGxvaEc1Sm1mc0E3Y251cU5xcjd4ZzdSbHNNQ2xoRUc4VUJTR24zQ1lRSE5VRGtUd0s0ZTljSlRxRmdwMFVqY0RsMjQwcm1SaVdSN29lNjYrd1JDSlwvSUtiSWpneFpuR2VzeUFBbzNBUUh2MnNVTFZ5bXVLTGVLNFM5TjdzdXpaM1ZFRDdvRUVlRFF0QUY4d2pXcmF4NkFwMGVodXRVUFlxVGhVRmVpYlwvRUJFT05idFhyeXp4TUtcLzN0MlVcL3ZIc2dWSncxaW55TDVUVXFIWjZZMUdHakJKVnpzRkxGeE52RWdLaW9WT0tCb3pTQW1xelNwaTRaQmtGeEpITjVEUU44Q3VGSnBGdzdOcFRyTE9sYmFTT3RrMDJYU3l0XC9PcVJ1OXo2MUpJdm5XSHZFZ0lIMGh5OGR2TEJkNTZjVHFKM1hSYnVEbm9vVFU1VUUzcmRDZ3JhZWRYQWZ1cU9aajVKMHdOMGpxczBSVU5GejNrNzk3bnVBa210dFdCblVBaUs5Y0VIWmxCdE04UlV6T2NEN3ZTN2E0MEhRYmlCNGk3V2xZN1R2ZUM4cVVZZ1Rlb1BndmFcL2phemNnbEhKb05QeHhxa1BldFFqK2ErcWZmYWs1RnNPWEpNK0x4MFo4MTU4OEttZTNxeDMrcCtkNUVwSUd4b1krOXRFdU1UNVFxZyszXC9Lb21TSG5hSFI2OVRVWmxIRm9UcTRlU2kyNWF6K1pQR3lMK1MyS0FvQ2ZFaTViTmdybm1xQ1BscVMzM2tjeUFCQVlvZFdPMTJTb2ttZDl2Q3BuTXVvTnJkUDRpa0g5cE4rWlRcL1l2MWdNdmY0MFVsMFArWWYzWVNmMW5oUnkwWk1mTVc3WUluU3dyQUM4TTZBbHJac0lOMDNiYVhVWks2TCs3QnN0VDlOXC9xaEwyUEtmblVmOXpcL3hoekQ1K3JKWVozVWxrdElKbTdWTHpaMnk2bXFQQ0VJalR1TVpIc1d4bmJjVVIwdTR1VXY1M1wvMEJMODVTWkNreVpCVmh3MWRDeERROGh5YnVsMkVKV2poMFwvYnZHakMycHJmQjUycDQ3b3laUUlTSjdmaDdFMnFtTHhIN1RvUnhhcUhCWXkybkhoMlFwZUVtM0VPUVZrcXp3S0lLMFwvOUtvZnhibE1ZUnp0bGVkcGdqTlp0dGV0cGhCa3hjUmxZXC96SWRFXC83OWxEUnRma1MyYnZqWGhMN0lSM0x2Z0NCTWxIR0pUYjByWDN4Y3JCT3JLTzFzUWkzS3NYTDVDZVJ3MmhEbXlXSENqYWc9PSIsIm1hYyI6Ijc1YmU5YTE4ZGEwNzExZGJlZWQ0MzZhNGVkNWE1NGMzYmE1YWFjNjBhYTgxYjFlYjUyN2M1Yzc4ZjkwNTcyNmMifQ==")
        
        headers = requestHeader
    }
    
    ///  链式语法
    func url(_ url:String?) -> Self{
        self.url = url ?? ""
        return self
    }
    ///  请求类型
    func requestType(_ type: HTTPMethod) -> Self {
        self.requestType = type
        return self
    }
    ///请求参数
    func params(_ params: [String:Any]?) -> Self {
        self.params = params
        return self
    }
    ///成功
    func success(_ handler:@escaping SuccessHandlerType) -> Self {
        self.success = handler
        return self
    }
    ///失败
    func failed(_ handler:@escaping FailureHandlerType) -> Self {
        self.failure = handler
        return self
    }
    ///获取包头
    func getHeader() -> HTTPHeaders {
        var requestHeader = HTTPHeaders()
        if let header = headers {
            requestHeader = header
        } else {
            requestHeader.add(name:"Conatent-Type",value:"application/json")
            requestHeader.add(name:"Accept",value:"application/json")
        }
        return requestHeader
    }
    
    ///开始请求
    func startRequest() -> Request? {
        guard YHNetworkStatusManager.shared.isNetWorkOK == true else {
            YHHUD.flash(message: "网络异常")
            return httpRequest
        }
        
        let requestHeaders = getHeader()
        ///不使用缓存
        AF.sessionConfiguration.requestCachePolicy = .reloadIgnoringCacheData
        AF.sessionConfiguration.timeoutIntervalForRequest = 20
        
        let encoding = (self.requestType == .get ? URLEncoding(destination: .queryString) : JSONEncoding()) as ParameterEncoding
        httpRequest = AF.request(self.url!, method: self.requestType,parameters: self.params, encoding:encoding, headers: requestHeaders, interceptor: nil, requestModifier: nil)
        
        httpRequest?.responseString(completionHandler: { string in
#if DEBUG
            printLog("\n网络请求已返回 string=\(string)")
#endif
            self.completeHandle(string: string)
        })
        
        return httpRequest
    }
    /// 请求response完成处理
    func completeHandle(string: AFDataResponse<String>) {
        let responseResult = string.result
        var statusCode = string.response?.statusCode ?? 0
        let errorResponseMsg = string.error?.localizedDescription ?? ""
        let resultValue = string.value ?? ""
        let serverDict = resultValue.toDictionary()
        switch responseResult {
        case .success:
            break
        case .failure:
            if let underyingError = string.error?.asAFError?.underlyingError {
                if let urlError = underyingError as? URLError {
                    switch urlError.code{
                    case.timedOut:
                        statusCode = urlError.code.rawValue
                    case.cannotConnectToHost:
                        statusCode = urlError.code.rawValue
                    case.cannotFindHost:
                        statusCode = urlError.code.rawValue
                    case.unsupportedURL:
                        statusCode = urlError.code.rawValue
                    default:
                        break
                    }
                }
            }
            break
        }
        
        if statusCode == 200 {
            guard let suclock = self.success else { return }
            
            let dittt = self.handleJsonObjectNullValue(serverDict)
            suclock(dittt as? [String : Any] ?? [:], statusCode)
        } else {
            guard let errorBlock = self.failure else { return }
            
            let errorModel = YHErrorModel(errorCode: Int32(statusCode), errorMsg: errorResponseMsg)
            errorBlock(errorModel)
        }
    }
    
    
    //处理对象为空的情况
    func handleJsonObjectNullValue(_ jsonObject: Any) -> Any {
        if let jsonArray = jsonObject as? Array<Any> {
            let noNullArray: [Any] = jsonArray.map { value in
                if value is NSNull {
                    return ""
                }else if let value = value as? Array<Any> {
                    return handleJsonObjectNullValue(value)
                }else if let value = value as? Dictionary<AnyHashable, Any> {
                    return handleJsonObjectNullValue(value)
                }else {
                    return value
                }
            }
            return noNullArray
        }else if let jsonDic = jsonObject as? Dictionary<AnyHashable, Any> {
            let noNullDic: [AnyHashable: Any] = jsonDic.mapValues { value in
                if value is NSNull {
                    return ""
                }else if let value = value as? Array<Any> {
                    return handleJsonObjectNullValue(value)
                }else if let value = value as? Dictionary<AnyHashable, Any> {
                    return handleJsonObjectNullValue(value)
                }else {
                    return value
                }
            }
            return noNullDic
        }
        return jsonObject
    }
    
}

extension YHNetRequest {
    class func getRequest(url:String, params:[String:Any] = [:], successBlock: SuccessHandlerType!, failBlock: FailureHandlerType!) -> Request? {
        
        printLog("\n发起请求的URL是===> url = \(url)")
        return YHNetRequest().url(url).requestType(.get).params(params).success(successBlock).failed(failBlock).startRequest()
    }
    
    class func postRequest(url:String, params:[String:Any] = [:], successBlock: SuccessHandlerType!, failBlock: FailureHandlerType!) -> Request? {
        printLog("\n发起请求的URL是===> url = \(url)")
        return YHNetRequest().url(url).requestType(.post).params(params).success(successBlock).failed(failBlock).startRequest()
    }
}
