package com.gh.gamecenter.login.user;

import static com.gh.gamecenter.common.constant.Constants.LOGIN_TAG;
import static com.gh.gamecenter.common.constant.Constants.LOGOUT_TAG;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MediatorLiveData;

import com.alibaba.android.arouter.launcher.ARouter;
import com.gh.gamecenter.common.utils.PackageFlavorHelper;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.provider.IAppProvider;
import com.gh.gamecenter.core.provider.IWechatBindHelperProvider;
import com.gh.gamecenter.login.HaloApp;
import com.gh.gamecenter.login.utils.LoginHelper;
import com.gh.gamecenter.common.callback.BiCallback;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.retrofit.ApiResponse;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.provider.IDataUtilsProvider;
import com.gh.gamecenter.core.provider.IDownloadManagerProvider;
import com.gh.gamecenter.core.provider.IErrorHelperProvider;
import com.gh.gamecenter.core.provider.IGameSubstituteRepositoryProvider;
import com.gh.gamecenter.core.provider.IMessageUnreadRepositoryProvider;
import com.gh.gamecenter.core.provider.IReservationRepositoryProvider;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.feature.entity.AvatarBorderEntity;
import com.gh.gamecenter.feature.entity.BackgroundImageEntity;
import com.gh.gamecenter.login.R;
import com.gh.gamecenter.login.entity.IdCardEntity;
import com.gh.gamecenter.login.entity.LoginTokenEntity;
import com.gh.gamecenter.login.entity.TokenEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.login.retrofit.ApiService;
import com.gh.gamecenter.login.retrofit.RetrofitManager;
import com.gh.gamecenter.login.utils.LoginUtils;
import com.gh.gamecenter.login.utils.NewLogUtils;
import com.gh.gamecenter.login.utils.QuickLoginHelper;
import com.lightgame.utils.Utils;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.HttpException;

/**
 * Created by khy on 28/11/17.
 */
public class UserRepository {

    private final SharedPreferences mPreferences;

    private Context mContext;

    private ApiService mApiService;

    private final MediatorLiveData<ApiResponse<UserInfoEntity>> mLoginObsResponseUserInfo = new MediatorLiveData<>();
    private final MediatorLiveData<ApiResponse<UserInfoEntity>> mEditObsResponseUserInfo = new MediatorLiveData<>();
    private final MediatorLiveData<Boolean> mUploadBackgroundLiveData = new MediatorLiveData<>();
    private final MediatorLiveData<Boolean> mUploadAvatarBorderLiveData = new MediatorLiveData<>();

    private final MediatorLiveData<LoginTokenEntity> mObservableLoginToken = new MediatorLiveData<>();

    private UserInfoEntity mCacheUserInfoEntity;
    private LoginTokenEntity mCacheLoginTokenEntity;

    public static UserRepository getInstance() {
        return SingletonHolder.INSTANCE;
    }

    private UserRepository() {
        mContext = HaloApp.getInstance().getApplicationContext();
        mApiService = RetrofitManager.getInstance().getApi();
        mPreferences = PreferenceManager.getDefaultSharedPreferences(mContext);
        checkLogin();
    }

    protected void checkLogin() {
        LoginTokenEntity tokenEntity = null;
        String userToken = mPreferences.getString(Constants.USER_TOKEN_KEY, null);
        if (!TextUtils.isEmpty(userToken)) {
            tokenEntity = GsonUtils.fromJson(userToken, LoginTokenEntity.class);
        }

        if (tokenEntity == null || tokenEntity.getRefreshToken() == null || tokenEntity.getAccessToken() == null) {
            logout();
            return;
        }
        TokenEntity refreshToken = tokenEntity.getRefreshToken();
        if (refreshToken.getExpire() > Utils.getTime(mContext)) {
            cacheAndNotifyLoginToken(tokenEntity); // 设置登录数据
            refreshUserInfo(null); // 刷新UserInfo,如果refreshToken过期 自动刷新
            return;
        }
        logout();
    }

