package com.gingersoft.gsa.cloud.table.mvp.presenter;

import android.app.Activity;
import android.app.Application;
import android.content.Intent;
import android.text.TextUtils;
import android.view.View;

import com.gingersoft.gsa.cloud.app.GsaCloudApplication;
import com.gingersoft.gsa.cloud.common.bean.BaseResult;
import com.gingersoft.gsa.cloud.common.constans.FoodSummaryConstans;
import com.gingersoft.gsa.cloud.common.constans.GoldConstants;
import com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager;
import com.gingersoft.gsa.cloud.common.core.table.TableBean;
import com.gingersoft.gsa.cloud.common.core.table.TableExtBean;
import com.gingersoft.gsa.cloud.common.function.XFunctionManager;
import com.gingersoft.gsa.cloud.common.function.XFunctionViews;
import com.gingersoft.gsa.cloud.common.logan.LoganManager;
import com.gingersoft.gsa.cloud.common.utils.JsonUtils;
import com.gingersoft.gsa.cloud.common.utils.other.SPUtils;
import com.gingersoft.gsa.cloud.database.bean.Food;
import com.gingersoft.gsa.cloud.database.bean.FoodCombo;
import com.gingersoft.gsa.cloud.database.bean.Function;
import com.gingersoft.gsa.cloud.database.bean.Modifier;
import com.gingersoft.gsa.cloud.database.utils.FoodComboDaoUtils;
import com.gingersoft.gsa.cloud.database.utils.ModifierDaoUtils;
import com.gingersoft.gsa.cloud.order.bean.response.OrderResponse;
import com.gingersoft.gsa.cloud.order.commodity.OrderDetail;
import com.gingersoft.gsa.cloud.order.order.BaseOrder;
import com.gingersoft.gsa.cloud.order.order.DoshokuOrder;
import com.gingersoft.gsa.cloud.pay.bean.PosActionStatusExceptionParam;
import com.gingersoft.gsa.cloud.pay.pos.PosAction;
import com.gingersoft.gsa.cloud.pay.pos.fragment.PosActionStatusExceptionFragment;
import com.gingersoft.gsa.cloud.table.FunctionTable;
import com.gingersoft.gsa.cloud.table.R;
import com.gingersoft.gsa.cloud.table.mvp.contract.TableContract;
import com.gingersoft.gsa.cloud.table.mvp.model.bean.FoodSummary;
import com.gingersoft.gsa.cloud.table.mvp.model.bean.response.BaseOrderResponse;
import com.gingersoft.gsa.cloud.table.mvp.model.constant.SkyOrderConstant;
import com.gingersoft.gsa.cloud.table.mvp.action.table.MoveTableAction;
import com.gingersoft.gsa.cloud.table.mvp.action.OnNetworkCallbackListener;
import com.gingersoft.gsa.cloud.table.mvp.action.table.PrintServingPaperAction;
import com.gingersoft.gsa.cloud.table.mvp.action.table.PrintSkyorderAction;
import com.gingersoft.gsa.cloud.table.mvp.action.table.ResetSkyorderAction;
import com.gingersoft.gsa.cloud.table.mvp.action.table.ResetTableAction;
import com.gingersoft.gsa.cloud.table.mvp.action.table.SplitTableAction;
import com.gingersoft.gsa.cloud.table.mvp.action.table.TableAction;
import com.gingersoft.gsa.cloud.table.mvp.model.utils.OrderAssemblyUtil;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.CoordinatorlayoutActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.TableActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.adapter.BottomFunctionAdapter;
import com.gingersoft.gsa.cloud.table.mvp.ui.widget.SplitTableDialog;
import com.gingersoft.gsa.cloud.ui.widget.dialog.BaseRetryDialog;
import com.gingersoft.gsa.cloud.ui.widget.dialog.CommonTipDialog;
import com.google.android.material.internal.NavigationMenuItemView;
import com.jess.arms.base.DefaultAdapter;
import com.jess.arms.di.scope.ActivityScope;
import com.jess.arms.http.imageloader.ImageLoader;
import com.jess.arms.integration.AppManager;
import com.jess.arms.mvp.BasePresenter;
import com.jess.arms.utils.RxLifecycleUtils;
import com.qmuiteam.qmui.widget.dialog.QMUIDialog;
import com.qmuiteam.qmui.widget.dialog.QMUIDialogAction;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.xuexiang.rxutil2.rxjava.RxJavaUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import okhttp3.FormBody;
import okhttp3.RequestBody;

