package com.phlx.wool.ui.sync.vm;

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.db.DbUtil;
import com.phlx.wool.db.interf.DbIDUCallBack;
import com.phlx.wool.db.interf.DbQueryCallBack;
import com.phlx.wool.entity.Label;
import com.phlx.wool.entity.TreatmentMethod;
import com.phlx.wool.entity.Unit;
import com.phlx.wool.entity.Variety;
import com.phlx.wool.entity.Veterinary;
import com.phlx.wool.entity.VillusBuyEntity;
import com.phlx.wool.params.BasicParams;
import com.phlx.wool.params.CattleResponse;
import com.phlx.wool.params.PostParams;
import com.phlx.wool.ui.base.BackBarVM;
import com.phlx.wool.ui.main.MainActivity;

import org.greenrobot.greendao.query.WhereCondition;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import io.reactivex.functions.Consumer;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.binding.command.BindingConsumer;
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 okhttp3.MediaType;
import okhttp3.RequestBody;

/**
 * <pre>
 *     author : lei
 *     e-mail : 18600395998@163.com
 *     time   : 2020/04/29
 *     desc   :
 *     version: 1.0
 * </pre>
 */
public class DownloadVM extends BackBarVM<Repository> {


    private SimpleDateFormat dateFormat;

    public SingleLiveEvent<String> errorEvent = new SingleLiveEvent<>();

    private int labelPageIndex = 0;
    private int unitPageIndex = 0;
    public ObservableField<Boolean> isDownloadLabel = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isDownloadBasic = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isDownloadUnit = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isDownloadVeterinary = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isDownloadVillusBuy = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isDownloadAll = new ObservableField<Boolean>(false);
    public ObservableInt downloadDataVisibility = new ObservableInt();

    public ObservableField<String> markingLabelNum = new ObservableField<>("发标记录");
    public ObservableField<String> unitNum = new ObservableField<>("养殖单位");
    public ObservableField<String> basicNum = new ObservableField<>("基础信息");
    public ObservableField<String> veterinaryNum = new ObservableField<>("兽医");
    public ObservableField<String> villusBuyNum = new ObservableField<>("绒毛购买");

    private boolean isLabelDownload, isBasicDownload, isUnitDownload, isVeterinaryDownload, isVillusBuyDownload;

    public DownloadVM(@NonNull Application application, Repository repository) {
        super(application, repository);

        dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if (Configs.isOnLine) {
            downloadDataVisibility.set(View.VISIBLE);
        } else {
            downloadDataVisibility.set(View.GONE);
        }
    }

    //初始化ToolBar
    public void initToolbar() {
        setBackTitleText("下载");
    }

    public BindingCommand<Boolean> onDownloadLabelCommand =
            new BindingCommand<>(new BindingConsumer<Boolean>() {
                @Override
                public void call(Boolean isChecked) {
                    isDownloadLabel.set(isChecked);
                }
            });

    public BindingCommand<Boolean> onDownloadBasicCommand =
            new BindingCommand<>(new BindingConsumer<Boolean>() {
                @Override
                public void call(Boolean isChecked) {
                    isDownloadBasic.set(isChecked);
                }
            });

    public BindingCommand<Boolean> onDownloadUnitCommand =
            new BindingCommand<>(new BindingConsumer<Boolean>() {
                @Override
                public void call(Boolean isChecked) {
                    isDownloadUnit.set(isChecked);
                }
            });

    public BindingCommand<Boolean> onDownloadVeterinaryCommand =
            new BindingCommand<>(new BindingConsumer<Boolean>() {
                @Override
                public void call(Boolean isChecked) {
                    isDownloadVeterinary.set(isChecked);
                }
            });

    public BindingCommand<Boolean> onDownloadVillusBuyCommand =
            new BindingCommand<>(new BindingConsumer<Boolean>() {
                @Override
                public void call(Boolean isChecked) {
                    isDownloadVillusBuy.set(isChecked);
                }
            });

