package com.doverfuelingsolutions.issp.api

import android.util.Base64
import com.doverfuelingsolutions.issp.BuildConfig
import com.doverfuelingsolutions.issp.DFSApplication
import com.doverfuelingsolutions.issp.R
import com.doverfuelingsolutions.issp.api.basic.RetrofitUtil
import com.doverfuelingsolutions.issp.api.dto.*
import com.doverfuelingsolutions.issp.api.service.*
import com.doverfuelingsolutions.issp.data.GlobalData
import com.doverfuelingsolutions.issp.utils.AppUtil
import com.doverfuelingsolutions.issp.utils.StringUtil
import com.doverfuelingsolutions.issp.utils.ValidateUtil
import com.doverfuelingsolutions.issp.utils.sp.SPKeys
import com.doverfuelingsolutions.issp.utils.sp.SPUtil
import com.wayne.www.waynelib.util.log.DFSLog
import com.doverfuelingsolutions.issp.utils.thread.ThreadUtil
import com.wayne.www.waynelib.fdc.message.DeviceClass
import com.wayne.www.waynelib.webservice.entity.*
import okhttp3.ResponseBody
import org.json.JSONArray
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.io.ByteArrayInputStream
import java.io.File
import java.math.BigDecimal
import javax.xml.parsers.DocumentBuilderFactory
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

object SystemApi {

    private var serviceLogin = makeLoginService()
    private var serviceBase = makeBaseService()
    private var serviceTrx = makeTrxService()
    private var servicePay = makePayService()
    private var serviceConfig = makeConfigService()
    private var serviceAssets = makeAssetsService()
    private var serviceCheck = makeCheckService()

    /**
     * 获取账户对应设备
     */
    suspend fun getUserDevice(accountName: String,SN:String) = suspendCoroutine<DFSResult<Boolean>> {
        DFSLog.i("验证当前账户：${accountName}是否可以登录设备：${SN}")
        serviceCheck.getUserDevice(accountName,SN).enqueue(object :Callback<UserDevice>{
            override fun onResponse(call: Call<UserDevice>, response: Response<UserDevice>) {
                val code = response.code()
                val body = response.body()
                DFSLog.i("验证当前账户：${accountName}是否可以登录设备：${SN}结果：$body")


                it.resume(DFSResult.success((body?.result)?:false))
            }

            override fun onFailure(call: Call<UserDevice>, t: Throwable) {
                DFSLog.e("验证当前账户：${accountName}是否可以登录设备：${SN}失败",t.message)
                it.resume(DFSResult.fail("验证当前账户：${accountName}是否可以登录设备：${SN}失败,${t.message}"))
            }
        })
    }

    /**
     * 登录 + 获取油站信息
     */
    suspend fun login(accountName: String, password: String): DFSResult<*> {
        val resultLogin = loginOnly(accountName, password)
        return if (resultLogin.success) {
            // 通知服务器（不明白其实际意义，但照做就是了）
            notifyTrx(PosTrxType.LogOn)
        } else {
            resultLogin
        }
    }

    /**
     * 根据油品代码查询油品名称
     */
    suspend fun barcodeName(id: Int) = suspendCoroutine<DFSResult<ResultBarcode>> {
        serviceBase.barcodeInfo(id).enqueue(object : Callback<ResultBarcode> {
            override fun onResponse(call: Call<ResultBarcode>, response: Response<ResultBarcode>) {
                val code = response.code()
                val body = response.body()
                if (code == 200 && body != null) {
                    it.resume(DFSResult.success(body))
                    return
                }
                it.resume(DFSResult.fail(R.string.req_fail))
            }

            override fun onFailure(call: Call<ResultBarcode>, t: Throwable) {
                DFSLog.e("SystemApi.barcodeName.onFailure", t)
                it.resume(DFSResult.fail(t.message.toString()))
            }
        })
    }

