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.GsonBuilder;
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.Harmless;
import com.phlx.wool.entity.HarmlessDao;
import com.phlx.wool.entity.HarmlessDetail;
import com.phlx.wool.entity.HarmlessDetailDao;
import com.phlx.wool.entity.Marking;
import com.phlx.wool.entity.MarkingDao;
import com.phlx.wool.entity.Quarantine;
import com.phlx.wool.entity.QuarantineDao;
import com.phlx.wool.entity.QuarantineDetail;
import com.phlx.wool.entity.QuarantineDetailDao;
import com.phlx.wool.entity.VillusBuyEntity;
import com.phlx.wool.entity.VillusBuyEntityDao;
import com.phlx.wool.entity.VillusGaugeEntity;
import com.phlx.wool.entity.VillusGaugeEntityDao;
import com.phlx.wool.params.CattleResponse;
import com.phlx.wool.params.UploadParams;
import com.phlx.wool.ui.base.BackBarVM;

import org.greenrobot.greendao.query.QueryBuilder;

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.http.ResponseThrowable;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
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 UploadVM extends BackBarVM<Repository> {

    private String toastStr = "";

    public ObservableField<Boolean> isUploadMarking = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isUploadHarmless = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isUploadQuarantine = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isUploadVillusBuy = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isUploadVillusGauge = new ObservableField<Boolean>(false);
    public ObservableField<Boolean> isUploadAll = new ObservableField<Boolean>(false);
    public ObservableInt uploadDataVisibility = new ObservableInt();

    private boolean isMarkingUpload, isHarmlessUpload, isQuarantineUpload, isVillusBuyUpload, isVillusGaugeUpload;

    public UploadVM(@NonNull Application application, Repository repository) {
        super(application, repository);
        if (Configs.isOnLine) {
            uploadDataVisibility.set(View.VISIBLE);
        } else {
            uploadDataVisibility.set(View.GONE);
        }
    }

    //初始化ToolBar
    public void initToolbar() {
        setBackTitleText("上传");
    }

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

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

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

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

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

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

    private void isAllSelected(boolean isSelected) {
        isUploadMarking.set(isSelected);
        isUploadHarmless.set(isSelected);
        isUploadQuarantine.set(isSelected);
        isUploadVillusBuy.set(isSelected);
        isUploadVillusGauge.set(isSelected);
    }

    private void uploadNext() {

        if (isUploadMarking.get() && !isMarkingUpload) {
            uploadMarking();
        } else if (isUploadHarmless.get() && !isHarmlessUpload) {
            uploadHarmless();
        } else if (isUploadQuarantine.get() && !isQuarantineUpload) {
            uploadQuarantine();
        } else if (isUploadVillusBuy.get() && !isVillusBuyUpload) {
            uploadVillusBuy();
        } else if (isUploadVillusGauge.get() && !isVillusGaugeUpload) {
            uploadVillusGauge();
        } else {
            if (!isUploadMarking.get() && !isUploadHarmless.get() && !isUploadQuarantine.get() && !isUploadVillusBuy.get() && !isUploadVillusGauge.get()) {
                ToastUtils.showShort("请选择上传的项目");
            } else if (!"".equals(toastStr)) {
                ToastUtils.showShort(toastStr);
            } else {
                ToastUtils.showShort("上传成功");
                finish();
            }
        }

    }

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

        isMarkingUpload = false;
        isHarmlessUpload = false;
        isQuarantineUpload = false;
        isVillusBuyUpload = false;
        isVillusGaugeUpload = false;
        toastStr = "";

        uploadNext();

    });

    private void uploadMarking() {

        QueryBuilder<Marking> builder =
                DbUtil.getInstance().getQueryBuilder(Marking.class).
                        where(MarkingDao.Properties.Status.eq("1"));
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<Marking>() {
            @Override
            public void onSuccess(List<Marking> result) {

                isMarkingUpload = true;
                if (result != null && result.size() > 0) {
                    String postInfoStr =
                            new GsonBuilder().serializeNulls()
//                                    .excludeFieldsWithoutExposeAnnotation()
                                    .create().toJson(new UploadParams<List<Marking>>(result));
                    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postInfoStr);
                    KLog.e(postInfoStr);
                    addSubscribe(model.submitMarking(body)
                            .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                            .compose(RxUtils.schedulersTransformer())
                            .compose(RxUtils.exceptionTransformer())
                            .doOnSubscribe(disposable -> showDialog("正在上传marking数据..."))
                            .subscribe((Consumer<CattleResponse<List<Marking>>>) response -> {
                                KLog.e(response.getCode() + response.getMsg());
                                if (response.getCode() == 0) {
                                    for (int i = 0; i < result.size(); i++) {
                                        result.get(i).setStatus(0);
                                    }
                                    DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                        @Override
                                        public void onNotification(boolean result) {
                                            if (result) {
                                                dismissDialog();
                                            } else {
                                                ToastUtils.showShort("删除marking数据失败");
                                            }
                                            uploadNext();
                                        }
                                    }).deleteAsyncBatch(Marking.class, result);
                                } else {
                                    dismissDialog();
                                    toastStr +="marking上传失败;";
                                    ToastUtils.showShort("marking上传失败");
                                    uploadNext();
                                }
                            }, (Consumer<ResponseThrowable>) throwable -> {
                                dismissDialog();
                                ToastUtils.showShort(throwable.message);
                                uploadNext();
                            })
                    );
                } else {
                    uploadNext();
                }
            }

            @Override
            public void onFailed() {
                ToastUtils.showShort("marking数据库查询失败");
            }
        }).queryAsyncAll(Marking.class, builder);


    }


    /**
     * 上传检疫数据
     */
    private void uploadQuarantine() {
        QueryBuilder<Quarantine> builder =
                DbUtil.getInstance().getQueryBuilder(Quarantine.class).
                        where(QuarantineDao.Properties.Status.eq("1"));
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<Quarantine>() {
            @Override
            public void onSuccess(List<Quarantine> result) {
                isQuarantineUpload = true;
                if (result != null && result.size() > 0) {
                    KLog.e(result.toString());
                    for (Quarantine quarantine : result) {
                        if (quarantine.getList() != null && quarantine.getList().size() > 0) {
                            quarantine.setList(null);
                        }
                        QueryBuilder<QuarantineDetail> builder =
                                DbUtil.getInstance().getQueryBuilder(QuarantineDetail.class).
                                        where(QuarantineDetailDao.Properties.QuarantineId.eq(quarantine.getId()));
                        List<QuarantineDetail> quarantineDetails =
                                DbUtil.getInstance().queryAll(QuarantineDetail.class, builder);
                        quarantine.setList(quarantineDetails);
                    }
                    KLog.e(result.toString());
                    String postInfoStr =
                            new GsonBuilder().serializeNulls()
//                                    .excludeFieldsWithoutExposeAnnotation()
                                    .create().toJson(new UploadParams<List<Quarantine>>(result));
                    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postInfoStr);
                    KLog.e(postInfoStr);
                    addSubscribe(model.submitQuarantine(body)
                            .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                            .compose(RxUtils.schedulersTransformer())
                            .compose(RxUtils.exceptionTransformer())
                            .doOnSubscribe(disposable -> showDialog("正在上传检疫数据..."))
                            .subscribe((Consumer<CattleResponse<List<Quarantine>>>) response -> {
                                KLog.e(response.getCode() + response.getMsg());
                                dismissDialog();
                                if (response.getCode() == 0) {
                                    DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                        @Override
                                        public void onNotification(boolean result) {
                                            if (result) {
                                                DbUtil.getInstance().deleteAll(QuarantineDetail.class);
                                            } else {
                                                ToastUtils.showShort("删除检疫数据失败");
                                            }
                                            uploadNext();
                                        }
                                    }).deleteAsyncBatch(Quarantine.class, result);
                                } else {
                                    toastStr +="上传检疫数据失败;";
                                    ToastUtils.showShort("上传检疫数据失败");
                                    uploadNext();
                                }
                            }, (Consumer<ResponseThrowable>) throwable -> {
                                dismissDialog();
                                ToastUtils.showShort(throwable.message);
                                uploadNext();
                            })
                    );
                } else {
                    uploadNext();
                }
            }

            @Override
            public void onFailed() {
                ToastUtils.showShort("检疫数据库查询失败");
            }
        }).queryAsyncAll(Quarantine.class, builder);
    }


    /**
     * 上传数据
     */
    private void uploadHarmless() {
        QueryBuilder<Harmless> builder =
                DbUtil.getInstance().getQueryBuilder(Harmless.class).
                        where(HarmlessDao.Properties.Status.eq("1"));
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<Harmless>() {
            @Override
            public void onSuccess(List<Harmless> result) {
                isHarmlessUpload = true;
                if (result != null && result.size() > 0) {
                    KLog.e(result.toString());
                    for (Harmless harmless : result) {
                        if (harmless.getList() != null && harmless.getList().size() > 0) {
                            harmless.setList(null);
                        }
                        QueryBuilder<HarmlessDetail> builder =
                                DbUtil.getInstance().getQueryBuilder(HarmlessDetail.class).
                                        where(HarmlessDetailDao.Properties.HarmlessId.eq(harmless.getId()));
                        List<HarmlessDetail> harmlessDetails =
                                DbUtil.getInstance().queryAll(HarmlessDetail.class, builder);
                        harmless.setList(harmlessDetails);
                    }
                    KLog.e(result.toString());
                    String postInfoStr =
                            new GsonBuilder().serializeNulls()
//                                    .excludeFieldsWithoutExposeAnnotation()
                                    .create().toJson(new UploadParams<List<Harmless>>(result));
                    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postInfoStr);
                    KLog.e(postInfoStr);
                    addSubscribe(model.submitHarmless(body)
                            .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                            .compose(RxUtils.schedulersTransformer())
                            .compose(RxUtils.exceptionTransformer())
                            .doOnSubscribe(disposable -> showDialog("正在上传无害化数据..."))
                            .subscribe((Consumer<CattleResponse<List<Harmless>>>) response -> {
                                KLog.e(response.getCode() + response.getMsg());
                                dismissDialog();
                                if (response.getCode() == 0) {
                                    DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                        @Override
                                        public void onNotification(boolean result) {
                                            if (result) {
                                                DbUtil.getInstance().deleteAll(HarmlessDetail.class);
                                            } else {
                                                ToastUtils.showShort("删除无害化数据失败");
                                            }
                                            uploadNext();
                                        }
                                    }).deleteAsyncBatch(Harmless.class, result);
                                } else {
                                    toastStr +="上传无害化失败;";
                                    ToastUtils.showShort("上传无害化失败");
                                    uploadNext();
                                }
                            }, (Consumer<ResponseThrowable>) throwable -> {
                                dismissDialog();
                                ToastUtils.showShort(throwable.message);
                                uploadNext();
                            })
                    );
                } else {
                    uploadNext();
                }
            }

            @Override
            public void onFailed() {
                ToastUtils.showShort("无害化数据库查询失败");
            }
        }).queryAsyncAll(Harmless.class, builder);
    }

    /**
     * 上传绒毛购买数据
     */
    private void uploadVillusBuy() {

        QueryBuilder<VillusBuyEntity> builder =
                DbUtil.getInstance().getQueryBuilder(VillusBuyEntity.class).
                        where(VillusBuyEntityDao.Properties.Status.eq("1"));
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<VillusBuyEntity>() {
            @Override
            public void onSuccess(List<VillusBuyEntity> result) {
                isVillusBuyUpload = true;
                if (result != null && result.size() > 0) {
                    KLog.e(result.toString());
                    String postInfoStr =
                            new GsonBuilder().serializeNulls()
//                                    .excludeFieldsWithoutExposeAnnotation()
                                    .create().toJson(new UploadParams<List<VillusBuyEntity>>(result));
                    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postInfoStr);
                    KLog.e(postInfoStr);
                    addSubscribe(model.submitVillusBuy(body)
                            .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                            .compose(RxUtils.schedulersTransformer())
                            .compose(RxUtils.exceptionTransformer())
                            .doOnSubscribe(disposable -> showDialog("正在上传绒毛购买数据..."))
                            .subscribe((Consumer<CattleResponse<List<VillusBuyEntity>>>) response -> {
                                KLog.e(response.getCode() + response.getMsg());
                                dismissDialog();
                                if (response.getCode() == 0) {
                                    for (VillusBuyEntity villusBuyEntity : result) {
                                        villusBuyEntity.setStatus(0);
                                    }
                                    DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                        @Override
                                        public void onNotification(boolean result) {
                                            if (result) {
                                            } else {
                                                ToastUtils.showShort("更新绒毛购买数据失败");
                                            }
                                            uploadNext();
                                        }
                                    }).updateAsyncBatch(VillusBuyEntity.class, result);
                                } else {
                                    toastStr +="上传绒毛购买数据失败;";
                                    ToastUtils.showShort("上传绒毛购买数据失败");
                                    uploadNext();
                                }
                            }, (Consumer<ResponseThrowable>) throwable -> {
                                dismissDialog();
                                ToastUtils.showShort(throwable.message);
                                uploadNext();
                            })
                    );
                } else {
                    uploadNext();
                }
            }

            @Override
            public void onFailed() {
                ToastUtils.showShort("查询绒毛购买数据失败");
            }
        }).queryAsyncAll(VillusBuyEntity.class, builder);
    }

    /**
     * 上传绒毛测量数据
     */
    private void uploadVillusGauge() {
        QueryBuilder<VillusGaugeEntity> builder =
                DbUtil.getInstance().getQueryBuilder(VillusGaugeEntity.class).
                        where(VillusGaugeEntityDao.Properties.Status.eq("1"));
        DbUtil.getInstance().setDbQueryCallBack(new DbQueryCallBack<VillusGaugeEntity>() {
            @Override
            public void onSuccess(List<VillusGaugeEntity> result) {
                isVillusGaugeUpload = true;
                if (result != null && result.size() > 0) {
                    KLog.e(result.toString());
                    String postInfoStr =
                            new GsonBuilder().serializeNulls()
//                                    .excludeFieldsWithoutExposeAnnotation()
                                    .create().toJson(new UploadParams<List<VillusGaugeEntity>>(result));
                    RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), postInfoStr);
                    KLog.e(postInfoStr);
                    addSubscribe(model.submitVillusGauge(body)
                            .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                            .compose(RxUtils.schedulersTransformer())
                            .compose(RxUtils.exceptionTransformer())
                            .doOnSubscribe(disposable -> showDialog("正在上传绒毛测量数据..."))
                            .subscribe((Consumer<CattleResponse<List<VillusGaugeEntity>>>) response -> {
                                KLog.e(response.getCode() + response.getMsg());
                                dismissDialog();
                                if (response.getCode() == 0) {
                                    for (VillusGaugeEntity villusGaugeEntity : result) {
                                        villusGaugeEntity.setStatus(0);
                                    }
                                    DbUtil.getInstance().setDbIDUCallBack(new DbIDUCallBack() {
                                        @Override
                                        public void onNotification(boolean result) {
                                            if (result) {
                                                DbUtil.getInstance().deleteAll(VillusGaugeEntity.class);
                                            } else {
                                                ToastUtils.showShort("删除绒毛测量数据失败");
                                            }
                                            uploadNext();
                                        }
                                    }).updateAsyncBatch(VillusGaugeEntity.class, result);
                                } else {
                                    toastStr +="上传绒毛测量数据失败;";
                                    ToastUtils.showShort("上传绒毛测量数据失败");
                                    uploadNext();
                                }
                            }, (Consumer<ResponseThrowable>) throwable -> {
                                dismissDialog();
                                ToastUtils.showShort(throwable.message);
                                uploadNext();
                            })
                    );
                } else {
                    uploadNext();
                }
            }

            @Override
            public void onFailed() {
                ToastUtils.showShort("查询绒毛测量数据失败");
            }
        }).queryAsyncAll(VillusGaugeEntity.class, builder);
    }

}
