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

import android.app.Application;
import android.graphics.Color;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;

import com.billy.cc.core.component.CC;
import com.gingersoft.gsa.cloud.common.bean.BaseResult;
import com.gingersoft.gsa.cloud.common.constans.ExpandConstant;
import com.gingersoft.gsa.cloud.common.constans.FoodSummaryConstans;
import com.gingersoft.gsa.cloud.common.constans.GoldConstants;
import com.gingersoft.gsa.cloud.common.constans.PrintConstans;
import com.gingersoft.gsa.cloud.common.rxjava.ErrorHandleSingleSubscriber;
import com.gingersoft.gsa.cloud.order.bean.discount.MemberWalletCoupon;
import com.gingersoft.gsa.cloud.common.core.member.MemberInfo;
import com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager;
import com.gingersoft.gsa.cloud.common.core.restaurant.utils.RestaurantExpandInfoUtils;
import com.gingersoft.gsa.cloud.common.core.table.TableBean;
import com.gingersoft.gsa.cloud.common.core.table.TableExtBean;
import com.gingersoft.gsa.cloud.common.logan.LoganManager;
import com.gingersoft.gsa.cloud.common.utils.JsonUtils;
import com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils;
import com.gingersoft.gsa.cloud.component.ComponentName;
import com.gingersoft.gsa.cloud.database.bean.Discount;
import com.gingersoft.gsa.cloud.database.bean.Function;
import com.gingersoft.gsa.cloud.order.bean.discount.CouponDiscountBean;
import com.gingersoft.gsa.cloud.order.bean.response.CouponDiscountResponse;
import com.gingersoft.gsa.cloud.order.bean.response.OrderResponse;
import com.gingersoft.gsa.cloud.order.billItem.BillItem;
import com.gingersoft.gsa.cloud.order.billItem.DiscountItem;
import com.gingersoft.gsa.cloud.order.commodity.OrderDetail;
import com.gingersoft.gsa.cloud.order.discount.MemberCouponDiscount;
import com.gingersoft.gsa.cloud.order.discount.MemberWalletCouponDiscount;
import com.gingersoft.gsa.cloud.order.discount.MultyDiscount;
import com.gingersoft.gsa.cloud.order.discount.NomalDiscount;
import com.gingersoft.gsa.cloud.order.order.BaseOrder;
import com.gingersoft.gsa.cloud.order.order.MealOrder;
import com.gingersoft.gsa.cloud.print.PrinterUtils;
import com.gingersoft.gsa.cloud.print.bean.PrintContent;
import com.gingersoft.gsa.cloud.print.bean.adapter.PrintContentAdapter;
import com.gingersoft.gsa.cloud.table.R;
import com.gingersoft.gsa.cloud.table.mvp.action.discount.BillCouponAction;
import com.gingersoft.gsa.cloud.table.mvp.contract.MealBillContract;
import com.gingersoft.gsa.cloud.table.mvp.model.bean.request.AddOrderRequest;
import com.gingersoft.gsa.cloud.table.mvp.model.bean.request.CreateOrderRequest;
import com.gingersoft.gsa.cloud.table.mvp.model.bean.response.BaseOrderResponse;
import com.gingersoft.gsa.cloud.table.mvp.action.discount.BillDiscountAction;
import com.gingersoft.gsa.cloud.table.mvp.model.utils.OrderAssemblyUtil;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.meal.MealBillActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.meal.MealPayActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.meal.MealStandActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.table.TableActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.adapter.BillItemAdapter;
import com.gingersoft.gsa.cloud.table.mvp.ui.adapter.MealBillFunctionAdapter;
import com.gingersoft.gsa.cloud.table.mvp.ui.adapter.meal.MealCartAdapter;
import com.gingersoft.gsa.cloud.table.mvp.ui.fragment.discount.CouponFragment;
import com.gingersoft.gsa.cloud.table.mvp.ui.fragment.discount.DiscountDialogFragment;
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.jess.arms.di.scope.ActivityScope;
import com.jess.arms.http.imageloader.ImageLoader;
import com.jess.arms.integration.AppManager;
import com.jess.arms.utils.ArmsUtils;
import com.jess.arms.utils.RxLifecycleUtils;
import com.scwang.smartrefresh.layout.api.RefreshLayout;
import com.xuexiang.rxutil2.rxjava.RxJavaUtils;