    /**
     * 获取油站的支付配置信息
     */
    suspend fun paymentParam() = suspendCoroutine<DFSResult<ResultPaymentParam>> {
        serviceTrx.paymentParam().enqueue(object : Callback<ResultObj<List<ResultPaymentParam>>> {
            override fun onResponse(call: Call<ResultObj<List<ResultPaymentParam>>>, response: Response<ResultObj<List<ResultPaymentParam>>>) {
                // {"StatusCode":200,"Message":"OK","Data":[{"PaymentId":2,"DispalyName":"支付宝支付"},{"PaymentId":3,"DispalyName":"微信支付"}]}
                // {"StatusCode":200,"Message":"OK","Data":[{"PaymentId":13,"DispalyName":"通联"}]}
                val code = response.code()
                val body = response.body()
                if (code != 200 || body?.Data.isNullOrEmpty()) {
                    it.resume(DFSResult.fail(R.string.fail_get_pay_param))
                    return
                }
                // 目前就三种支付渠道：通联、微信、支付宝
                // 由于实际使用只有两种方案：通联 OR 微信+支付宝，不存在单独使用的情况
                // 对于微信+支付宝，pay 方法会根据付款码来判断区分究竟是微信还是支付宝，因此本地化一个支付类型
                body!!.Data.let { channels ->
//                    val combine = channels.find { type -> type.PaymentId == 13 }
//                    val param = combine ?: ResultPaymentParam(0, "移动支付")
//                    val param = if (channels.isNotEmpty()) channels[0] else ResultPaymentParam(0,"移动支付")

                    val sequenceStr = SPUtil.getString(SPKeys.PAYMENT_SEQUENCE,"")
                    val sequence = sequenceStr.split(" ")
                    sequence.forEach { id->
                        channels.forEach { payment ->
                            if (payment.PaymentId.toString() == id) {
                                GlobalData.paymentId.set(payment.PaymentId)
                                GlobalData.paymentName.set(payment.DispalyName)
                                it.resume(DFSResult.success(payment))

                                return@let
                            }
                        }
                    }

                    // 如果获取到的支付 id 和 设置的支付顺序匹配不到，就按原本的处理——拿到第一个作为支付 id
                    val combine = channels.find { type -> type.PaymentId != 3 && type.PaymentId != 2 && type.PaymentId != 701 && type.PaymentId != 700 }
                    val param = combine ?: ResultPaymentParam(0, "移动支付")
                    GlobalData.paymentId.set(param.PaymentId)
                    GlobalData.paymentName.set(param.DispalyName)
                    it.resume(DFSResult.success(param))
                }
            }

            override fun onFailure(call: Call<ResultObj<List<ResultPaymentParam>>>, t: Throwable) {
                DFSLog.e("SystemApi.paymentParam.onFailure", t)
                it.resume(DFSResult.fail(R.string.fail_get_pay_param))
            }
        })
    }

    /**
     * 查找云端当前订单状态
     */
    suspend fun getOrderStateForClound(dc: DeviceClass) = suspendCoroutine<DFSResult<CheckResponse>> {
        val releaseToken = dc.releaseTokenAttribute ?: ""
        val pumpInfo = if (dc.pumpNo != null) dc.pumpNo.toString() else ""
        val amount = if (dc.amount != null) dc.myAmount else ""
        val transactionSeqNo = dc.transactionSeqNo ?: ""
        val time = dc.endTimeStamp ?: ""

        DFSLog.i("查找云端订单状态：${releaseToken}-${amount}-${transactionSeqNo}-${pumpInfo}-${time}-${GlobalData.serialNumber.get()}")
        serviceCheck.checkOrderState(time,releaseToken,amount,transactionSeqNo, pumpInfo, GlobalData.serialNumber.get()).enqueue(object :Callback<CheckResponse>{
            override fun onResponse(call: Call<CheckResponse>, response: Response<CheckResponse>) {
                val code = response.code()
                val body = response.body()
                if (body is CheckResponse) {
                    it.resume(DFSResult.success(body))
                } else {
                    it.resume(DFSResult.fail(R.string.fail_request))
                }
            }

            override fun onFailure(call: Call<CheckResponse>, t: Throwable) {
                DFSLog.e("SystemApi.getOrderStateForClound.onFailure", t)
                it.resume(DFSResult.fail(t.message.toString()))
            }
        })
    }

