package com.yidianling.user.http

import android.app.Activity
import com.google.gson.Gson
import com.google.gson.internal.LinkedTreeMap
import com.umeng.socialize.bean.SHARE_MEDIA
import com.ydl.ydlcommon.base.BaseApp
import com.ydl.ydlcommon.data.http.BaseAPIResponse
import com.ydl.ydlcommon.data.http.BaseResponse
import com.ydl.ydlcommon.data.http.RxUtils
import com.ydl.ydlcommon.router.YdlCommonOut
import com.ydl.ydlnet.YDLHttpUtils
import com.yidianling.common.tools.RxAppTool
import com.yidianling.common.tools.RxDeviceTool
import com.yidianling.user.api.bean.UserResponseBean
import com.yidianling.user.UserHelper
import com.yidianling.user.bean.CheckPhonePassBean
import com.yidianling.user.http.request.*
import com.yidianling.user.http.response.CheckPassword
import com.yidianling.user.http.response.CountryResponse
import com.yidianling.user.http.response.ExistResponse
import com.yidianling.user.http.response.SecretResponse
import com.yidianling.user.rxlogin.LoginObservable
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/02
 */
class UserHttpImpl private constructor() : UserHttp {

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

        fun clearUserApi() {
            Holder.INSTANCE.userApi = null
        }
    }

    private var userApi: UserApi? = null

    private fun getUserApi(): UserApi {
        if (userApi == null) {
            userApi = YDLHttpUtils.obtainApi(UserApi::class.java)
        }
        return userApi!!
    }

//    private val userApi: UserApi by lazy {
//        RetrofitProvider.getRetrofit()
//                .create(UserApi::class.java)
//    }

    override fun login(param: LoginParam): Observable<BaseResponse<UserResponseBean>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().login(it) }
    }

    override fun countryList(): Observable<BaseResponse<CountryResponse>> {
        return getUserApi().countryList("")
                .compose(RxUtils.netCheck())
    }

    override fun phoneExist(param: ExistParam): Observable<BaseResponse<ExistResponse>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().phoneExists(it) }
    }

    override fun code(param: CodeParam): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().getCode(it) }

    }

    override fun bindPhone(param: BindPhoneParam): Observable<BaseResponse<UserResponseBean>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().bindPhone(it) }
    }

    override fun forget(param: ForgetParam): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().forget(it) }
    }

    override fun register(param: RegisterParam): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().register(it) }
    }

    override fun channelId(param: ChannelIdParam): Observable<BaseResponse<LinkedTreeMap<String, String>>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().setChannelId(it) }
    }

    override fun thirdPartLogin(param: ThirdLoginParam): Observable<BaseAPIResponse<UserResponseBean>> {

        var param: String = Gson().toJson(param)
        val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), param)

        return getUserApi().thirdPartyLogin(body)

    }

    override fun setUserInfo(param: UserInfoParam): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().setUserInfo(it) }
    }

    //验证账号密码
    override fun checkPhonePass(cmd: CheckPhonePassBean): Observable<BaseResponse<CheckPassword>> {
        return RxUtils.mapObservable(cmd)
                .flatMap { getUserApi().checkPhonePass(it) }
    }

    override fun uploadHead(param: HeadParam): Observable<BaseResponse<Any>> {
        return Observable.just(param)
                .compose(RxUtils.netCheck())
                .subscribeOn(Schedulers.io())
                .map {
                    val map = HashMap<String, RequestBody>()
                    val mediaType = MediaType.parse("text/plain")
                    map["type"] = RequestBody.create(mediaType, it.type)
                    map["value"] = RequestBody.create(mediaType, it.value)
                    map["ffrom"] = RequestBody.create(mediaType, YdlCommonOut.getChannelName())
                    map["isFromApp"] = RequestBody.create(mediaType, "1")
                    map["osBuild"] = RequestBody.create(mediaType, """${RxDeviceTool.getBuildBrandModel()},${RxDeviceTool.getSDKVersionName()},${RxAppTool.getAppVersionName(BaseApp.getApp())}""")
                    map["ts"] = RequestBody.create(mediaType, (System.currentTimeMillis() / 1000).toString())
                    map["version"] = RequestBody.create(mediaType, RxAppTool.getAppVersionName(BaseApp.getApp()))
                    val userInfo = UserHelper.getUserInfo()
                    if (userInfo != null) {
                        map["uid"] = RequestBody.create(mediaType, userInfo.uid)
                        map["accessToken"] = RequestBody.create(mediaType, userInfo.accessToken)
                    }
                    val fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), it.file)
                    map.put("""head"; filename="${it.file.name}""", fileBody)
                    map
                }
                .flatMap {
                    getUserApi().uploadHeadImg(it)
                }
    }

    override fun bindQQ(param: BindQQ): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().bindQQ(it) }
    }

    override fun bindWX(param: BindWX): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().bindWx(it) }
    }

    override fun logout(param: Logout): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().logout(it) }
    }

    override fun checkPwd(param: CheckPwd): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().checkPwd(it) }
    }

    override fun changePhone(param: ChangePhone): Observable<BaseResponse<Any>> {
        return RxUtils.mapObservable(param)
                .flatMap { getUserApi().changePhone(it) }
    }

    override fun privacyAgree(uid: String): Observable<BaseResponse<Any>> {
        return getUserApi().privacyAgree(uid)
    }

    override fun umLogin(activity: Activity, media: SHARE_MEDIA): Observable<ThirdLoginParam> {
        return LoginObservable(activity, media)
    }

    override fun thirdPartJavaLogin(param: ThirdLoginParam): Observable<BaseResponse<UserResponseBean>> {
        var str = Gson().toJson(param)
        val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), str)
        return getUserApi().thirdPartJavaLogin(body)
    }

    override fun unBindThirdLogin(param: UnBindThirdLoginParam): Observable<BaseResponse<Any>> {
        var str = Gson().toJson(param)
        val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), str)
        return getUserApi().unBindThirdLogin(body)
    }

    override fun getSecretData(): Observable<BaseResponse<SecretResponse>> {
        return getUserApi().getSecretData()
    }


    private object Holder {
        val INSTANCE = UserHttpImpl()
    }

}