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.BaseCommand
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.UserHelper
import com.yidianling.user.api.bean.UserResponseBean
import com.yidianling.user.bean.CheckPhonePassBean
import com.yidianling.user.bean.CollectFocusItemBean
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.mine.bean.RedPacketId
import com.yidianling.user.mine.bean.RedPacketIdCmd
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>>> {
        var param: String = Gson().toJson(param)
        val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), param)
        return getUserApi().setChannelId(body)
    }

    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 getSecretJavaData(): Observable<BaseResponse<String>> {
        return getUserApi().getSecretJavaData()
    }

    override fun getRedPacketId(param: RedPacketIdCmd): Observable<BaseResponse<RedPacketId>> {
        return RxUtils.mapObservable(param)
            .flatMap { getUserApi().getRedPacketId(it) }
    }

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

    override fun getFocusData(): Observable<BaseAPIResponse<List<CollectFocusItemBean>>> {
        return getUserApi().getFocusData()
    }

    override fun getNewUserJumpUrl(): Observable<BaseAPIResponse<String>> {
        return RxUtils.mapObservable(BaseCommand())
            .flatMap { getUserApi().getNewUserJumpUrl(it) }
    }

    /**
     * 用户注销账号调用接口(禁止登陆)
     * */
    override fun userForbidLogin(param: UserForbidLoginParam): Observable<BaseAPIResponse<Boolean>> {
        return RxUtils.mapObservable(param)
            .flatMap { getUserApi().userForbidLogin(it) }
    }

    /**
     * 用户注销账号调用接口
     * */
    override fun accountLogOff(param: UserForbidLoginParam): Observable<BaseAPIResponse<Boolean>> {
        return RxUtils.mapObservable(param)
            .flatMap { getUserApi().accountLogOff(it) }
    }

    private object Holder {
        val INSTANCE = UserHttpImpl()
    }

}