    /**
     * 向服务器备案即将进行支付的订单
     */
    suspend fun generateOrder(dc: DeviceClass, posItemUniqueId: String) = suspendCoroutine<DFSResult<PosTrx>> {
        val clientPosTrx = ClientPosTrx(PosTrxType.Sale)
        val clientRingUpPosItem = ClientRingUpPosItem()
        clientRingUpPosItem.posItemUniqueId = posItemUniqueId
        clientRingUpPosItem.setFuelItemSoldOnPumpId(dc.pumpNo)
        clientRingUpPosItem.setFuelItemSoldOnPumpNozzleId(dc.nozzleNo)
        clientRingUpPosItem.setFuelItemClientSidePrice(dc.unitPrice)
        clientRingUpPosItem.qty = dc.volume
        clientRingUpPosItem.fuelItemFdcTransactionSeqNo = dc.transactionSeqNo
        clientRingUpPosItem.setFuelItemPumpTotalizerMoney(dc.amountTotalizer)
        clientRingUpPosItem.setFuelItemPumpTotalizerVolume(dc.volumeTotalizer)
        clientRingUpPosItem.setFuelItemTransactionEndTime(dc.saleEndTime)
        clientRingUpPosItem.setFuelItemFdcReleaseTokenAttribute(dc.releaseTokenAttribute.toInt())
//        clientRingUpPosItem.setFuelItemOriginalGrossAmount(if (AppUtil.isDebug()) BigDecimal("0.01") else dc.amount)
        clientRingUpPosItem.setFuelItemOriginalGrossAmount(dc.amount)
        clientPosTrx.addClientRingUpPosItem(clientRingUpPosItem)
        DFSLog.d("generateOrder.params", clientPosTrx)

        serviceTrx.generateOrder(clientPosTrx).enqueue(object : Callback<PosTrx> {
            override fun onResponse(call: Call<PosTrx>, response: Response<PosTrx>) {
                val code = response.code()
                val body = response.body()
                if (code == 200 && body is PosTrx) {
                    it.resume(DFSResult.success(body))
                } else {
                    it.resume(DFSResult.fail(R.string.fail_request))
                }
            }

            override fun onFailure(call: Call<PosTrx>, t: Throwable) {
                DFSLog.e("SystemApi.generateOrder.onFailure", t)
                it.resume(DFSResult.fail(t.message.toString()))
            }
        })
    }

    /**
     * 查询折扣
     */
    suspend fun getDiscount(posTrx: PosTrx,code:String) = suspendCoroutine<DFSResult<PosTrx>> {

        val posTrxMop = PosTrxMop().apply {
            setPayBack(0f)
            // 支付类型
            val paymentId = GlobalData.paymentId.get()
            posMopPaymentId = when {
                paymentId > 0 -> paymentId
                ValidateUtil.isAliPaymentCode(code) -> 2 // 支付宝支付
                else -> 3 // 微信支付
            }
            paid = posTrx.grossAmount.toFloat()
        }

        DFSLog.i("查询折扣，支付类型：${posTrxMop.posMopPaymentId}")
        serviceTrx.getDiscount(posTrx.id,posTrxMop).enqueue(object :Callback<PosTrx> {
            override fun onResponse(call: Call<PosTrx>, response: Response<PosTrx>) {
                val code = response.code()
                val body = response.body()
                if (code == 200 && body is PosTrx) {
                    it.resume(DFSResult.success(body))
                } else {
                    it.resume(DFSResult.fail(R.string.fail_discount))
                }
            }

            override fun onFailure(call: Call<PosTrx>, t: Throwable) {
                DFSLog.e("SystemApi.getDiscount.onFailure",t)
                it.resume(DFSResult.fail(t.message.toString()))
            }
        })
    }