    public void logout() {
        SensorsBridge.logout(UserManager.getInstance().getUserId());

        if (UserManager.getInstance().getLoginTokenEntity() != null
                && "qq".equals(UserManager.getInstance().getLoginTokenEntity().getLoginType())) {
            LoginHelper.logoutWithQQ();
        }

        UserManager.getInstance().logout();

        mLoginObsResponseUserInfo.postValue(null);
        mObservableLoginToken.postValue(null);

        if (mCacheLoginTokenEntity != null) {
            mCacheLoginTokenEntity = null;
        }

        if (mCacheUserInfoEntity != null) {
            mCacheUserInfoEntity = null;
        }

        SPUtils.setString(mPreferences, Constants.USER_TOKEN_KEY, null);
        SPUtils.setString(mPreferences, Constants.USER_INFO_KEY, null);
        SPUtils.setString(Constants.SP_REGULATION_TEST_PASS_STATUS, "");

        IReservationRepositoryProvider reservationRepository = (IReservationRepositoryProvider) ARouter.getInstance().build(RouteConsts.provider.reservationRepository).navigation();
        if (reservationRepository != null) {
            reservationRepository.clearReservations();
        }

        IGameSubstituteRepositoryProvider gameSubstituteRepository = (IGameSubstituteRepositoryProvider) ARouter.getInstance().build(RouteConsts.provider.gameSubstituteRepository).navigation();
        if (gameSubstituteRepository != null) {
            gameSubstituteRepository.updateSubstitutableGames();
        }

        // 通知页面更新
        EventBus.getDefault().post(new EBReuse(LOGOUT_TAG));

        IDataUtilsProvider dataUtils = (IDataUtilsProvider) ARouter.getInstance().build(RouteConsts.provider.dataUtils).navigation();
        dataUtils.getDeviceCertification();

        // 退出登录后进行预取号
        QuickLoginHelper.getPhoneInfo();
    }

    public LiveData<ApiResponse<UserInfoEntity>> getLoginUserInfo() {
        if (mCacheUserInfoEntity != null) {
            mLoginObsResponseUserInfo.postValue(new ApiResponse<>(mCacheUserInfoEntity));
        } else {
            String userInfo = mPreferences.getString(Constants.USER_INFO_KEY, null);
            if (!TextUtils.isEmpty(userInfo)) {
                UserInfoEntity infoEntity = GsonUtils.fromJson(userInfo, UserInfoEntity.class);
                cacheAndNotifyUserInfo(infoEntity, false);
            }
        }

        return mLoginObsResponseUserInfo;
    }

    public void login(final JSONObject content, final LoginTag loginTag) {
        login(content, loginTag, null);
    }