import static com.gingersoft.gsa.cloud.order.commodity.OrderDetail.FOOD_TYPE;
import static com.gingersoft.gsa.cloud.order.commodity.OrderDetail.MODIFIER_TYPE;


/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 12/27/2019 19:19
 * <a href="mailto:jess.yan.effort@gmail.com">Contact me</a>
 * <a href="https://github.com/JessYanCoding">Follow me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms">Star me</a>
 * <a href="https://github.com/JessYanCoding/MVPArms/wiki">See me</a>
 * <a href="https://github.com/JessYanCoding/MVPArmsTemplate">模版请保持更新</a>
 * ================================================
 */
@ActivityScope
public class TablePresenter extends BasePresenter<TableContract.Model, TableContract.View> {
    @Inject
    RxErrorHandler mErrorHandler;
    @Inject
    Application mApplication;
    @Inject
    ImageLoader mImageLoader;
    @Inject
    AppManager mAppManager;

    private TableActivity IActivity;

    /**
     * 分檯弹窗
     */
    private SplitTableDialog mSplitTableDialog;

    private List<TableBean.DataBean> mTableList = new ArrayList<>();

    private BottomFunctionAdapter mBottomFunctionAdapter;

    @XFunctionViews(FunctionTable.TABLE_BOTTOM_GROUP)
    private List<Function> mBottomFunctionList = new ArrayList<>();

    private TableAction mTableAction;
    private List<TableAction> mTableActions = new ArrayList<>();
    /**
     * 选中操作的台名、id、分檯編號
     */
    private String originalTableName = "";
    private long originalTableId;
    private String originalTableNumber = "";
    private long originalScanId;
    /**
     * 转台需要转到台名、id、分檯編號
     */
    private String targetTableName = "";
    private long targetTableId;
    private String targetTableNumber = "";

    private Disposable mGetTablesDataDisposable;

    private Disposable mTablesPollingDisposable;

    @Inject
    public TablePresenter(TableContract.Model model, TableContract.View rootView) {
        super(model, rootView);
        this.IActivity = (TableActivity) rootView;
        XFunctionManager.inJect(this, FunctionTable.class);
        startTablePolling();
    }