    /**
     * 扫码支付
     *
     * code=412：交易ID不存在
     * code=409：交易已经支付过
     * code=406：优惠券核销不通过
     * code=400：支付失败
     */
    suspend fun pay(posTrx: PosTrx, code: String) = suspendCoroutine<DFSResult<ResultPayment>> {
        val posTrxMop = PosTrxMop().apply {
            setPayBack(0f)
            authCode = code
            // 支付类型
            val paymentId = GlobalData.paymentId.get()
            posMopPaymentId = when {
                paymentId > 0 -> paymentId
                ValidateUtil.isAliPaymentCode(code) -> 2 // 支付宝支付
                else -> 3 // 微信支付
            }
//            paid = if (BuildConfig.DEBUG) {
//                0.01f
//            } else {
//                posTrx.netAmount.toFloat()
//            }
            paid = posTrx.netAmount.toFloat()
        }

        DFSLog.i("支付类型：${posTrxMop.posMopPaymentId}")
        servicePay.pay(posTrx.id, posTrxMop).enqueue(object : Callback<ResultPayment> {
            override fun onResponse(call: Call<ResultPayment>, response: Response<ResultPayment>) {
                val body = response.body()
                val codeResponse = response.code()
                when {
                    codeResponse == 200 && body is ResultPayment -> {
                        it.resume(DFSResult.success(body))
                    }
                    codeResponse == 412 -> {
                        it.resume(DFSResult.fail("订单交易 ID 不存在"))
                    }
                    codeResponse == 409 -> {
                        it.resume(DFSResult.fail("此订单已支付，请勿重复支付"))
                    }
                    codeResponse == 406 -> {
                        it.resume(DFSResult.fail("优惠券核销不通过"))
                    }
                    codeResponse == 410 -> {
                        it.resume(DFSResult.fail("订单支付中"))
                    }
                    else -> {
                        it.resume(DFSResult.fail(R.string.fail_pay))
                    }
                }
            }

            override fun onFailure(call: Call<ResultPayment>, t: Throwable) {
                DFSLog.e("SystemApi.pay.onFailure", t)
                it.resume(DFSResult.fail(""))
            }
        })
    }

    /**
     * 查询油站联系电话
     */
    suspend fun sessionInfo() = suspendCoroutine<DFSResult<ResultDeviceSessionInfo>> {
        serviceBase.sessionInfo(GlobalData.serialNumber.get()).enqueue(object : Callback<ResultDeviceSessionInfo> {
            override fun onResponse(call: Call<ResultDeviceSessionInfo>, response: Response<ResultDeviceSessionInfo>) {
                val code = response.code()
                val body = response.body()
                if (code != 200 || body == null) {
                    it.resume(DFSResult.fail(R.string.return_data_error))
                } else {
                    it.resume(DFSResult.success(body))
                }
            }

            override fun onFailure(call: Call<ResultDeviceSessionInfo>, t: Throwable) {
                DFSLog.e("SystemApi.sessionInfo.onFailure", t)
                it.resume(DFSResult.fail(R.string.return_data_error))
            }
        })
    }

    /**
     * 获取一些油站信息（LOGO）
     */
    suspend fun stationLogo(): DFSResult<String> {
        val resultConfig = config(WayneApiConfig.CONFIG_LOGO)
        // 保存油站名称前缀
        GlobalData.belongName.set(resultConfig.data?.description ?: "")
        if (resultConfig.success && !resultConfig.data?.configFileDescriptions?.get(0)?.id.isNullOrEmpty()) {
            val resultFile = file(resultConfig.data!!.configFileDescriptions[0].id)
            if (resultFile.success && resultFile.data != null) {
                return DFSResult.success(resultFile.data)
            }
        }
        return DFSResult.fail(R.string.req_fail)
    }