    // 登录前，做好body判断
    public void login(final JSONObject content, final LoginTag loginTag, BiCallback<LoginTokenEntity, ApiResponse<LoginTokenEntity>> callback) {

        Observable<LoginTokenEntity> observable = null;
        String userToken = null;

        try {
            JSONObject device = DeviceUtils.getLoginDevice(mContext.getApplicationContext());
            content.put("device", device);
            RequestBody body = RequestBody.create(MediaType.parse("application/json"), content.toString());

            if (loginTag == LoginTag.weibo) {
                userToken = content.getString("uid");
                observable = mApiService.loginByWeibo(body);
            } else if (loginTag == LoginTag.qq) {
                userToken = content.getString("openid");
                observable = mApiService.loginByQQ(body);
            } else if (loginTag == LoginTag.wechat) {
                userToken = content.getString("openid");
                observable = mApiService.loginByWechat(body);
            } else if (loginTag == LoginTag.douyin) {
                userToken = content.getString("openid");
                observable = mApiService.loginByDouYin(body);
            } else if (loginTag == LoginTag.phone) {
                userToken = content.getString("mobile");
                observable = mApiService.loginByMobile(body);
            } else if (loginTag == LoginTag.oauth) {
                userToken = content.getString("token");
                observable = mApiService.loginByOauth(body);
            } else {
                return;
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }

        if (observable == null) return;

        final String finalUserToken = userToken;
        observable
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<LoginTokenEntity>() {
                    @Override
                    public void onResponse(LoginTokenEntity response) {
                        super.onResponse(response);
                        // 设置登录方式
                        if (LoginTag.phone.equals(loginTag)) {
                            try {
                                response.setLoginType(content.getString("mobile"));
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        } else {
                            response.setLoginType(loginTag.name());
                        }

                        response.setId(finalUserToken);

                        userTokenHandle(response, loginTag);

                        IGameSubstituteRepositoryProvider gameSubstituteRepository = (IGameSubstituteRepositoryProvider) ARouter.getInstance().build(RouteConsts.provider.gameSubstituteRepository).navigation();
                        gameSubstituteRepository.updateSubstitutableGames();
                        IWechatBindHelperProvider wechatBindHelper = (IWechatBindHelperProvider) ARouter.getInstance().build(RouteConsts.provider.wechatHelper).navigation();
                        wechatBindHelper.getWechatConfig(null);

                        if (callback != null) {
                            callback.onFirst(response);
                        }
                    }

                    @Override
                    public void onApiFailure(ApiResponse<LoginTokenEntity> e) {
                        super.onApiFailure(e);
                        try {
                            HttpException httpException = e.getHttpException();
                            ApiResponse<UserInfoEntity> value = new ApiResponse<>();
                            value.setThrowable(value.getThrowable());
                            value.setHttpException(httpException);
                            mLoginObsResponseUserInfo.postValue(value);

                            if (LoginTag.qq.equals(loginTag)) {
                                LoginHelper.logoutWithQQ();
                            }

                            if (httpException != null) {
                                if ((httpException.code() == 400 || httpException.code() == 403)) {
                                    ResponseBody responseBody = httpException.response().errorBody();
                                    String string = responseBody.string();
                                    JSONObject content = new JSONObject(string);
                                    int code = content.getInt("code");
                                    if (httpException.code() == 400) {
                                        LoginUtils.outputErrorHint(mContext, code);
                                    } else if (code == 403092) {
                                        Utils.toast(mContext, "填写邀请码错误");
                                    } else {
                                        Utils.toast(mContext, mContext.getString(R.string.login_failure_hint_code, code));
                                    }
                                    Utils.log("login->onFailure:: code:" + code + " content:" + content.toString());
                                } else {
                                    Utils.toast(mContext, mContext.getString(R.string.login_failure_hint_code, httpException.code()));
                                }
                            } else {
                                Utils.toast(mContext, mContext.getString(R.string.login_failure_hint));
                            }
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }

                        if (callback != null) {
                            callback.onSecond(e);
                        }
                    }
                });
    }

    //更改用户信息
    @SuppressLint("CheckResult")
    public void changeUserInfo(final String content, final String editType, final Boolean isForcedToCertificate) {
        // 未登录也可以更新实名认证 https://git.ghzs.com/pm/halo-app-issues/-/issues/1526 (这里拦截掉实名更新类型的东西)
        if (UserViewModel.TYPE_ID_CARD.equals(editType)) {
            updateCertificate(content, isForcedToCertificate);
            return;
        }

        JSONObject object = new JSONObject();
        try {
            if (editType.equals(UserViewModel.TYPE_BACKGROUND)
                    || editType.equals(UserViewModel.TYPE_ICON_BORDER)) {
                object = new JSONObject();
                object.put(editType, new JSONObject(content));
            } else {
                object.put(editType, content);
            }
            JSONObject device = DeviceUtils.getLoginDevice(mContext.getApplicationContext());
            object.put("device", device);
        } catch (JSONException e) {
            e.printStackTrace();
        }

        RequestBody body = RequestBody.create(MediaType.parse("application/json"),
                object.toString());
        mApiService
                .changeUserInfo(body, UserManager.getInstance().getUserId())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<ResponseBody>() {
                    @Override
                    public void onResponse(ResponseBody response) {
                        super.onResponse(response);
                        switch (editType) {
                            case UserViewModel.TYPE_NAME:
                                mCacheUserInfoEntity.setName(content);
                                break;
                            case UserViewModel.TYPE_QQ:
                                mCacheUserInfoEntity.setQq(content);
                                break;
                            case UserViewModel.TYPE_MOBILE:
                                mCacheUserInfoEntity.setMobile(content);
                                break;
                            case UserViewModel.TYPE_GENDER:
                                mCacheUserInfoEntity.setGender(content);
                                break;
                            case UserViewModel.TYPE_REGION:
                                mCacheUserInfoEntity.setRegion(content);
                                break;
                            case UserViewModel.TYPE_PORTRAIT:
                                mCacheUserInfoEntity.setIcon(content);
                                break;
                            case UserViewModel.TYPE_ID_CARD:
                                mCacheUserInfoEntity.setIdCard(GsonUtils.fromJson(content, IdCardEntity.class));
                                break;
                            case UserViewModel.TYPE_INTRODUCE:
                                mCacheUserInfoEntity.setIntroduce(content);
                                break;
                            case UserViewModel.TYPE_BACKGROUND:
                                mCacheUserInfoEntity.setBackground(GsonUtils.fromJson(content, BackgroundImageEntity.class));
                                mUploadBackgroundLiveData.postValue(true);
                                break;
                            case UserViewModel.TYPE_ICON_BORDER:
                                mCacheUserInfoEntity.setIconBorder(GsonUtils.fromJson(content, AvatarBorderEntity.class));
                                mUploadAvatarBorderLiveData.postValue(true);
                                break;
                        }

                        userInfoHandle(mCacheUserInfoEntity, true);
                    }

                    @Override
                    public void onApiFailure(ApiResponse<ResponseBody> e) {
                        super.onApiFailure(e);
                        HttpException httpException = e.getHttpException();

                        ApiResponse<UserInfoEntity> value = new ApiResponse<>();
                        value.setThrowable(e.getThrowable());
                        value.setHttpException(httpException);
                        mEditObsResponseUserInfo.postValue(value);
                        if (editType.equals(UserViewModel.TYPE_BACKGROUND)) {
                            mUploadBackgroundLiveData.postValue(false);
                        }
                        if (editType.equals(UserViewModel.TYPE_ICON_BORDER)) {
                            mUploadAvatarBorderLiveData.postValue(false);
                        }

                        if (httpException == null || httpException.code() == Constants.NOT_NETWORK_CODE) {
                            Utils.toast(mContext, "请检查网络是否可用");
                            return;
                        }
                        try {
                            ResponseBody responseBody = e.getHttpException().response().errorBody();
                            String string = responseBody.string();
                            JSONObject content = new JSONObject(string);
                            int code = content.getInt("code");
                            LoginUtils.outputErrorHint(mContext, code);
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
                    }
                });
    }

    private void refreshUserInfo(LoginTag loginTag) {
        mApiService
                .getUserInfo(EnvHelper.getHost() + "tokens:validate")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(userInfoResponse(loginTag));
    }

    /**
     * 更新实名信息
     */
    @SuppressLint("CheckResult")
    private void updateCertificate(final String content, final Boolean isForcedToCertificate) {
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        IdCardEntity idCardEntity = GsonUtils.fromJson(content, IdCardEntity.class);
        userInfoEntity.setIdCard(idCardEntity);
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json"), GsonUtils.toJson(userInfoEntity));
        RetrofitManager.getInstance().getApi().postCertification(body)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new BiResponse<ResponseBody>() {
                    @Override
                    public void onSuccess(ResponseBody data) {
                        ApiResponse<UserInfoEntity> response = new ApiResponse<>();
                        response.setData(new UserInfoEntity());
                        mEditObsResponseUserInfo.postValue(response);
                        // 登录状态下更新实名认证信息
                        if (mCacheUserInfoEntity != null) {
                            mCacheUserInfoEntity.setIdCard(GsonUtils.fromJson(content, IdCardEntity.class));
                            userInfoHandle(mCacheUserInfoEntity, true);
                        }
                        try {
                            JSONObject object = new JSONObject(data.string());
                            boolean isUnQualified = object.getBoolean("minor");
                            int qualifyInt = 1;
                            if (!isUnQualified) {
                                qualifyInt = 2;
                            }
                            NewLogUtils.INSTANCE.logCertificationResult(isForcedToCertificate, qualifyInt);
                        } catch (Throwable e) {
                            e.printStackTrace();
                        }

                        // 重启因为实名认证而处于等待中的任务
                        IDownloadManagerProvider downloadManager = (IDownloadManagerProvider) ARouter.getInstance().build(RouteConsts.provider.downloadManager).navigation();
                        downloadManager.resumeAllInvisiblePendingTask();
                    }

                    @Override
                    public void onFailure(@NonNull Exception exception) {
                        mEditObsResponseUserInfo.postValue(null);
                        IErrorHelperProvider errorHelper = (IErrorHelperProvider) ARouter.getInstance().build(RouteConsts.provider.errorHelper).navigation();
                        errorHelper.handleLoginError(HaloApp.getInstance(), (HttpException) exception, "", true);
                        NewLogUtils.INSTANCE.logCertificationResult(isForcedToCertificate, 0);
                    }
                });
    }


