package com.yidianling.ydlcommon.custom.http

import com.yidianling.ydlcommon.core.base.BaseApplication
import com.yidianling.common.tools.RxAppTool
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.ydlcommon.custom.http.params.*
import com.yidianling.ydlcommon.custom.http.response.Balance
import com.yidianling.ydlcommon.custom.http.response.Recharge
import com.yidianling.ydlcommon.custom.http.response.TestAddOrderBean
import com.yidianling.ydlcommon.custom.http.response.WXPay
import com.yidianling.ydlcommon.custom.pay.redpacket.RedPacketBean
import com.yidianling.ydlcommon.custom.pay.redpacket.RedPacketParam
import com.yidianling.ydlcommon.custom.router.YdlCommonOut
import com.yidianling.ydlcommon.custom.router.YdlCommonRouterManager
import com.yidianling.ydlcommon.custom.ui.confideredpacket.RedListParam
import io.reactivex.Observable
import io.reactivex.schedulers.Schedulers
import okhttp3.MediaType
import okhttp3.RequestBody

/**
 * author : Zhangwenchao
 * e-mail : zhangwch@yidianling.com
 * time   : 2018/02/05
 */
class YdlCommonHttpImpl private constructor() : YdlCommonHttp {

    companion object {
        fun getInstance(): YdlCommonHttpImpl {
            return Holder.INSTANCE
        }

        fun clearYdlCommonApi() {
            Holder.INSTANCE.api = null
        }
    }

    private var api: YdlCommonApi? = null

    private fun getYdlCommonApi(): YdlCommonApi {
        if (api == null) {
            api = RetrofitProvider.getRetrofit()
                .create(YdlCommonApi::class.java)
        }
        return api!!
    }


    override fun uploadLog(param: LogParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<Any>> {
//        return RxUtils.mapObservable(param)
//                .flatMap { api.uploadLog(it) }
        return Observable.just(param)
                .compose(RxUtils.netCheck())
                .subscribeOn(Schedulers.io())
                .map {
                    val map = HashMap<String, RequestBody>()
                    val mediaType = MediaType.parse("text/plain")
                    map.put("apiurl", RequestBody.create(mediaType, it.apiurl))
                    map.put("os_type", RequestBody.create(mediaType, it.os_type.toString()))
                    map.put("errorCode", RequestBody.create(mediaType, it.errorCode.toString()))
                    map.put("errorMsg", RequestBody.create(mediaType, it.errorMsg))
                    map.put("ffrom", RequestBody.create(mediaType, YdlCommonOut.getChannelName()))
                    map.put("isFromApp", RequestBody.create(mediaType, "1"))
                    map.put("osBuild", RequestBody.create(mediaType, """${RxDeviceTool.getBuildBrandModel()},${RxDeviceTool.getSDKVersionName()},${RxAppTool.getAppVersionName(
                        BaseApplication.getApp())}"""))
                    map.put("ts", RequestBody.create(mediaType, (System.currentTimeMillis() / 1000).toString()))
                    map.put("version", RequestBody.create(mediaType, RxAppTool.getAppVersionName(BaseApplication.getApp())))
                    val userInfo = YdlCommonRouterManager.getYdlCommonRoute()?.getUserInfo()
                    if (userInfo != null) {
                        map.put("uid", RequestBody.create(mediaType, userInfo.userId))
                        map.put("accessToken", RequestBody.create(mediaType, userInfo.token))
                    }
                    val fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), it.file)
                    map.put("""uploadlog"; filename="${it.file.name}""", fileBody)
                    map
                }
                .flatMap { getYdlCommonApi().uploadLog(it) }
    }

    override fun wxRecharge(param: WXRechargeIdParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<WXPay>> {
        return RxUtils.mapObservable(param)
                .flatMap { getYdlCommonApi().wxRecharge(it) }
    }

    override fun getBalance(param: BalanceParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<Balance>> {
        return RxUtils.mapObservable(param)
                .flatMap { getYdlCommonApi().getBalance(it) }
    }

    override fun recharge(param: RechargeParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<Recharge>> {
        return RxUtils.mapObservable(param)
                .flatMap { getYdlCommonApi().recharge(it) }
    }

    override fun pay(param: BalancePayParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getYdlCommonApi().pay(it) }
    }

    override fun wxPay(param: PayParam.WxPayParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<WXPay>> {
        return RxUtils.mapObservable(param)
                .flatMap { getYdlCommonApi().wxPay(it) }
    }

    override fun aliPay(param: PayParam.AliPayParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<Recharge>> {
        return RxUtils.mapObservable(param)
                .flatMap { getYdlCommonApi().aliPay(it) }
    }

    override fun getCoupon(): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<ArrayList<RedPacketBean>>> {
        return RxUtils.mapObservable(
            RedPacketParam(
                ""
            )
        )
                .flatMap { getYdlCommonApi().getCoupon(it) }
    }

    override fun addOrder(param: AddOrderParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<TestAddOrderBean>> {
        return RxUtils.mapObservable((param))
                .flatMap { getYdlCommonApi().testAddOrder(it) }
    }

    override fun getRedList(param: RedListParam): Observable<com.yidianling.ydlcommon.custom.http.BaseResponse<Any>> {
        return RxUtils.mapObservable((param))
                .flatMap { getYdlCommonApi().getRedList(it) }
    }

    private object Holder {
        internal val INSTANCE = YdlCommonHttpImpl()
    }
}