    /**
     *  获取自助机配置信息
     */
    suspend fun getDeviceConfig():DFSResult<String> {
        val configStr = getDeviceConfig(WayneApiConfig.CONFIG_DEVICE)
        if (configStr.success && configStr.data != null && configStr.data.isNotEmpty()){
            val data = configStr.data

            val inputStream = ByteArrayInputStream(data.toByteArray(charset("UTF-8")))
            val factory = DocumentBuilderFactory.newInstance()
            val builder = factory.newDocumentBuilder()
            val dom = builder.parse(inputStream)

            val paySequence = dom.getElementsByTagName("ThirdPay")
            if (paySequence != null && paySequence.length != 0) {
                val value = paySequence.item(0).firstChild.nodeValue
                return DFSResult.success(value)
            } else {
                return DFSResult.fail(R.string.req_fail)
            }

        }
        return DFSResult.fail(R.string.req_fail)
    }

    /**
     * 获取 APP 版本信息
     */
    suspend fun remoteVersion() = suspendCoroutine<DFSResult<ResultVersionInfo>> {
        serviceAssets.remoteVersion().enqueue(object : Callback<ResultVersionInfo> {
            override fun onResponse(call: Call<ResultVersionInfo>, response: Response<ResultVersionInfo>) {
                if (response.code() == 200 && response.body() is ResultVersionInfo) {
                    it.resume(DFSResult.success(response.body() as ResultVersionInfo))
                } else {
                    it.resume(DFSResult.fail(R.string.fail_request))
                }
            }

            override fun onFailure(call: Call<ResultVersionInfo>, t: Throwable) {
                DFSLog.e("SystemApi.remoteVersion.onFailure", t)
                it.resume(DFSResult.fail(R.string.fail_request))
            }
        })
    }

    /**
     * 单纯的登录操作
     */
    private suspend fun loginOnly(accountName: String, password: String) = suspendCoroutine<DFSResult<ResultLogin>> {
        serviceLogin.login(accountName, password).enqueue(object : Callback<ResultLogin> {

            override fun onResponse(call: Call<ResultLogin>, response: Response<ResultLogin>) {
                val code = response.code()
                val body = response.body()
                if (code != 200) {
                    it.resume(DFSResult.fail(R.string.account_name_password_error))
                    return
                } else if (body != null) {
                    GlobalData.accountName.set(accountName)
                    GlobalData.password.set(password)
                    GlobalData.accessToken.set(body.access_token)
                    GlobalData.accessTokenExpire.set((System.currentTimeMillis() + body.expires_in.toLong() * 1000))
                    // [{\"Id\":\"dfc5cc2d-a5ef-4bc4-b1b0-4aa0c82a73de\",\"Name\":\"GlobalUnit\"}]
                    if (body.BusinessUnits.isNotBlank()) {
                        val jsonArray = JSONArray(body.BusinessUnits)
                        if (jsonArray.length() > 0) {
                            val obj = jsonArray.getJSONObject(0)
                            if (!obj.isNull("Id") && !obj.isNull("Name")) {
                                val buId = obj.optString("Id")
                                val buName = obj.optString("Name")
                                GlobalData.businessId.set(buId)
                                GlobalData.businessName.set(buName)
                                it.resume(DFSResult.success(body))
                                return
                            }
                        }
                    }
                }
                it.resume(DFSResult.fail(R.string.return_data_error))
            }

            override fun onFailure(call: Call<ResultLogin>, t: Throwable) {
                DFSLog.e("SystemApi.loginOnly.onFailure", t)
                it.resume(DFSResult.fail(t.message.toString()))
            }
        })
    }