    /**
     * 同步实名信息
     */
    @SuppressLint("CheckResult")
    public void syncCertificate(final String realName, final String idCard) {
        Map<String, Map<String, String>> map = new HashMap<>();
        Map<String, String> info = new HashMap<>();
        info.put("id", idCard);
        info.put("name", realName);
        map.put("id_card", info);
        RequestBody body = RequestBody.create(
                MediaType.parse("application/json"), new JSONObject(map).toString());
        RetrofitManager.getInstance().getApi().postSyncCertification(body)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Response<ResponseBody>() {
                    @Override
                    public void onResponse(@Nullable ResponseBody response) {
                        super.onResponse(response);
                        IDataUtilsProvider dataUtils = (IDataUtilsProvider) ARouter.getInstance().build(RouteConsts.provider.dataUtils).navigation();
                        dataUtils.getDeviceCertification();
                    }

                    @Override
                    public void onApiFailure(ApiResponse<ResponseBody> e) {
                        super.onApiFailure(e);

                    }
                });
    }

    private Response<UserInfoEntity> userInfoResponse(final LoginTag loginTag) {
        return new Response<UserInfoEntity>() {
            @Override
            public void onResponse(UserInfoEntity response) {
                super.onResponse(response);
                userInfoHandle(response, false);

                IReservationRepositoryProvider reservationRepository = (IReservationRepositoryProvider) ARouter.getInstance().build(RouteConsts.provider.reservationRepository).navigation();
                reservationRepository.refreshReservations();

                UserManager.getInstance().refreshUserRegulationTestStatus();

                if (loginTag != null) {
                    Utils.toast(mContext, R.string.login_success);
                    EventBus.getDefault().post(new EBReuse(LOGIN_TAG));

                    IMessageUnreadRepositoryProvider messageUnreadRepository = (IMessageUnreadRepositoryProvider) ARouter.getInstance().build(RouteConsts.provider.messageUnreadRepository).navigation();
                    messageUnreadRepository.loadMessageUnreadData();
                }

                if (UserManager.getInstance().getLoginTokenEntity() != null) {
                    IAppProvider appProvider = (IAppProvider) ARouter.getInstance().build(RouteConsts.provider.app).navigation();
                    if (UserManager.getInstance().getLoginTokenEntity().isFirstLogin()) {
                        appProvider.getFlavorProvider().logEvent("active_register");
                    }

                    SensorsBridge.login(UserManager.getInstance().getUserId());
                    if (loginTag != null) {
                        SensorsBridge.trackEvent("LoginResult", "login_type", loginTag.toChinese(), "login_result", "成功");
                    }
                }
            }

            @Override
            public void onApiFailure(ApiResponse<UserInfoEntity> e) {
                super.onApiFailure(e);
                mLoginObsResponseUserInfo.postValue(e);
                if (loginTag != null) {
                    IErrorHelperProvider errorHelper = (IErrorHelperProvider) ARouter.getInstance().build(RouteConsts.provider.errorHelper).navigation();
                    errorHelper.handleLoginError(mContext, e.getHttpException(), loginTag.toChinese(), false);
                    logout();
                }

                if (PackageFlavorHelper.IS_TEST_FLAVOR) {
                    try {
                        HttpException httpException = e.getHttpException();
                        ResponseBody responseBody = httpException.response().errorBody();
                        Utils.log("UserInfo ->onApiFailure Code:" + httpException.code() + " ErrorBody:" + responseBody.string());
                    } catch (Exception e1) {
                        e1.printStackTrace();
                    }
                }
            }
        };
    }


    private void userInfoHandle(final UserInfoEntity userInfo, boolean isEditUserInfo) {
        SPUtils.setString(mPreferences, Constants.USER_INFO_KEY, GsonUtils.toJson(userInfo));

        cacheAndNotifyUserInfo(userInfo, isEditUserInfo);
    }

    private void userTokenHandle(final LoginTokenEntity tokenEntity, LoginTag loginTag) {
        SPUtils.setString(mPreferences, Constants.USER_TOKEN_KEY, GsonUtils.toJson(tokenEntity));
        cacheAndNotifyLoginToken(tokenEntity);

        refreshUserInfo(loginTag);
    }

    public void cacheAndNotifyUserInfo(UserInfoEntity userInfoEntity, boolean isEditUserInfo) {
        setUserManagerData(null, userInfoEntity);

        mCacheUserInfoEntity = userInfoEntity;
        mLoginObsResponseUserInfo.postValue(new ApiResponse<>(userInfoEntity));

        if (isEditUserInfo) {
            mEditObsResponseUserInfo.postValue(new ApiResponse<>(userInfoEntity));
        } else {
            IDataUtilsProvider dataUtils = (IDataUtilsProvider) ARouter.getInstance().build(RouteConsts.provider.dataUtils).navigation();
            dataUtils.getDeviceCertification();
        }
    }

    @Nullable
    public UserInfoEntity getCacheUserInfoEntity() {
        return mCacheUserInfoEntity;
    }

    private void cacheAndNotifyLoginToken(LoginTokenEntity loginTokenEntity) {
        setUserManagerData(loginTokenEntity, null);

        mCacheLoginTokenEntity = loginTokenEntity;
        mObservableLoginToken.postValue(loginTokenEntity);
    }


    public void setUserManagerData(LoginTokenEntity loginTokenEntity, UserInfoEntity userInfoEntity) {
        if (loginTokenEntity != null) {
            UserManager.getInstance().setLoginTokenEntity(loginTokenEntity);
        }
        if (userInfoEntity != null) {
            UserManager.getInstance().setUserInfoEntity(userInfoEntity);
        }

    }

    public MediatorLiveData<ApiResponse<UserInfoEntity>> getEditObsUserInfo() {
        return mEditObsResponseUserInfo;
    }

    public MediatorLiveData<Boolean> getUploadBackgroundLiveData() {
        return mUploadBackgroundLiveData;
    }

    public MediatorLiveData<Boolean> getUploadAvatarBorderLiveData() {
        return mUploadAvatarBorderLiveData;
    }

    private static class SingletonHolder {
        private static final UserRepository INSTANCE = new UserRepository();
    }
}
