package com.phlx.wool.ui.login;

import android.app.Activity;
import android.app.Application;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableField;
import androidx.databinding.ObservableInt;

import com.google.gson.Gson;
import com.phlx.wool.Configs;
import com.phlx.wool.data.Repository;
import com.phlx.wool.data.VMFactory;
import com.phlx.wool.entity.User;
import com.phlx.wool.net.NetworkUtils;
import com.phlx.wool.params.CattleResponse;
import com.phlx.wool.params.UserParams;
import com.phlx.wool.ui.base.BackBarVM;
import com.phlx.wool.ui.main.MainActivity;
import com.phlx.wool.ui.splash.SplashActivity;
import com.phlx.wool.util.StringUtil;
import com.phlx.wool.util.TextUtil;

import io.reactivex.functions.Consumer;
import me.goldze.mvvmhabit.binding.command.BindingAction;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.http.ResponseThrowable;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.SPUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * 登录页数据处理
 */

public class LoginVM extends BackBarVM<Repository> {
    //用户账号输入监听
    public ObservableField<String> userName = new ObservableField<>("");
    //用户密码输入监听
    public ObservableField<String> password = new ObservableField<>("");
    //用户账号EditText监听
    public ObservableInt clearBtnVisibility = new ObservableInt();
    //监听密码显隐
    public SingleLiveEvent<Boolean> pSwitchEvent = new SingleLiveEvent<>();
    public SingleLiveEvent<Boolean> exitEvent = new SingleLiveEvent<>();
    //更新app
    public SingleLiveEvent<String> appUpdateEvent = new SingleLiveEvent<>();


    public LoginVM(@NonNull Application application, Repository repository) {
        super(application, repository);
        //从本地取得数据绑定到View层
        //        userName.set(model.getUserName());
        //        password.set(model.getPassword());

        userName.set("ds02");
        password.set("123456");
    }

    //初始化ToolBar
    public void initToolbar() {
        setBackIconVisibleObservable(View.GONE);
        setBackTitleText("");
    }

    //清除用户名的点击事件
    public BindingCommand clearUserNameOnClickCommand = new BindingCommand(() -> userName.set(""));
    //密码显示点击事件
    public BindingCommand passwordShowSwitchOnClickCommand =
            new BindingCommand(() -> {
                pSwitchEvent.setValue(pSwitchEvent.getValue() == null || !pSwitchEvent.getValue());
            });
    //用户名输入框焦点改变的回调事件
    public BindingCommand<Boolean> onFocusChangeCommand =
            new BindingCommand<>(hasFocus -> {
                if (hasFocus) {
                    clearBtnVisibility.set(View.VISIBLE);
                } else {
                    clearBtnVisibility.set(View.INVISIBLE);
                }
            });
    //离线,联机
    public BindingCommand<String> isOnlineCheckedChangeCommand = new BindingCommand<String>(s -> {
        if (s.equals("离线")) {
            Configs.isOnLine = false;
        } else if (s.equals("联机")) {
            Configs.isOnLine = true;
        }
    });
    //登录按钮的点击事件
    public BindingCommand loginOnClickCommand = new BindingCommand(new BindingAction() {
        @Override
        public void call() {
            if (Configs.isOnLine) {
                login();
            } else {
                offLine();
            }
        }
    });

    //退出按钮的点击事件
    public BindingCommand loginOutClickCommand =
            new BindingCommand(() -> exitEvent.setValue(exitEvent.getValue() == null || !exitEvent.getValue()));


    /**
     * 登陆
     **/
    private void login() {
        if (checkPerson(userName.get(), password.get()))
            return;
        String postInfoStr = new Gson().toJson(new UserParams(userName.get(), password.get()));
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"),
                postInfoStr);
        addSubscribe(model.loginPost(body)
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .compose(RxUtils.schedulersTransformer())
                .compose(RxUtils.exceptionTransformer())
                .doOnSubscribe(disposable -> showDialog("正在登录..."))
                .subscribe((Consumer<CattleResponse<User>>) response -> {

                    dismissDialog();
                    KLog.e("login", response.toString());
                    if (response.getCode() == 0) {

                        //保存账号密码
                        model.saveUserName(userName.get());
                        model.savePassword(password.get());
                        if (response.getData() != null) {
                            model.saveToken(response.getData().getToken());
                            model.saveEmail(response.getData().getUser().getEmail());
                            model.savePhone(response.getData().getUser().getPhonenumber());
                            model.saveFrequencyConfig(response.getData().getUser().getFrequencyConfig());
                            Configs.FREQUENCY_CONFIG = response.getData().getUser().getFrequencyConfig();
                            model.saveBreed(response.getData().getUser().getDept().getDeptName());
                            SPUtils.getInstance().put(Configs.SP_NAME, response.getData().getUser().getUserName());
                        }
                        VMFactory.getInstance(getApplication()).refreshRepository();
                        if (SPUtils.getInstance().getBoolean("isFirst", true)) {
                            startActivity(SplashActivity.class);
                            finish();
                        } else {
                            startActivity(MainActivity.class);
                            finish();
                        }
                    } else {
                        ToastUtils.showShort("服务器:" + response.getMsg());
                    }
                }, (Consumer<ResponseThrowable>) throwable -> {
                    dismissDialog();
                    ToastUtils.showShort(throwable.message);
                })
        );

    }

    private boolean checkPerson(String name, String psd) {
        if (StringUtil.isSpace(name)) {
            ToastUtils.showShort("请输入账号！");
            return true;
        }
        if (StringUtil.isSpace(psd)) {
            ToastUtils.showShort("请输入密码！");
            return true;
        }
        return false;
    }


    /**
     * 离线登录
     */
    private void offLine() {
        //检测账号密码是否为空
        if (checkPerson(userName.get(), password.get()))
            return;
        //检测本地是否保存账号密码
        if (!TextUtil.isSpace(model.getUserName()) && !TextUtil.isSpace(model.getPassword())) {
            if (!model.getUserName().equals(userName.get())) {
                ToastUtils.showShort("账号错误");
                return;
            }
            if (!model.getUserName().equals(userName.get())) {
                ToastUtils.showShort("密码错误");
                return;
            }
            startActivity(MainActivity.class);
            finish();
        } else {
            ToastUtils.showShort("请先联机登录");
        }

    }


    /**
     * 判断网络，网络可用时连接服务器获取版本，不可用则忽略
     */
    public void requestVersion(Activity activity) {
        if (NetworkUtils.isAvailable(activity)) {

            addSubscribe(model.versionGet()
                    .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                    .compose(RxUtils.schedulersTransformer())
                    .compose(RxUtils.exceptionTransformer())
                    .doOnSubscribe(disposable -> showDialog("正在检测版本..."))
                    .subscribe((Consumer<CattleResponse<String>>) response -> {
                        dismissDialog();
                        if (response.getCode() == 0) {
                            appUpdateEvent.setValue(response.getData());
                        }
                    }, (Consumer<ResponseThrowable>) throwable -> {
                        dismissDialog();
                        ToastUtils.showShort(throwable.message);
                    })
            );
        }

    }

}