import org.simple.eventbus.EventBus;

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

import javax.inject.Inject;

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


/**
 * ================================================
 * Description:
 * <p>
 * Created by MVPArmsTemplate on 01/09/2020 19:23
 * <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 MealBillPresenter extends BaseMealPresenter<MealBillContract.Model, MealBillContract.View> {
    @Inject
    RxErrorHandler mErrorHandler;
    @Inject
    Application mApplication;
    @Inject
    ImageLoader mImageLoader;
    @Inject
    AppManager mAppManager;

    private MealBillActivity IActivity;

    private MealBillFunctionAdapter mOrderTopFunctionAdapter;
    private List<Function> mFunctionList = new ArrayList<>();

    /**
     * 分檯弹窗
     */
    private SplitTableDialog mSplitTableDialog;
    /**
     * 整單折扣
     */
    private BillDiscountAction mNomalDiscountAction;
    /**
     * 整單優惠券
     */
    private BillCouponAction mBillCouponAction;

    private Disposable mGetTablesDataDisposable;
    private Disposable mTablesPollingDisposable;

    @Inject
    public MealBillPresenter(MealBillContract.Model model, MealBillContract.View rootView) {
        super(model, rootView);
        this.IActivity = (MealBillActivity) rootView;
        if (mMealOrder != null && !mMealOrder.isModifyOrder()) {
            //转移食品可多选
            mMealCartAdapter.setSelectedMode(MealCartAdapter.MULTIPLE_SELECTED);
        }
        initAction();
    }

    private void initAction() {
        mNomalDiscountAction = BillDiscountAction.builder()
                .cashStr(cashStr)
                .context(IActivity)
                .listener(new BillDiscountAction.OnCallBackListener() {

                    @Override
                    public void exclusiveRemoveOthers(List<NomalDiscount> nomalDiscountList) {
                        mShoppingCart.delAllNomalDiscountList(nomalDiscountList);
                    }

                    @Override
                    public void preformAddDiscount(Discount discount) {
                        addOrderDiscount(discount);
                    }
                })
                .build();
        mBillCouponAction = BillCouponAction.builder()
                .context(IActivity)
                .cashStr(cashStr)
                .listener((coupon) -> {
                    addOrderCoupon(coupon);
                    updateCouponSelects(false);
                })
                .build();
    }

    private void addOrderCoupon(MemberWalletCoupon coupon) {
        mShoppingCart.addMultyDiscount(mShoppingCart.createMemberWalletCoupon(coupon, BillItem.BILL_ITEM_NO_ORDER_STATUS));
        MealOrder.getInstance().setBillItemStatus(MealOrder.DISCOUNT_ITEM_TAG);
        updateBillInfo();
    }

    private void addOrderDiscount(Discount discount) {
        mShoppingCart.addMultyDiscount(mShoppingCart.createNomalDiscount(discount, BillItem.BILL_ITEM_NO_ORDER_STATUS));
        MealOrder.getInstance().setBillItemStatus(MealOrder.DISCOUNT_ITEM_TAG);
        updateBillInfo();
    }

    private void updateCouponSelects(boolean sticky) {
        if (sticky) {
            EventBus.getDefault().postSticky(getSelectWalletCouponMapNoByBill(), CouponFragment.UPDATE_COUPON_CHECKED_STATE);
        } else {
            EventBus.getDefault().post(getSelectWalletCouponMapNoByBill(), CouponFragment.UPDATE_COUPON_CHECKED_STATE);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.mAppManager = null;
        this.mImageLoader = null;
        this.mApplication = null;
        if (mNomalDiscountAction != null) {
            mNomalDiscountAction.destroy();
        }
        stopTablePolling();
    }

    public void initAdapter() {
        if (mOrderTopFunctionAdapter == null) {
            mOrderTopFunctionAdapter = new MealBillFunctionAdapter(IActivity, mFunctionList);
            mRootView.setTopFunctionAdapter(mOrderTopFunctionAdapter);
        }
        if (mBillItemAdapter != null) {
            mRootView.setBillDetailAdapter(mBillItemAdapter);
        }
        mRootView.setMealCartAdapter(mMealCartAdapter);

        setPrinterMachineName();
    }

    public void initItemListener() {
        mOrderTopFunctionAdapter.setOnClickListener(new MealBillFunctionAdapter.OnClickListener() {
            @Override
            public void onItemClick(View v, Function function) {

                LoganManager.w_tableMode(TAG, LoganManager.EVENT_CLICK, function.getResName());

                switch (function.getResName()) {
                    case "送單":
                        sendOrder(false, null);
                        break;
                    case "印單":
                        if (!canPrint()) {
                            return;
                        }
                        if (BaseOrder.isCurrentOrderType(FoodSummaryConstans.TAKEAWAY_TYPE)) {
                            //TODO 外賣新訂單印單
                            printOrder(MealOrder.getInstance().getOpenTableInfo().getId(), false);
                            return;
                        }
                        if (hasNesOrderFoods() || getNewDiscount() != null) {
                            //有未送單食品先送單
                            sendOrder(true, null);
                        } else {
                            printOrder(MealOrder.getInstance().getOpenTableInfo().getId(), false);
                        }
                        break;
                    case "結賬":
//                        if (!canPay()) {
//                            return;
//                        }
                        if (hasNesOrderFoods() || getNewDiscount() != null || hasModifyFoods() || mMealOrder.isBillHasChanged()) {
                            Class[] parameterTypes = {boolean.class, Class.class};
                            Object[] parameters = {false, MealPayActivity.class};
                            CommonTipDialog.showDoubtDialog(IActivity, "賬單已變化，是否送單后去結賬", BaseMealPresenter.class, mBaseOrderPresenter,
                                    "sendOrder", parameterTypes, parameters);
                            //有未送單食品先送單
//                            sendOrder(false, OrderPayActivity.class);
                        } else {
                            mRootView.startActivityForResult(MealBillActivity.BILL_CODE, MealPayActivity.class, null);
                        }
                        break;
                    case "轉移":
                        if (!canTransfer()) {
                            return;
                        }
                        mRootView.showTransferFoodLayout();
                        break;
                    case "折扣":
                        if (!canDiscount()) {
                            return;
                        }
                        showDiscountDialog();
                        break;
                    case "送單信息":
                        CC.obtainBuilder(ComponentName.COMPONENT_DELIVERYPICK)
                                .setActionName("SendOrder")
                                .build()
                                .call();
                        break;
                }
            }

            @Override
            public boolean onItemLongClick(View v, Function datasBean) {
                LoganManager.w_tableMode(TAG, LoganManager.EVENT_LONG_CLICK, datasBean.getResName());
                if (datasBean.getResName().equals("印單") || datasBean.getResName().equals("送單")) {
                    PrinterUtils.switchPrintMethod(IActivity, datasBean, mOrderTopFunctionAdapter);
                }
                return false;
            }
        });
        mBillItemAdapter.setOnItemClickListener(new BillItemAdapter.OnItemClickListener() {

            @Override
            public void onItemClick(BillItem datasBean, int position) {

            }

            @Override
            public void onItemDeleteClick(BillItem datasBean, int position) {
                addDeleteDiscountIdByType(datasBean);
                removeBillItemByPosition(position);
            }
        });
    }

    /**
     * 跟进折扣类型将Id加入到删除列表,注：会员折扣不可删除
     *
     * @param item
     */
    private void addDeleteDiscountIdByType(BillItem item) {
        if (item instanceof DiscountItem) {
            if (item.getType() == BillItem.NOMAL_DISCOUNT_TYPE) {
                NomalDiscount nomalDiscount = (NomalDiscount) ((DiscountItem) item).getDiscount();
                mMealOrder.addDeleteDiscountId(nomalDiscount.getDiscount().getDiscountRecordId());
            } else if (item.getType() == BillItem.COUPON_DISCOUNT_TYPE) {
                final MultyDiscount multyDiscount = ((DiscountItem) item).getDiscount();
                if (multyDiscount instanceof MemberCouponDiscount) {
                    MemberCouponDiscount couponDiscount = (MemberCouponDiscount) multyDiscount;
                    mMealOrder.addDeleteDiscountId(couponDiscount.getCouponId());
                } else if (multyDiscount instanceof MemberWalletCouponDiscount) {
                    MemberWalletCouponDiscount walletCouponDiscount = (MemberWalletCouponDiscount) multyDiscount;
                    mMealOrder.addDeleteDiscountId(walletCouponDiscount.getCouponId());
                }
            }
        }
    }

    public void initTopFunctionData() {
        if (mFunctionList.size() > 0) {
            mFunctionList.clear();
        }
        if (BaseOrder.isTableToMeal()) {
            if (mMealOrder.isModifyOrder()) {
                //修改訂單隱藏送單，印單功能
                mFunctionList.add(new Function("結賬", Color.parseColor("#FFFFFF"), Color.parseColor("#DC0000"), 24));
                mFunctionList.add(new Function("折扣", Color.parseColor("#FFFFFF"), Color.parseColor("#008577"), 24));
            } else {
//                List<Function> functions = FunctionManager.getDefault().getFunctionByResModule(GsaCloudApplication.getAppContext(), ComponentTable.table.class, ComponentTable.table.order, "order");
//                for (int i = 0; i < functions.size(); i++) {
//                    if (functions.get(i).getParentId() == 0) {
//                        functions.remove(i);
//                    }
//                }
//                if (functions.size() > 0) {
//                    mFunctionList.addAll(functions);
//                } else {
                mFunctionList.add(new Function("送單", Color.parseColor("#FFFFFF"), Color.parseColor("#008131"), 24));
                mFunctionList.add(new Function("印單", Color.parseColor("#FFFFFF"), Color.parseColor("#FF8E04"), 24));
                mFunctionList.add(new Function("結賬", Color.parseColor("#FFFFFF"), Color.parseColor("#DC0000"), 24));
                mFunctionList.add(new Function("轉移", Color.parseColor("#FFFFFF"), Color.parseColor("#FF4B9DFA"), 24));
                mFunctionList.add(new Function("折扣", Color.parseColor("#FFFFFF"), Color.parseColor("#008577"), 24));
//                }
            }
        } else if (BaseOrder.isCurrentOrderType(FoodSummaryConstans.TAKEAWAY_TYPE)) {
            mFunctionList.add(new Function("折扣", Color.parseColor("#FFFFFF"), Color.parseColor("#008577"), 24));
            mFunctionList.add(new Function("印單", Color.parseColor("#FFFFFF"), Color.parseColor("#FF8E04"), 24));
            mFunctionList.add(new Function("送單信息", Color.parseColor("#FFFFFF"), Color.parseColor("#008131"), 24));
        }
    }

    public void setPrinterMachineName() {
        if (!TextUtils.isEmpty(PrinterUtils.printMachineCode)) {
            for (int i = 0; i < mFunctionList.size(); i++) {
                Function function = mFunctionList.get(i);
                if (function.getResName().equals("印單")) {
                    function.setLable(PrinterUtils.printMachineCode);
                    mOrderTopFunctionAdapter.notifyItemChanged(i);
                    break;
                }
            }
        }
    }

    @Override
    public void createOrder(boolean isPrint, Class<?> afterToActivity) {
        CreateOrderRequest request = getCreateOrderRequest(getOrderFoodLists());
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), GsonUtils.GsonString(request));
        String json = GsonUtils.GsonString(request);
        mModel.createOrder(requestBody)
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseOrderResponse info) {
                        sendOrderRespose(info, isPrint, afterToActivity);
                    }
                });
    }

    @Override
    public void addOrderFood(boolean isPrint, Class<?> afterToActivity) {
        List<OrderDetail> foodLists = getOrderFoodLists();
        for (OrderDetail food : foodLists) {
            food.setOrderId(mMealOrder.getOrderId());
        }
        AddOrderRequest addOrderRequest = getAddOrderRequest(foodLists);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), GsonUtils.GsonString(addOrderRequest));
        String json = GsonUtils.GsonString(addOrderRequest);
        mModel.addOrderFood(requestBody)
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseOrderResponse info) {
                        sendOrderRespose(info, isPrint, afterToActivity);
                    }
                });
    }

    private void sendOrderRespose(BaseOrderResponse info, boolean isPrint, Class<?> afterToActivity) {
        if (info == null) {
            if (isPrint) {
                printOrder(mTableInfo.getId(), true);
            } else {
                if (!hasNesOrderFoods()) {
                    //未新增食品點擊送單 後台不讓過直接提示即可，不調用打印
                    mRootView.showMessage("送單成功");
                } else {
                    mRootView.showMessage(info.getErrMsg());
                }
            }
        } else {
            if (isPrint) {
                printOrder(mTableInfo.getId(), true);
            } else {
                mRootView.showMessage("送單成功");
                //刷新食品列表
                if (afterToActivity != null) {
                    updateOrderDetails(info);
                }
                printSendOrder(afterToActivity);
            }
        }

    }

    /**
     * 送單打印上菜纸
     */
    private void printSendOrder(Class<?> afterToActivity) {
        if (afterToActivity != null) {
            mRootView.startActivityForResult(MealBillActivity.BILL_CODE, afterToActivity, null);
        }
        if (RestaurantExpandInfoUtils.getValue(ExpandConstant.AutoPrinterPaper, true)) {
            if (RestaurantExpandInfoUtils.getValue(ExpandConstant.MergeSendFood, true)) {
                //合并主食品
                mergeMainFoodNumber(mOrderMealList);
            }
            //賬單內容送單
            if (MealOrder.getInstance().getNewFoodList() == null || MealOrder.getInstance().getNewFoodList().size() <= 0) {
                //沒有新的食品時，不打印送單
                if (afterToActivity == null) {
                    mRootView.sendSuccess();
                    mAppManager.killActivity(MealStandActivity.class);
                }
                return;
            }
            //賬單內容送單
            PrintContent printContent = new PrintContentAdapter().adaptationSendOrderPaperContent(MealOrder.getInstance(), mTableInfo);

            CC.obtainBuilder(ComponentName.COMPONENT_PRINT)
                    .setActionName("printActivity")
                    .addParam(PrintConstans.PRINT_TYPE, PrintConstans.PRINT_SERVE)
                    .addParam(PrintConstans.PRINT_CONTENT, printContent)
                    .addParam(PrintConstans.PRINT_ORDER_NO, MealOrder.getInstance().getOrderNo())
                    .build()
                    .callAsyncCallbackOnMainThread((cc, result) -> {
                        if (result.isSuccess()) {
                        } else {
                            mRootView.showMessage("打印失敗");
                        }
                        if (afterToActivity == null) {
                            mRootView.sendSuccess();
                            mAppManager.killActivity(MealStandActivity.class);
                        }
                    });
        } else {
            if (afterToActivity == null) {
                mRootView.sendSuccess();
                mAppManager.killActivity(MealStandActivity.class);
            }
        }
    }

    public void printOrder(long tableId, boolean isSend) {
        RequestBody requestBody = new FormBody.Builder()
                .add("tableId", tableId + "")
                .add("tableNumber", mTableInfo.getTableNumber())
                .build();
        mModel.printOrder(requestBody)
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseOrderResponse info) {
                        if (info != null && info.isSuccess()) {
                            if (RestaurantExpandInfoUtils.getValue(ExpandConstant.MergeSendFood, true)) {
                                //合并主食品
                                mergeMainFoodNumber(mOrderMealList);
                            }

                            PrintContent printContent = new PrintContentAdapter().adaptationPrintSlipContent(MealOrder.getInstance(), mTableInfo);

                            CC.obtainBuilder(ComponentName.COMPONENT_PRINT)
                                    .addParam(PrintConstans.PRINT_TYPE, PrintConstans.PRINT_SLIP)//印單
                                    .addParam(PrintConstans.PRINT_CONTENT, printContent)
                                    .addParam(PrintConstans.PRINT_ORDER_NO, MealOrder.getInstance().getOrderNo())
                                    .setActionName("printActivity")
                                    .build()
                                    .callAsyncCallbackOnMainThread((cc, result) -> {
                                        Log.e("error", "是否成功打印：" + result.isSuccess());
                                        if (result.isSuccess()) {
                                            //打印成功
                                            mRootView.showMessage("打印成功!");
                                        } else {
                                            mRootView.showMessage("打印失敗!");
                                        }
                                        //不管打印是否成功，都需要退出當前頁面
                                        mRootView.printSuccess();
                                    });
                            //打印
                        } else {
                            mRootView.showMessage("印單失敗!");
                            if (isSend) {
                                //印單失敗但提交新食品成功,更新一遍訂單數據
                                loadOrder(mMealOrder.getOrderId());
                            }
                        }
                    }
                });
    }

    public void queryCoupon(Long memberId, long couponMemberId, String couponNo, int restaurantId) {
        if (mMealOrder == null) {
            return;
        }
        int tableId = mMealOrder.getOpenTableInfo().getId();
        mModel.queryCoupon(tableId, memberId, couponMemberId, couponNo, restaurantId)
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseResult info) {
                        if (info != null && info.isSuccess()) {
                            if (info.getData() != null) {
                                CouponDiscountResponse couponResult = JsonUtils.parseObject(info.getData(), CouponDiscountResponse.class);
                                if (couponResult != null) {
                                    boolean updateBillItem = false;
                                    MemberInfo memberInfo = couponResult.getMemberInfo();
                                    if (memberInfo != null) {
                                        updateBillItem = true;
                                        mMealOrder.setMemberInfo(memberInfo);
                                        mShoppingCart.addMultyDiscount(mShoppingCart.createMemberDiscount(memberInfo, BillItem.BILL_ITEM_NO_ORDER_STATUS));
                                    }
                                    CouponDiscountBean couponBean = couponResult.getCouponBean();
                                    if (couponBean != null) {
                                        if (!addMemberCouponConditionFilter(couponBean)) {
                                            return;
                                        }
                                        updateBillItem = true;
                                        mShoppingCart.addMultyDiscount(mShoppingCart.createCouponDiscount(couponBean, BillItem.BILL_ITEM_NO_ORDER_STATUS));
                                    }
                                    if (updateBillItem) {
                                        updateBillInfo();
                                    }
                                }
                            } else {
                                mRootView.showMessage(info.getErrMsg());
                            }
                        } else {
                            if (info.getErrCode().equals(CouponDiscountResponse.ERROR_CODE_0001)) {
                                mRootView.showMessage("會員已在其他餐廳使用");
                            } else if (info.getErrCode().equals(CouponDiscountResponse.ERROR_CODE_0002)) {
                                mRootView.showMessage("請掃描當前品牌的優惠券碼");
                            } else if (info.getErrCode().equals(CouponDiscountResponse.ERROR_CODE_0003)) {
                                mRootView.showMessage("請掃描當前會員的優惠券碼");
                            } else {
                                mRootView.showMessage(info.getErrMsg());
                            }
                        }
                    }
                });
    }

    public void loadOrder(long orderId) {
        mModel.loadOrder(orderId)
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseOrderResponse info) {
                        updateOrderDetails(info);
                    }
                });
    }

    public void getTables(boolean show, RefreshLayout refreshLayout) {
        int restaurantId = RestaurantInfoManager.newInstance().getRestaurantId();
        mModel.getTables(restaurantId)
                .doOnSubscribe(disposable -> {
                    if (show && refreshLayout == null) {
                        mRootView.showLoading(null);
                    }
                })
                .doAfterTerminate(() -> 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 (!IActivity.isRefreshData()) {
                            return;
                        }
                        if (tableBean.isSuccess()) {
                            List<TableBean.DataBean> tableBeanData = tableBean.getData();
                            if (tableBeanData != null && tableBeanData.size() > 0) {
                                sortTableList(tableBeanData);
                                mRootView.returnTableList(tableBeanData);
                            } else {
                                mRootView.getCurrentTableFragment().showLoadSirCall(true, 0, null);
                            }
                        } else {
                            if (show) {
                                mRootView.getCurrentTableFragment().showMessage(tableBean.getErrMsg());
                            }
                            mRootView.getCurrentTableFragment().showLoadSirCall(false, 0, null);
                        }
                        resetRefreshLayout();
                    }

                    @Override
                    public void onError(Throwable t) {
                        super.onError(t);
                        mRootView.getCurrentTableFragment().showLoadSirCall(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 getTable(TableBean.DataBean dataBean) {
        mModel.getTable(dataBean.getId(), dataBean.getTableNumber())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseResult result) {
                        if (result.isSuccess()) {
                            TableBean.DataBean tableBean = JsonUtils.parseObject(result.getData(), TableBean.DataBean.class);
                            if (tableBean != null) {
                                if (tableBean.getUseStatus() == 0) {
                                    String msg = "轉移到" + tableBean.getTableName() + "號檯?";
                                    Class[] parameterTypes = {TableBean.DataBean.class};
                                    Object[] parameters = {tableBean};
                                    CommonTipDialog.showDoubtDialog(IActivity, msg, MealBillPresenter.class, MealBillPresenter.this,
                                            "transferFood", parameterTypes, parameters);
                                } else {
                                    mRootView.showMessage(tableBean.getTableName() + "號檯操作中");
                                }
                                mRootView.setTransferTableName(tableBean.getTableName());
                            }
                        } else {
                            mRootView.showMessage(result.getErrMsg());
                        }
                    }
                });
    }

    private void transferFood(TableBean.DataBean dataBean) {

        String ids = getSelectedOldFoodIds();
        if (TextUtils.isEmpty(ids)) {
            return;
        }

        RequestBody requestBody = new FormBody.Builder()
                .add("tableId", String.valueOf(mTableInfo.getId()))
                .add("targetId", String.valueOf(dataBean.getId()))
                .add("tableNumber", mTableInfo.getTableNumber())
                .add("targetTableNumber", dataBean.getTableNumber())
                .add("orderId", String.valueOf(mMealOrder.getOrderId()))
                .add("orderDetailsIds", ids)
                .build();

        mModel.transferFood(requestBody)
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .doAfterTerminate(() -> mRootView.hideLoading())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseOrderResponse>(mErrorHandler) {

                    @Override
                    public void onSuccess(@NonNull BaseOrderResponse info) {

                        if (info == null) {
                            mRootView.showMessage("轉移失敗");
                            return;
                        }

                        if (info.isSuccess()) {

                            mRootView.showMessage("轉移成功");

                            updateOrderDetails(info);
                            updateBillInfo();
                            IActivity.backPressed();
                        } else {
                            mRootView.showMessage(info.getErrMsg());
                        }
                    }
                });
    }


    public void getSplitTables(int tableId) {
        mModel.getSplitTables(tableId)
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSingleSubscriber<BaseResult>(mErrorHandler) {

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

                    @Override
                    public void onSuccess(@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 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) {
                    mSplitTableDialog.closeDialog();
                    //獲取餐檯狀態
                    getTable(dataBean);
                }
            });
            mSplitTableDialog.setOnRetryListener(new BaseRetryDialog.OnRetryListener() {

                @Override
                public void onRetryClick() {
                    getSplitTables(tableId);
                }
            });
        }
        mSplitTableDialog.setMainTableId(tableId);
        mSplitTableDialog.build().show();
        getSplitTables(tableId);
    }

    private void showDiscountDialog() {
        if (IActivity.findFragment(DiscountDialogFragment.class) == null) {
            DiscountDialogFragment dialogFragment = DiscountDialogFragment.newInstance();
            dialogFragment.setOnDiscountItemClickListener(new DiscountDialogFragment.OnDiscountItemClickListener() {

                @Override
                public void onBillDiscountClick(Discount item, int position) {
                    mNomalDiscountAction.setWholeAmount(mShoppingCart.getWholeAmount());
                    mNomalDiscountAction.setNomalDiscountList(mShoppingCart.getNomalDiscoutByMultyDiscountList());
                    mNomalDiscountAction.action(item);
                    dialogFragment.dismiss();
                }

                @Override
                public void onCouponClick(MemberWalletCoupon item, int position) {
                    mBillCouponAction.setNomalDiscountList(mShoppingCart.getNomalDiscoutByMultyDiscountList());
                    mBillCouponAction.action(item);
                    dialogFragment.dismiss();
                }
            });
            dialogFragment.show(IActivity.getSupportFragmentManager(), "DiscountDialogFragment");
            updateCouponSelects(true);
        }
    }

    /**
     * 更新訂單詳情
     *
     * @param info
     */
    private void updateOrderDetails(BaseOrderResponse info) {
        OrderResponse orderResponse = info.getData();
        if (mMealOrder != null && orderResponse != null) {

            mTableInfo.setPerson(orderResponse.getPerson());
            mTableInfo.setCreateTime(orderResponse.getCreateTime());

            mMealOrder.setOpenTableInfo(mTableInfo);
            mMealOrder.setOrderPlaced(orderResponse);

            if (orderResponse.getOrderDetails() != null) {
                //组装食品信息
                List<OrderDetail> orderDetailList = OrderAssemblyUtil.assemblyOrder(OrderDetail.orderTransOrderDetails(info.getData().getOrderDetails()));

                mMealOrder.setNewFoodList(orderDetailList);

                mOrderMealList.clear();
                mOrderMealList.addAll(orderDetailList);
                mMealCartAdapter.notifyDataSetChanged();
                mMealCartAdapter.setIndex();
            }

            for (BillItem billItem : mBillItemList) {
                //將已有折扣 服務費狀態改為已送單
                billItem.setStatus(BillItem.BILL_ITEM_ORDER_SENT_STATUS);
                billItem.setTextColor(ArmsUtils.getColor(IActivity, R.color.theme_black));
            }
            mBillItemAdapter.notifyDataSetChanged();

            boolean memberItemStatus = false;
            boolean discountItemStatus = false;
            if (orderResponse.getMemberInfo() != null) {
                memberItemStatus = true;
            }
            if (orderResponse.getDiscountDetails() != null) {
                discountItemStatus = true;
            }
            mMealOrder.initBillStatus(memberItemStatus, discountItemStatus);
        }
    }

    /**
     * 轉移條件過濾
     *
     * @return
     */
    public boolean transferFoodConditionFilter(long memberId) {
        List<OrderDetail> oldOrderDetails = getSelectedOldFood();
        for (OrderDetail item : oldOrderDetails) {
            //積分食品轉移-》目標檯不是會員檯-》提示不可轉移
            if ((item.getPointsAdd() != 0 || item.getPointsRedeem() != 0) && memberId == 0) {
                String msg = "積分食品轉移,目標檯不是會員檯,不可轉移!";
                CommonTipDialog.showSurpisedDialog(IActivity, msg, MealBillPresenter.class, MealBillPresenter.this,
                        "", null, null);
                return false;
            }
        }
        return true;
    }

    /**
     * 會員優惠券使用條件
     *
     * @param coupon
     * @return
     */
    private boolean addMemberCouponConditionFilter(CouponDiscountBean coupon) {
        if (coupon.getSpend() != null) {
            //配置了消費滿減
            double toodTotal = getFoodTotal();
            if (toodTotal < coupon.getSpend().doubleValue()) {
                //未滿足消費滿條件
                String msg = "消費金額未滿足使用條件,最低消費[$" + toodTotal + "]";
                CommonTipDialog.showSurpisedDialog(IActivity, msg, MealBillPresenter.class, MealBillPresenter.this,
                        "", null, null);
                return false;
            }
        }
        return true;
    }

    public void removeBillItemByPosition(int index) {
        if (index < mBillItemList.size()) {
            BillItem billItem = mBillItemList.get(index);
            if (billItem instanceof DiscountItem) {
                //刪除折扣列表對應數據
                mShoppingCart.delMultyDiscount(((DiscountItem) billItem).getDiscount());
                MealOrder.getInstance().setBillItemStatus(MealOrder.DISCOUNT_ITEM_TAG);
            }
            updateBillInfo();
        }
    }

    @Override
    protected void initBillAmount(double wholeAmount, double totalAmount) {
        mRootView.initBillAmount(wholeAmount,totalAmount);
    }

    /**
     * 修改訂單包含修改或刪除過的的食品
     *
     * @return
     */
    private boolean hasModifyFoods() {
        for (OrderDetail orderDetail : getOrderFoodLists()) {
            if (orderDetail.isModify()) {
                return true;
            }
        }
        return false;
    }

    private boolean canPrint() {
        if (getFoodCount() == 0) {
            mRootView.showMessage("沒有食品，不能印單");
            return false;
        }
        return true;
    }

    private boolean canPay() {
        if (getFoodCount() == 0) {
            mRootView.showMessage("沒有食品，不能結賬");
            return false;
        }
        return true;
    }

    private boolean canTransfer() {
        if (getFoodCount() == 0 || mMealCartAdapter.getSelect_position() == -1) {
            mRootView.showMessage("請選擇轉移食品");
            return false;
        }
        if (mOrderMealList.get(mMealCartAdapter.getSelect_start_position()).isNew() == true) {
            mRootView.showMessage("請選擇已送單食品轉移");
            return false;
        }
        return true;
    }

    private boolean canDiscount() {
        if (getFoodCount() == 0) {
            mRootView.showMessage("請先選擇食品!");
            return false;
        }
        return true;
    }

    public void startTablePolling() {
        if (mTablesPollingDisposable == null) {
            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 disposeGetTablesDataDisposable(){
        if (mGetTablesDataDisposable != null && !mGetTablesDataDisposable.isDisposed()) {
            mGetTablesDataDisposable.dispose();
        }
    }

    public List<Function> getFunctionList() {
        return mFunctionList;
    }

}