    private void initTableActions(Activity context, List<Function> functions) {
        for (Function function : functions) {
            if (function.getResUrl().endsWith("init")) {
                mTableActions.add(new ResetTableAction(context));
            } else if (function.getResUrl().endsWith("move")) {
                mTableActions.add(new MoveTableAction(context));
            } else if (function.getResUrl().endsWith("initSkyorder")) {
                mTableActions.add(new ResetSkyorderAction(context));
            } else if (function.getResUrl().endsWith("skyorder")) {
                mTableActions.add(new PrintSkyorderAction(context, this));
            } else if (function.getResUrl().endsWith("splite")) {
                mTableActions.add(new SplitTableAction(context));
            } else if (function.getResUrl().endsWith("parper")) {
                mTableActions.add(new PrintServingPaperAction(context, this));
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.mAppManager = null;
        this.mImageLoader = null;
        this.mApplication = null;
        for (TableAction action : mTableActions) {
            action.destroy();
        }
        stopTablePolling();
    }

    public void initBottomFunction() {
        swapSkyorderPosition(mBottomFunctionList);
        initTableActions(IActivity, mBottomFunctionList);
        if (mBottomFunctionAdapter == null) {
            mBottomFunctionAdapter = new BottomFunctionAdapter(IActivity, mBottomFunctionList);
            mRootView.setBottomFunctionAdapter(mBottomFunctionAdapter);
        }
        initBottomFunctionListener();
    }

    private void initBottomFunctionListener() {
        mBottomFunctionAdapter.setOnItemClickListener(new DefaultAdapter.OnRecyclerViewItemClickListener() {

            @Override
            public void onItemClick(View view, int viewType, Object data, int position) {
//                Function function = (Function) data;
//                switch (function.getStatus()) {
//                    case STATUS_NONACTIVATED:
//                        mRootView.showMessage("服務暫未開通,敬請期待");
//                        return;
//                    case STATUS_TIME_LIMIT:
//                        mRootView.showMessage("服務已到期,請前往續費");
//                        return;
//                }
                if (mTableActions.size() > position) {
                    mTableAction = mTableActions.get(position);
                    if (mTableAction != null) {
                        boolean isMoveTableAction = mTableAction instanceof MoveTableAction;
                        if (!isMoveTableAction) {
                            filterTableByAction();
                        }
                        mRootView.setCurrentTableAction(mTableAction);
                    }
                }
            }
        });
    }

    private void swapSkyorderPosition(List<Function> functions) {
        int skyorderPosition = -1;
        for (int i = 0; i < functions.size(); i++) {
            if (functions.get(i).getResUrl().equals("table/bottom/skyorder")) {
                skyorderPosition = i;
                break;
            }
        }
        if (skyorderPosition != -1) {
            if (functions.size() > 3) {
                Collections.swap(functions, 2, skyorderPosition);
            } else {
                Collections.swap(functions, 1, skyorderPosition);
            }
        }
    }

    public void getTables(boolean show, RefreshLayout refreshLayout) {
        int restaurantId = RestaurantInfoManager.newInstance().getRestaurantId() != 0 ? RestaurantInfoManager.newInstance().getRestaurantId() : 26;
        mModel.getTables(restaurantId)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> {
                    if (show && refreshLayout == null) {
                        mRootView.showLoading(null);
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> {
                    if (show && refreshLayout == null) {
                        mRootView.hideLoading();
                    }
                })
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<TableBean>(mErrorHandler) {

                    @Override
                    public void onSubscribe(Disposable d) {
                        super.onSubscribe(d);
                        mGetTablesDataDisposable = d;
                    }

                    @Override
                    public void onNext(@NonNull TableBean tableBean) {
                        if (!TableActivity.isRefreshData) {
                            return;
                        }
                        if (tableBean.isSuccess()) {
                            List<TableBean.DataBean> tableBeanData = tableBean.getData();
                            if (tableBeanData != null && tableBeanData.size() > 0) {
                                if (mTableList.size() > 0) {
                                    mTableList.clear();
                                }
                                sortTableList(tableBeanData);
                                mTableList.addAll(tableBeanData);
                                mRootView.returnTableList(tableBeanData);
                            } else {
                                mRootView.getCurrentTableFragment().showEmptyView(true, 0, null);
                            }
                        } else {
                            if (show) {
                                mRootView.getCurrentTableFragment().showMessage(tableBean.getErrMsg());
                            }
                            mRootView.getCurrentTableFragment().showEmptyView(false, 0, null);
                        }
                        resetRefreshLayout();
                    }

                    @Override
                    public void onError(Throwable t) {
                        super.onError(t);
                        if (mRootView.getCurrentTableFragment() != null) {
                            mRootView.getCurrentTableFragment().showEmptyView(false, 0, t);
                        }
                        resetRefreshLayout();
                    }

                    private void resetRefreshLayout() {
                        if (refreshLayout != null) {
                            refreshLayout.finishRefresh();
                            refreshLayout.resetNoMoreData();
                        }
                    }

                    private void sortTableList(List<TableBean.DataBean> dataBeanList) {
                        Comparator c = new Comparator<TableBean.DataBean>() {
                            @Override
                            public int compare(TableBean.DataBean o1, TableBean.DataBean o2) {
                                Integer sort1 = o1.getSort();
                                Integer sort2 = o2.getSort();
                                return sort1.compareTo(sort2);
                            }
                        };
                        Collections.sort(dataBeanList, c);
                    }
                });
    }

    public void loadOrderToPrintParper(TableBean.DataBean tableBean, OnNetworkCallbackListener networkCallBackListener) {
        if (tableBean.getOrderId() == null) {
            return;
        }
        mModel.getOrderById(tableBean.getOrderId())
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseOrderResponse respose) {
                        if (networkCallBackListener != null) {
                            networkCallBackListener.onResult(respose);
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (networkCallBackListener != null) {
                            networkCallBackListener.onError(t);
                        }
                    }
                });
    }