    public BindingCommand<Boolean> onDownloadAllCommand =
            new BindingCommand<>(new BindingConsumer<Boolean>() {
                @Override
                public void call(Boolean isChecked) {
                    isDownloadAll.set(isChecked);
                    isAllSelected(isChecked);
                }
            });

    private void isAllSelected(boolean isSelected) {
        isDownloadLabel.set(isSelected);
        isDownloadBasic.set(isSelected);
        isDownloadUnit.set(isSelected);
        isDownloadVeterinary.set(isSelected);
        isDownloadVillusBuy.set(isSelected);
    }

    public BindingCommand onDownloadClickCommand = new BindingCommand(() -> {

        isLabelDownload = false;
        isBasicDownload = false;
        isUnitDownload = false;
        isVeterinaryDownload = false;
        isVillusBuyDownload = false;
        downloadNext();

    });

    private void downloadNext() {

        if (isDownloadLabel.get() && !isLabelDownload) {
            baseDateUpload();
        } else if (isDownloadBasic.get() && !isBasicDownload) {
            DbUtil.getInstance().deleteAll(TreatmentMethod.class);
            DbUtil.getInstance().deleteAll(Variety.class);
            requestBasicInfo();
        } else if (isDownloadUnit.get() && !isUnitDownload) {
            queryUnitInputTime(unitPageIndex, 100000);
        } else if (isDownloadVeterinary.get() && !isVeterinaryDownload) {
            DbUtil.getInstance().deleteAll(Veterinary.class);
            requestVeterinary();
        } else if (isDownloadVillusBuy.get() && !isVillusBuyDownload) {
            requestVillusBuy();
        } else {
            refreshUploadCount();
            startActivity(MainActivity.class);
            finish();
        }

    }

    //查询每项记录数量
    public void refreshUploadCount() {
        markingLabelNum.set("发标记录 " + "(" + DbUtil.getInstance().count(Label.class) + ")");
        unitNum.set("养殖单位 " + "(" + DbUtil.getInstance().count(Unit.class) + ")");
        basicNum.set("基础信息 " + "(" + DbUtil.getInstance().count(TreatmentMethod.class) + "-" + DbUtil.getInstance().count(Variety.class) + ")");
        veterinaryNum.set("兽医 " + "(" + DbUtil.getInstance().count(Veterinary.class) + ")");
        villusBuyNum.set("绒毛购买 " + "(" + DbUtil.getInstance().count(VillusBuyEntity.class) + ")");
    }

