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.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.ydlnet.YDLHttpUtils
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.mine.bean.RedPacketId
import com.yidianling.user.mine.bean.RedPacketIdCmd
import com.yidianling.user.rxlogin.LoginObservable
import io.reactivex.Observable
import okhttp3.MediaType
import okhttp3.MultipartBody
import okhttp3.RequestBody
import java.io.File

/**
 * 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 modifyUserBaseInfo(param: ModifyBaseInfo): Observable<BaseAPIResponse<Boolean>> {
        return RxUtils.mapObservable(param)
            .flatMap { getUserApi().modifyUserBaseInfo(it) }
    }

    override fun getUserAuditInfo(type: BaseInfo): Observable<BaseAPIResponse<UserModifyAuditRespDto>> {
        return RxUtils.mapObservable(type)
            .flatMap { getUserApi().getUserAuditInfo(it) }
    }

    override fun uploadFile(file: File): Observable<BaseAPIResponse<Boolean>> {
        return Observable.just(true)
            .compose(RxUtils.netCheck())
            .flatMap {
                getUserApi().uploadFile(
                    MultipartBody.Part.createFormData(
                        "file", file.name,
                        RequestBody.create(MediaType.parse("multipart/form-data"), file)
                    )
                )
            }.flatMap {
                if (it.code == "200")
                    modifyUserBaseInfo(ModifyBaseInfo(it.data, 102))
                else
                    Observable.just(BaseAPIResponse())
            }
    }

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

}