    /**
     * 可能需要告知云端发生的事务？？
     */
    private suspend fun notifyTrx(type: Int) = suspendCoroutine<DFSResult<Boolean>> {
        val clientPosTrx = ClientPosTrx(type)
        serviceTrx.report(clientPosTrx).enqueue(object : Callback<Any> {
            override fun onResponse(call: Call<Any>, response: Response<Any>) {
                it.resume(if (response.code() == 200) {
                    DFSResult.success(true)
                } else {
                    DFSResult.fail(StringUtil.get(R.string.login_fail, response.errorBody()?.string() ?: response.message()))
                })
            }

            override fun onFailure(call: Call<Any>, t: Throwable) {
                DFSLog.e("SystemApi.notifyTrx.onFailure", t)
                it.resume(DFSResult.fail(t.message.toString()))
            }
        })
    }

    /** 查询自助机配置信息
     *
     */
    private suspend fun getDeviceConfig(type: String) = suspendCoroutine<DFSResult<String>> {
        serviceConfig.getDeviceConfig(type,GlobalData.serialNumber.get()).enqueue(object : Callback<Array<DeviceConfig>> {
            override fun onResponse(call: Call<Array<DeviceConfig>>, response: Response<Array<DeviceConfig>>) {
                val code = response.code()
                val body = response.body()
                if (code == 200 && !body.isNullOrEmpty()) {
                    val config = body[0]
                    if (config.enabled == "true") {
                        it.resume(DFSResult.success(config.value))  //成功
                    } else {
                        it.resume(DFSResult.fail(R.string.return_data_error))
                    }
                    return
                }
                it.resume(DFSResult.fail(R.string.return_data_error))
            }

            override fun onFailure(call: Call<Array<DeviceConfig>>, t: Throwable) {
                DFSLog.e("SystemApi.config.onFailure", t)
                it.resume(DFSResult.fail(R.string.req_fail))
            }
        })
    }
    /**
     * 查询站级配置信息
     */
    private suspend fun config(type: String) = suspendCoroutine<DFSResult<ResultConfig>> {
        serviceConfig.config(GlobalData.businessId.get(), type).enqueue(object : Callback<Array<ResultConfig>> {
            override fun onResponse(call: Call<Array<ResultConfig>>, response: Response<Array<ResultConfig>>) {
                val code = response.code()
                val body = response.body()
                if (code == 200 && !body.isNullOrEmpty() && body[0].configFileDescriptions.isNotEmpty()) {
                    if (body[0].configFileDescriptions.isNotEmpty()) {
                        it.resume(DFSResult.success(body[0]))
                        return
                    }
                }
                it.resume(DFSResult.fail(R.string.return_data_error))
            }

            override fun onFailure(call: Call<Array<ResultConfig>>, t: Throwable) {
                DFSLog.e("SystemApi.config.onFailure", t)
                it.resume(DFSResult.fail(R.string.req_fail))
            }
        })
    }

    /**
     * 下载文件
     */
    private suspend fun file(id: String) = suspendCoroutine<DFSResult<String>> {
        serviceConfig.file(id).enqueue(object : Callback<Array<ResultFile>> {
            override fun onResponse(call: Call<Array<ResultFile>>, response: Response<Array<ResultFile>>) {
                val code = response.code()
                val body = response.body()
                if (code != 200 || body.isNullOrEmpty() || body[0].value.isBlank()) {
                    it.resume(DFSResult.fail(R.string.return_data_error))
                } else {
                    ThreadUtil.io {
                        try {
                            val file = File(DFSApplication.instance.applicationContext.filesDir, body[0].name)
                            if (file.isFile) file.delete()
                            file.createNewFile()
                            file.writeBytes(Base64.decode(body[0].value, Base64.DEFAULT))
                            it.resume(DFSResult.success(body[0].name))
                        } catch (e: Exception) {
                            DFSLog.e("SystemApi.file.save", e)
                            it.resume(DFSResult.fail(R.string.fail_save_file))
                        }
                    }
                }
            }

            override fun onFailure(call: Call<Array<ResultFile>>, t: Throwable) {
                DFSLog.e("SystemApi.serviceConfig.file", t)
                it.resume(DFSResult.fail(R.string.req_fail))
            }
        })
    }

