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.Unit;
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 me.goldze.mvvmhabit.utils.ToastUtils;
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();

    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) {
                    isDownloadVeterinary.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) {
            requestBasicInfo();
        } else if (isDownloadUnit.get() && !isUnitDownload) {
            queryUnitInputTime(unitPageIndex, 100000);
        } else if (isDownloadVeterinary.get() && !isVeterinaryDownload) {
            requestVeterinary();
        } else if (isDownloadVillusBuy.get() && !isVillusBuyDownload) {
            requestVillusBuy();
        } else {
            startActivity(MainActivity.class);
            finish();
        }

    }

    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) {

        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() {
        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.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() {
        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() {
        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();
                })
        );
    }

}