    private void baseDateUpload() {

        showDialog("正在同步数据，请勿关闭屏幕或退出程序!");
        String sql = "TIMESTAMP IN " + "(SELECT MAX(TIMESTAMP) FROM LABEL)";
        WhereCondition.StringCondition stringCondition = new WhereCondition.StringCondition(sql);
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<Label>() {
            @Override
            public void onSuccess(List<Label> result) {
                long inputTime = 0;
                if (result != null && result.size() > 0) {
                    inputTime = result.get(0).getTimestamp();
                }
                requestLabel(0, inputTime, 100000);
            }

            @Override
            public void onFailed() {
                downloadNext();
            }
        }).queryAsync(Label.class, stringCondition);
    }


    /**
     * 获取标签数据
     */
    public void requestLabel(int index, long inputTime, int count) {

        isLabelDownload = true;

        PostParams postParams = new PostParams();
        postParams.setInputTime(inputTime);
        postParams.setPageNum(index);
        postParams.setPageSize(count);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");
        postParams.setYears(dateFormat.format(new Date()));
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(postParams));
        KLog.e("label", postParams.toString());
        addSubscribe(model.getLabelList(body)
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .compose(RxUtils.schedulersTransformer())
                .compose(RxUtils.exceptionTransformer())
                .doOnSubscribe(disposable -> {
                })
                .subscribe((Consumer<CattleResponse<List<Label>>>) response -> {

                    if (response.getCode() == 0) {
                        if (response.getData() != null && response.getData().size() > 0) {
                            KLog.e(response.getData().size());
                            DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                @Override
                                public void onNotification(boolean result) {
                                    if (result) {
                                        labelPageIndex++;
                                        requestLabel(labelPageIndex, inputTime, count);
                                    } else {
                                        downloadNext();
                                    }
                                }
                            }).insertAsyncBatch(Label.class, response.getData());
                        } else {
                            dismissDialog();
                            downloadNext();
                        }
                    } else {
                        errorEvent.setValue("标签数据-服务器 :" + response.getMsg());
                        downloadNext();
                    }
                }, (Consumer<ResponseThrowable>) throwable -> {
                    dismissDialog();
                    KLog.e(throwable.message);
                    errorEvent.setValue("同步标签数据失败");
                    downloadNext();
                })
        );

    }


    private void requestUnit(int index, long inputTime, int count) {

        isUnitDownload = true;
        PostParams postParams = new PostParams();
        postParams.setInputTime(inputTime);
        postParams.setPageNum(index);
        postParams.setPageSize(count);
        postParams.setYears("");
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(postParams));
        KLog.e("--Unit--" + postParams.toString());
        addSubscribe(model.getUnitList(body)
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .compose(RxUtils.schedulersTransformer())
                .compose(RxUtils.exceptionTransformer())
                .doOnSubscribe(disposable -> {
                })
                .subscribe((Consumer<CattleResponse<List<Unit>>>) response -> {

                    if (response.getCode() == 0) {
                        if (response.getData() != null && response.getData().size() > 0) {
                            KLog.e("--Unit--" + response.getData().size());
                            DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                @Override
                                public void onNotification(boolean result) {
                                    if (result) {
                                        unitPageIndex++;
                                        requestUnit(unitPageIndex, inputTime, count);
                                    } else {
                                        downloadNext();
                                    }
                                }
                            }).insertAsyncBatch(Unit.class, response.getData());
                        } else {
                            dismissDialog();
                            downloadNext();
                        }

                    } else {
                        errorEvent.setValue("服务器 :" + response.getMsg());
                        downloadNext();
                    }
                }, (Consumer<ResponseThrowable>) throwable -> {
                    dismissDialog();
                    KLog.e(throwable.message);
                    errorEvent.setValue("同步数据失败");
                    downloadNext();
                })
        );

    }


    public void queryUnitInputTime(int index, int count) {
        String sql = "TIMESTAMP IN " + "(SELECT MAX(TIMESTAMP) FROM UNIT)";
        WhereCondition.StringCondition stringCondition =
                new WhereCondition.StringCondition(sql);
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<Unit>() {
            @Override
            public void onSuccess(List<Unit> result) {
                long inputTime = 0;
                if (result != null && result.size() > 0) {
                    inputTime = result.get(0).getTimestamp();
                }
                requestUnit(index, inputTime, count);
            }

            @Override
            public void onFailed() {
                downloadNext();
            }
        }).queryAsync(Unit.class, stringCondition);
    }

    private void requestVeterinary() {
        isVeterinaryDownload = true;
        PostParams postParams = new PostParams();
        postParams.setPageNum(1);
        postParams.setInputTime(0);
        postParams.setPageSize(200);
        postParams.setYears("");
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(postParams));
        addSubscribe(model.getVeterinaryList(body)
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .compose(RxUtils.schedulersTransformer())
                .compose(RxUtils.exceptionTransformer())
                .doOnSubscribe(disposable -> {
                })
                .subscribe((Consumer<CattleResponse<List<Veterinary>>>) response -> {
                    if (response.getCode() == 0) {
                        if (response.getData() != null && response.getData().size() > 0) {
                            KLog.e(response.getData().size());
                            DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                @Override
                                public void onNotification(boolean result) {
                                    if (result) {
                                        dismissDialog();
                                        if (isDownloadBasic.get()) {
                                            showDialog("正在同步数据，请勿关闭屏幕或退出程序!");
                                        }
                                        downloadNext();
                                    }
                                }
                            }).insertAsyncBatch(Veterinary.class, response.getData());

                        } else {
                            dismissDialog();
                            errorEvent.setValue("缺少兽医基础数据，请联系管理员");
                            downloadNext();
                        }
                    } else {
                        errorEvent.setValue("服务器 :" + response.getMsg());
                        downloadNext();
                    }
                }, (Consumer<ResponseThrowable>) throwable -> {
                    dismissDialog();
                    KLog.e(throwable.message);
                    errorEvent.setValue("同步数据失败");
                    downloadNext();
                })
        );
    }

    private void requestVillusBuy() {
        isVillusBuyDownload = true;
        List<VillusBuyEntity> villusBuy = model.getVillusBuy();
        PostParams postParams = new PostParams();
        Date _date = null;
        try {
            if (villusBuy != null && villusBuy.size() > 0) {
                _date = dateFormat.parse(villusBuy.get(0).getCreateTime());
                postParams.setInputTime(_date.getTime());
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        postParams.setPageNum(1);
        postParams.setPageSize(200);
//        postParams.setYears("2018");
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(postParams));
        addSubscribe(model.getVillusBuyList(body)
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .compose(RxUtils.schedulersTransformer())
                .compose(RxUtils.exceptionTransformer())
                .doOnSubscribe(disposable -> {
                })
                .subscribe((Consumer<CattleResponse<List<VillusBuyEntity>>>) response -> {
                    if (response.getCode() == 0) {
                        if (response.getData() != null && response.getData().size() > 0) {
                            KLog.e(response.getData().size());
                            DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                @Override
                                public void onNotification(boolean result) {
                                    if (result) {
                                        dismissDialog();
                                        if (isDownloadBasic.get()) {
                                            showDialog("正在同步绒毛购买数据，请勿关闭屏幕或退出程序!");
                                        }
                                        downloadNext();
                                    }
                                }
                            }).insertAsyncBatch(VillusBuyEntity.class, response.getData());

                        } else {
                            dismissDialog();
                            downloadNext();
                        }

                    } else {
                        errorEvent.setValue("服务器 :" + response.getMsg());
                        downloadNext();
                    }
                }, (Consumer<ResponseThrowable>) throwable -> {
                    dismissDialog();
                    KLog.e(throwable.message);
                    errorEvent.setValue("同步数据失败");
                    downloadNext();
                })
        );
    }

    private void requestBasicInfo() {

        isBasicDownload = true;
        PostParams postParams = new PostParams();
        postParams.setInputTime(0);
        postParams.setPageNum(1);
        postParams.setPageSize(200);
        postParams.setYears("");
        RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(postParams));
        addSubscribe(model.getBasicInfo(body)
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .compose(RxUtils.schedulersTransformer())
                .compose(RxUtils.exceptionTransformer())
                .doOnSubscribe(disposable -> {
                })
                .subscribe((Consumer<CattleResponse<BasicParams>>) response -> {
                    dismissDialog();
                    if (response.getCode() == 0) {
                        if (response.getData().getAncestryinfoList() != null && response.getData().getAncestryinfoList().size() > 0) {
                            model.saveVariety(response.getData().getAncestryinfoList());
                        }
                        if (response.getData().getInnocuitymanagewayinfoList() != null && response.getData().getInnocuitymanagewayinfoList().size() > 0) {
                            model.saveTreatmentMethod(response.getData().getInnocuitymanagewayinfoList());
                        }
                        SPUtils.getInstance().put("isFirst", false);
                        downloadNext();
                    } else {
                        errorEvent.setValue("服务器 :" + response.getMsg());
                        downloadNext();
                    }
                }, (Consumer<ResponseThrowable>) throwable -> {
                    dismissDialog();
                    KLog.e(throwable.message);
                    errorEvent.setValue("同步数据失败");
                    downloadNext();
                })
        );
    }

    @Override
    public void onResume() {
        super.onResume();
        refreshUploadCount();
    }
}