    /**
     * 在设置中修改后需要重新生成 baseUrl
     */
    fun regenerateAllService() {
        serviceLogin = makeLoginService()
        serviceBase = makeBaseService()
        serviceTrx = makeTrxService()
        servicePay = makePayService()
        serviceConfig = makeConfigService()
        serviceCheck = makeCheckService()
    }

    /**
     * 获取POS订单小票
     */
    suspend fun getPosTicketInfo(trxId: String): DFSResult<ResultPosTicketInfo> {
        return suspendCoroutine {
            val tip = "获取POS订单小票信息失败"
            serviceBase.posTicketInfo(trxId).enqueue(object : Callback<ResponseBody> {
                override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                    val code = response.code()
                    val body = response.body()?.string()
                    if (code != 200 || body == null) {
                        it.resume(DFSResult.fail(tip))
                        return
                    }
                    // 加油员
                    var operator = ""
                    val index1 = body.indexOf("加油员：")
                    if (index1 > -1) {
                        val index2 = body.indexOf("<", index1)
                        operator = body.slice((index1 + 4) until index2).trim()
                    }
                    //开票二维码
                    var qrcodeStr = ""
                    if (SPUtil.getBoolean(SPKeys.OPEN_QR_CODE_TICKET)) {
                        val qrcodeSign = "data:image/jpg;base64,"
                        val indexQRcodeStart = body.indexOf(qrcodeSign)
                        if (indexQRcodeStart > -1) {
                            val indexQRCodeEnd = body.indexOf("</img>",indexQRcodeStart)
                            qrcodeStr = body.slice((indexQRcodeStart + qrcodeSign.length) until (indexQRCodeEnd-2)).trim() //base64字符串后面多了 \">，所有减三
                        }
                    }

                    it.resume(DFSResult.success(ResultPosTicketInfo(
                        operator,qrcodeStr
                    )))
                }

                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    DFSLog.e(tip, t)
                    it.resume(DFSResult.fail("$tip: ${t.message}"))
                }
            })
        }
    }

    private fun makeLoginService(): ServiceLogin {
        return RetrofitUtil.getGsonBuilder()
            .baseUrl(WayneApiConfig.HOST_BASE)
            .build()
            .create(ServiceLogin::class.java)
    }

    private fun makeBaseService(): ServiceBase {
        return RetrofitUtil.getAuthBuilder()
            .baseUrl(WayneApiConfig.HOST_BASE)
            .build()
            .create(ServiceBase::class.java)
    }

    private fun makeTrxService(): ServiceTrx {
        return RetrofitUtil.getAuthBuilder()
            .baseUrl(WayneApiConfig.HOST_TRX)
            .build()
            .create(ServiceTrx::class.java)
    }

    private fun makePayService():ServiceTrx {
        return RetrofitUtil.getPayBuilder()
            .baseUrl(WayneApiConfig.HOST_TRX)
            .build()
            .create(ServiceTrx::class.java)
    }

    private fun makeConfigService(): ServiceConfig {
        return RetrofitUtil.getAuthBuilder()
            .baseUrl(WayneApiConfig.HOST_CONFIG)
            .build()
            .create(ServiceConfig::class.java)
    }

    private fun makeAssetsService(): ServiceAssets {
        return RetrofitUtil.getAuthBuilder()
            .baseUrl(WayneApiConfig.HOST_ASSETS)
            .build()
            .create(ServiceAssets::class.java)
    }

    private fun makeCheckService():ServiceCheck {
        return RetrofitUtil.getAuthBuilder()
            .baseUrl(WayneApiConfig.CHECK_ORDER_BASE)
            .build()
            .create(ServiceCheck::class.java)
    }
}