    public void openTable(long tableId, TableBean.DataBean tableExtBean) {
        String tableNumber = "";
        if (tableExtBean != null) {
            tableNumber = tableExtBean.getTableNumber();
        }
        RequestBody requestBody = new FormBody.Builder()
                .add("id", String.valueOf(tableId))
                .add("tableNumber", tableNumber)
                .build();
        mModel.openTable(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseOrderResponse respose) {
                        if (respose.isSuccess()) {
                            //設置當前開台數據
                            TableBean.DataBean openTableBean;
                            if (tableExtBean != null) {
                                openTableBean = tableExtBean;
                                if (mSplitTableDialog != null) {
                                    mSplitTableDialog.closeDialog();
                                }
                            } else {
                                openTableBean = getTableById(tableId);
                            }

                            DoshokuOrder doshokuOrder = DoshokuOrder.getInstance();

                            OrderResponse orderBean = respose.getData();
                            if (orderBean != null && respose.getData().getOrderDetails() != null) {

                                if (!TextUtils.isEmpty(orderBean.getTxnId())) {
                                    //有支付異常事項需要處理
                                    PosActionStatusExceptionFragment statusExceptionFragment = IActivity.findFragment(PosActionStatusExceptionFragment.class);
                                    if (statusExceptionFragment == null) {
                                        PosActionStatusExceptionParam statusExceptionParam = new PosActionStatusExceptionParam();
                                        statusExceptionParam.setTxnId(orderBean.getTxnId());
                                        statusExceptionParam.setAmount(orderBean.getTotalAmount());
                                        statusExceptionParam.setOrderId(orderBean.getId());
                                        statusExceptionParam.setOrderNo(orderBean.getOrderNo());
                                        statusExceptionParam.setPayMethodName(orderBean.getPayName());
                                        statusExceptionParam.setPosAction(PosAction.RETRIEVAL);
                                        IActivity.loadRootFragment(R.id.fl_container, PosActionStatusExceptionFragment.newInstance(statusExceptionParam));
                                    } else {
                                        IActivity.start(statusExceptionFragment);
                                    }
                                    return;
                                }

                                if (respose.getData().getCreateTime() != null && openTableBean != null) {
                                    //將開台時間設置為訂單創建時間
                                    openTableBean.setCreateTime(respose.getData().getCreateTime());
                                }

                                List<OrderResponse.OrderDetailsBean> mealCommoditysBeans = orderBean.getOrderDetails();

                                setFoodPoints(mealCommoditysBeans);
                                //設置套餐topId
                                setTopId(mealCommoditysBeans);

                                //設置用餐人數
                                openTableBean.setPerson(orderBean.getPerson());
                                //緩存訂單信息
                                doshokuOrder.setOrderId(orderBean.getId());
                                doshokuOrder.setOrderNo(orderBean.getOrderNo());
                                doshokuOrder.setOrderPlaced(new OrderResponse(orderBean));
                                doshokuOrder.getShoppingCart().addCommodityList(OrderAssemblyUtil.assemblyOrder(OrderDetail.orderTransOrderDetails(mealCommoditysBeans)));
                                if (orderBean.getMemberInfo() != null) {
                                    //设置会员信息
                                    doshokuOrder.setMemberInfo(orderBean.getMemberInfo());
                                    doshokuOrder.setMemberUpdateStatus(true + "-" + true);
                                } else {
                                    doshokuOrder.setMemberUpdateStatus(false + "-" + false);
                                }
                            } else {
                                doshokuOrder.setOrderPlaced(null);
                                doshokuOrder.getShoppingCart().setOrderCommodityList(new ArrayList<>());
                            }
                            doshokuOrder.setOpenTableInfo(openTableBean);

                            if (openTableBean.getScanId() != null) {
                                BaseOrder.orderType = FoodSummaryConstans.SKYORDER;
                            } else {
                                BaseOrder.orderType = FoodSummaryConstans.RESTAURANT_MODE;
                            }
                            mRootView.startMealStandActivity();
                        } else {
                            CommonTipDialog.showSurpisedDialog(IActivity, respose.getErrMsg(), null, null, null, null, null);
                        }
                    }
                });
    }

    /**
     * 設置已送單食品積分(訂單表沒有存儲食品積分字段)
     */
    private void setFoodPoints(List<OrderResponse.OrderDetailsBean> orderDetailsBeans) {
        List<Food> foods = mModel.queryDB_AllFoodList();
        for (int i = 0; i < orderDetailsBeans.size(); i++) {
            OrderResponse.OrderDetailsBean orderDetailsBean = orderDetailsBeans.get(i);
            if (orderDetailsBean.getType() != FOOD_TYPE) {
                continue;
            }
            for (int j = 0; j < foods.size(); j++) {
                Food food = foods.get(j);
                if (food.getId() == orderDetailsBean.getProductId()) {
                    orderDetailsBean.setPointsAdd(food.getPointsAdd());
                    orderDetailsBean.setPointsRedeem(food.getPointsRedeem());
                }
            }
        }
    }

    /**
     * 設置套餐，細項組別ID
     *
     * @param orderDetailsBeans
     */
    private void setTopId(List<OrderResponse.OrderDetailsBean> orderDetailsBeans) {
        long paroductId = 0;
        long topId = 0;
        for (int i = 0; i < orderDetailsBeans.size(); i++) {
            OrderResponse.OrderDetailsBean orderDetailsBean = orderDetailsBeans.get(i);
            if (orderDetailsBean.getType() == FOOD_TYPE) {
                int nextIndex = i + 1;
                if (orderDetailsBean.getParentId() == 0 || (orderDetailsBeans.size() > nextIndex && orderDetailsBeans.get(nextIndex).getType() == MODIFIER_TYPE)) {
                    paroductId = orderDetailsBean.getProductId();
                }
                topId = getComboIdByFid(paroductId);
            } else {
                topId = 0;
                List<Modifier> modifierList = mModel.queryDB_ModifierList(paroductId, ModifierDaoUtils.modifierMode_All);
                for (Modifier modifier : modifierList) {
                    if (modifier.getMid() == orderDetailsBean.getProductId()) {
                        topId = modifier.getTopId();
                        break;
                    }
                }
//                topId = CommonConfiguration.getInstance().getModifierTopIdMid((int) orderDetailsBean.getProductId());
            }
            if (orderDetailsBean.getParentId() != 0) {
                orderDetailsBean.setTopId(topId);
            }
        }
    }

    private long getComboIdByFid(long fid) {
        FoodComboDaoUtils daoUtils = new FoodComboDaoUtils(GsaCloudApplication.getAppContext());
        List<FoodCombo> foodCombos = daoUtils.queryCombosByQueryBuilder(fid);
        if (foodCombos != null && foodCombos.size() > 0) {
            return foodCombos.get(0).getComId();
        }
        return 0;
    }

    public void getTableToMove(TableBean.DataBean dataBean) {
        mModel.getTable(dataBean.getId(), dataBean.getTableNumber())
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseResult result) {
                        if (result.isSuccess()) {
                            TableBean.DataBean tableBean = JsonUtils.parseObject(result.getData(), TableBean.DataBean.class);
                            if (tableBean != null) {
                                if (!TextUtils.isEmpty(tableBean.getTableNumber())) {
                                    //如果是分檯拼接分檯名称
                                    tableBean.setTableName(tableBean.getTableName() + "-" + tableBean.getTableNumber());
                                }
                                if (originalTableId == 0) {
                                    if (tableBean.getUseStatus() == 1) {
                                        mRootView.showMessage("此檯使用中.");
                                        return;
                                    }
                                    if (tableBean.getStatus() == 0) {
                                        mRootView.showMessage("此檯未開檯.");
                                        return;
                                    }
                                    originalTableName = tableBean.getTableName();
                                    originalTableId = tableBean.getId();
                                    originalTableNumber = tableBean.getTableNumber();
                                    if (tableBean.getScanId() != null) {
                                        originalScanId = tableBean.getScanId().longValue();
                                    }
                                    mRootView.setTableActionContentText("由: " + originalTableName + " 轉到 ");
                                } else {
                                    if (tableBean.getUseStatus() == 1) {
                                        mRootView.showMessage("此檯使用中.");
                                        return;
                                    }
                                    targetTableName = tableBean.getTableName();
                                    targetTableId = tableBean.getId();
                                    targetTableNumber = tableBean.getTableNumber();
                                    if (tableBean.getStatus() == 1 || tableBean.getStatus() == 2 || tableBean.getStatus() == 3) {
                                        mRootView.setTableActionContentText("由: " + originalTableName + " 合併 " + targetTableName);
                                    } else {
                                        mRootView.setTableActionContentText("由: " + originalTableName + " 轉到 " + targetTableName);
                                    }
                                    showMoveActionDialog(tableBean);
                                }
                            }
                        } else {
                            mRootView.showMessage(result.getErrMsg());
                        }
                    }
                });
    }

    public void turnTable(long originalTableId, long targetTableId, String tableNumber, String targetTableNumber, long originalScanId, boolean isMergeTable) {

        RequestBody requestBody = new FormBody.Builder()
                .add("id", String.valueOf(originalTableId))
                .add("tableId", String.valueOf(targetTableId))
                .add("tableNumber", tableNumber)
                .add("targetTableNumber", targetTableNumber)
                .add("scanId", String.valueOf(originalScanId))
                .build();

        mModel.turnTable(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseOrderResponse respose) {
                        if (respose.isSuccess()) {
                            if (isMergeTable) {
                                mRootView.showMessage("合併成功");
                            } else {
                                mRootView.showMessage("轉檯成功");
                            }
                            mRootView.canceTableAction();
                            //立即獲取餐檯數據
                            getTables(false, null);
                        } else {
                            mRootView.showMessage(respose.getErrMsg());
                        }
                    }
                });
    }

    public void initTable(int tableId, String tableNumber, boolean showMessage) {

        RequestBody requestBody = new FormBody.Builder()
                .add("id", tableId + "")
                .add("tableNumber", tableNumber)
                .build();

        mModel.initTable(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> {
                    if (showMessage) {
                        mRootView.showLoading(null);
                    }
                })
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> {
                    if (showMessage) {
                        mRootView.hideLoading();
                    }
                })
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseOrderResponse respose) {

                        if (respose.isSuccess()) {

//                            if (showMessage)
//                                mRootView.showMessage("重置成功!");

                            mRootView.canceTableAction();

                            getTables(false, null);

                            refreshSplitTablesDialog();
                        } else {
                            if (showMessage) {
                                mRootView.showMessage(respose.getErrMsg());
                            }
                        }
                    }
                });
    }

    public void resetSkyorder(int tableId, String scanId) {

        RequestBody requestBody = new FormBody.Builder()
                .add("id", tableId + "")
                .add("scanId", scanId)
                .build();

        mModel.resetSkyorder(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> {
                    mRootView.showLoading(null);
                })
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> {
                    mRootView.hideLoading();
                })
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseResult respose) {

                        if (respose.isSuccess()) {

                            mRootView.canceTableAction();

                            getTables(false, null);
                        } else {
                            mRootView.showMessage(respose.getErrMsg());
                        }
                    }
                });
    }

    public void getSplitTables(int tableId) {
        mModel.getSplitTables(tableId)
                .subscribeOn(Schedulers.io())
//                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
//                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onSubscribe(Disposable d) {
                        super.onSubscribe(d);
                        mSplitTableDialog.clearItems();
                        mSplitTableDialog.setProgressVisibility(true);
                    }

                    @Override
                    public void onNext(@NonNull BaseResult info) {
                        if (info != null && info.isSuccess()) {
                            if (info.getData() != null) {

                                TableExtBean tableExtBean = JsonUtils.parseObject(info.getData(), TableExtBean.class);

                                List<TableBean.DataBean> dataBeanList = assemblyTableExts(tableExtBean.getRestaurantTable(), tableExtBean.getRestaurantTableExtList());

                                mSplitTableDialog.addItems(dataBeanList);
                                mSplitTableDialog.notifyDataSetChanged();
                            } else {
                                mSplitTableDialog.showEmptyView(true, 0, null);
                            }
                        } else {
                            mSplitTableDialog.showEmptyView(false, 0, null);
                        }
                        mSplitTableDialog.setProgressVisibility(false);
                    }

                    @Override
                    public void onError(Throwable t) {
                        super.onError(t);
                        mSplitTableDialog.setProgressVisibility(false);
                        mSplitTableDialog.showEmptyView(false, 0, t);
                    }

                    private List<TableBean.DataBean> assemblyTableExts(TableBean.DataBean mainTable, List<TableExtBean.DataBean> restaurantTableExtList) {
                        List<TableBean.DataBean> dataBeans = new ArrayList<>();
                        //添加主檯
                        dataBeans.add(mainTable);
                        //添加分檯
                        for (TableExtBean.DataBean dataBean : restaurantTableExtList) {
                            dataBeans.add(TableBean.splitTableTransformTable2(mainTable, dataBean));
                        }
                        return dataBeans;
                    }
                });
    }

    public void splitTable(TableBean.DataBean tableBean) {
        mModel.splitTable(tableBean.getId())
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseResult result) {
                        if (result.isSuccess()) {
                            if (result.getData() != null) {
                                TableExtBean.DataBean tableExtBean = JsonUtils.parseObject(result.getData(), TableExtBean.DataBean.class);
                                long tableExtId = tableExtBean.getId();
                                //分檯开檯
                                openTable(tableExtId, TableBean.splitTableTransformTable(tableBean, tableExtBean));
                            }
                        } else {
                            mRootView.showMessage(result.getErrMsg());
                        }
                    }
                });
    }

    /**
     * 刷新分檯数据
     */
    private void refreshSplitTablesDialog() {
        if (mSplitTableDialog != null) {
            //刷新餐檯
            getSplitTables(mSplitTableDialog.getMainTableId());
        }
    }

    public void getFoodSummarys(OnNetworkCallbackListener networkCallBackListener) {
        int restaurantId = RestaurantInfoManager.newInstance().getRestaurantId();
        byte businessType = FoodSummary.BUSINESS_TYPE_SKYORDER;
        mModel.getFoodSummarys(restaurantId, false, businessType)
                .subscribeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseResult result) {
                        if (networkCallBackListener != null) {
                            networkCallBackListener.onResult(result);
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (networkCallBackListener != null) {
                            networkCallBackListener.onError(t);
                        }
                    }
                });
    }


    public void addScan(String shopId, int tableId, String tableNum, String tableName, int person, String createBy, String endTime, int summaryId, OnNetworkCallbackListener networkCallBackListener) {

        RequestBody requestBody = new FormBody.Builder()
                .add("shopId", shopId)
                .add("tableId", String.valueOf(tableId))
                .add("tableNum", tableNum)
                .add("tableName", tableName)
                .add("person", String.valueOf(person))
                .add("createBy", createBy)
                .add("endTime", endTime)
                .add("summaryId", String.valueOf(summaryId))
                .build();

        mModel.addScan(requestBody)
                .subscribeOn(Schedulers.io())
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseResult result) {
                        if (networkCallBackListener != null) {
                            networkCallBackListener.onResult(result);
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        if (networkCallBackListener != null) {
                            networkCallBackListener.onError(t);
                        }
                    }
                });
    }

    /**
     * 根据操作类型过滤一遍餐台
     */
    public void filterTableByAction() {
        if (mTableList.size() == 0) {
            return;
        }
        List<TableBean.DataBean> filterTableBeanList = new ArrayList<>();
        if (mTableAction != null) {
            for (int i = 0; i < mTableList.size(); i++) {
                TableBean.DataBean dataBean = mTableList.get(i);
                if (mTableAction.filterTableCondition(dataBean)) {
                    filterTableBeanList.add(dataBean);
                }
            }
        } else {
            //正常餐檯模式下顯示所有餐檯數據
            filterTableBeanList.addAll(mTableList);
        }
        IActivity.nofilyFragmentUpdateTableData(filterTableBeanList);
    }

    public void showMoveActionDialog(TableBean.DataBean dataBean) {
        QMUIDialog.MessageDialogBuilder dialogBuilder = new QMUIDialog.MessageDialogBuilder(IActivity);
        dialogBuilder.setTitleIcon(R.drawable.qmui_icon_dialog_doubt);
        //是否合併檯
        boolean isMergeTable = false;
        String message;
        if (dataBean.getStatus() == 1 || dataBean.getStatus() == 2 || dataBean.getStatus() == 3) {
            message = "是否由%s號檯合併到%s號檯";
            isMergeTable = true;
        } else {
            message = "是否由%s號檯轉到%s號檯";
        }
        dialogBuilder.setMessage(String.format(message, originalTableName, targetTableName));
        boolean finalIsMergeTable = isMergeTable;
        dialogBuilder.addAction(0, "確認", QMUIDialogAction.ACTION_PROP_NEGATIVE, new QMUIDialogAction.ActionListener() {
            @Override
            public void onClick(QMUIDialog dialog, int index) {
                dialog.dismiss();
                turnTable(originalTableId, targetTableId, originalTableNumber, targetTableNumber, originalScanId, finalIsMergeTable);
            }
        });
        dialogBuilder.addAction("取消", new QMUIDialogAction.ActionListener() {
            @Override
            public void onClick(QMUIDialog dialog, int index) {
                dialog.dismiss();
                mTableAction.cancel();
            }
        });
        dialogBuilder.create(R.style.MyDialogTheme2).show();
    }

    public void showSplitTableDialog(int tableId) {
        if (mSplitTableDialog == null) {
            mSplitTableDialog = new SplitTableDialog(IActivity);
            mSplitTableDialog.setOnClickListener(new SplitTableDialog.OnClickListener() {
                @Override
                public void onItemClick(SplitTableDialog dialog, TableBean.DataBean dataBean, int position) {
                    if (mTableAction != null) {
                        if (mTableAction instanceof MoveTableAction) {
                            getTableToMove(dataBean);
                        } else {
                            mTableAction.action(dataBean);
                        }
                    } else {
                        //開台操作
                        openTable(dataBean.getId(), dataBean);
                    }
                    mSplitTableDialog.closeDialog();
                }
            });
            mSplitTableDialog.setOnRetryListener(new BaseRetryDialog.OnRetryListener() {
                @Override
                public void onRetryClick() {
                    getSplitTables(tableId);
                }
            });
        }
        mSplitTableDialog.setMainTableId(tableId);
        mSplitTableDialog.build().show();
        getSplitTables(tableId);
    }

    /**
     * 執行餐檯操作
     */
    public boolean doTableAction(TableBean.DataBean dataBean) {
        if (mTableAction != null) {
            mTableAction.setActionListener(new TableAction.OnActionListener() {

                @Override
                public void setOperatContentText(String content) {
                    mRootView.setTableActionContentText(content);
                }

                @Override
                public void resetTable(TableBean.DataBean tableBean) {
                    LoganManager.w_tableMode(TAG, mTableAction.getActionTitle() + " tableName=" + tableBean.getTableName());
                    initTable(tableBean.getId(), tableBean.getTableNumber(), true);
                }

                @Override
                public void resetSkyTable(TableBean.DataBean tableBean) {
                    LoganManager.w_tableMode(TAG, mTableAction.getActionTitle() + " tableName=" + tableBean.getTableName());
                    if (tableBean.getScanId() == null) {
                        mRootView.showMessage(tableBean.getTableName() + "不是skyorder檯");
                        return;
                    }
                    resetSkyorder(tableBean.getId(), String.valueOf(tableBean.getScanId()));
                }

                @Override
                public void moveTable(TableBean.DataBean tableBean) {
                    LoganManager.w_tableMode(TAG, mTableAction.getActionTitle() + " tableName=" + tableBean.getTableName());
//                    if (dataBean.getId() == tableBean.getId()) {
//                        CommonTipDialog.showSurpisedDialog(IActivity, "相同檯不能轉移", null, null, null, null, null);
//                        return;
//                    }
                    getTableToMove(tableBean);
                }


                @Override
                public void splitTableAction(TableBean.DataBean tableBean) {
                    LoganManager.w_tableMode(TAG, mTableAction.getActionTitle() + " tableName=" + tableBean.getTableName());
                    splitTable(tableBean);
                }

                @Override
                public void printSkyorderSuccess() {
                    initTableActionParameter();
                    mRootView.canceTableAction();
                    IActivity.initSkyorderModeState();
                }

                @Override
                public void showSplitTableDialogAction() {
                    showSplitTableDialog(dataBean.getId());
                }

                @Override
                public void cancel() {
                    initTableActionParameter();
                    mRootView.canceTableAction();
                }
            });
            mTableAction.action(dataBean);
            return true;
        }
        return false;
    }

    /**
     * 初始化操作參數
     */
    public void initTableActionParameter() {
        originalTableName = "";
        originalTableId = 0;
        originalTableNumber = "";
        originalScanId = 0;
        targetTableName = "";
        targetTableId = 0;
        targetTableNumber = "";
        mTableAction = null;
    }

    /**
     * 跟進id獲取餐檯對象
     *
     * @param id
     * @return
     */
    private TableBean.DataBean getTableById(long id) {
        for (int i = 0; i < mTableList.size(); i++) {
            TableBean.DataBean dataBean = mTableList.get(i);
            if (dataBean.getId() == id) {
                return dataBean;
            }
        }
        return null;
    }

    /**
     * 根據類獲取餐檯操作對象
     *
     * @param cla 具體類型
     * @return
     */
    public TableAction getTableActionByClass(Class<?> cla) {
        for (TableAction action : mTableActions) {
            if (action.getClass().equals(cla)) {
                return action;
            }
        }
        return null;
    }

    /**
     * 開啟skyorder模式
     */
    public void openSkyorderMode() {
        PrintSkyorderAction skyOrderAction = (PrintSkyorderAction) getTableActionByClass(PrintSkyorderAction.class);
        if (skyOrderAction != null) {
            setTableAction(skyOrderAction);
        }
    }

    public boolean setSkyorderMode() {
        boolean state = (boolean) SPUtils.get(SkyOrderConstant.skyorder_mode, false);
        SPUtils.put(SkyOrderConstant.skyorder_mode, !state);
        return !state;
    }

    public boolean isSkyorderMode() {
        return (boolean) SPUtils.get(SkyOrderConstant.skyorder_mode, false);
    }

    public void startTablePolling() {
        if (mTablesPollingDisposable == null) {
            LoganManager.w_tableMode(TAG, "start.....tables polling");
            mTablesPollingDisposable = RxJavaUtils.polling(GoldConstants.refreshTime)
                    .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            if (TableActivity.isRefreshData) {
                                getTables(false, null);
                            }
                        }
                    });
        }
    }

    public void stopTablePolling() {
        if (mTablesPollingDisposable != null && !mTablesPollingDisposable.isDisposed()) {
            mTablesPollingDisposable.dispose();
            mTablesPollingDisposable = null;
        }
    }

    public void setTableAction(TableAction tableAction) {
        this.mTableAction = tableAction;
    }

    public Disposable getGetTablesDataDisposable() {
        return mGetTablesDataDisposable;
    }

    public List<TableBean.DataBean> getTableList() {
        return mTableList;
    }
}
