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

import android.app.Application;
import android.text.TextUtils;

import com.gingersoft.gsa.cloud.common.bean.BaseResult;
import com.gingersoft.gsa.cloud.common.constans.FoodSummaryConstans;
import com.gingersoft.gsa.cloud.common.constans.HttpsConstans;
import com.gingersoft.gsa.cloud.common.core.member.MemberInfo;
import com.gingersoft.gsa.cloud.common.core.restaurant.RestaurantInfoManager;
import com.gingersoft.gsa.cloud.common.logan.LoganManager;
import com.gingersoft.gsa.cloud.common.utils.JsonUtils;
import com.gingersoft.gsa.cloud.common.utils.MoneyUtil;
import com.gingersoft.gsa.cloud.common.utils.gson.GsonUtils;
import com.gingersoft.gsa.cloud.order.bean.request.MealOrderPayRequest;
import com.gingersoft.gsa.cloud.order.commodity.OrderDetail;
import com.gingersoft.gsa.cloud.pay.bean.PayMethod;
import com.gingersoft.gsa.cloud.table.mvp.contract.OrderPayContract;
import com.gingersoft.gsa.cloud.table.mvp.model.bean.response.OrderPayResponse;
import com.gingersoft.gsa.cloud.table.mvp.ui.activity.OrderPayActivity;
import com.gingersoft.gsa.cloud.ui.view.OrderPayView;
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.RxLifecycleUtils;

import java.util.List;

import javax.inject.Inject;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import okhttp3.MediaType;
import okhttp3.RequestBody;


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

    private OrderPayActivity IActivity;

    private List<PayMethod> mBillMoneyList;
    /**
     * 0#店內支付
     * 1#貨到付款
     * 2#在線支付
     */
    private final int orderPayType = 0;


    @Inject
    public OrderPayPresenter(OrderPayContract.Model model, OrderPayContract.View rootView) {
        super(model, rootView);
        this.IActivity = (OrderPayActivity) rootView;
    }

    @Override
    public void createOrder(boolean isPrint, Class afterToActivity) {
    }

    @Override
    public void addOrderFood(boolean isPrint, Class afterToActivity) {
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.mAppManager = null;
        this.mImageLoader = null;
        this.mApplication = null;
    }

    public void initAdapter() {
        if (mSelectMealAdapter != null) {
            mRootView.setFoodAdapter(mSelectMealAdapter);
        }
        if (mBillItemAdapter != null) {
            mRootView.setOrderDetailAdapter(mBillItemAdapter);
        }
    }

    public void getPayMethods() {
        int brandId = RestaurantInfoManager.newInstance().getBrandId();
        int restaurantId = RestaurantInfoManager.newInstance().getRestaurantId();
        mModel.getPayMethods(brandId, restaurantId, FoodSummaryConstans.RESTAURANT_MODE)
                .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(BaseResult baseResult) {
                        if (baseResult.isSuccess()) {
                            List<PayMethod> payMethods = JsonUtils.parseArray(baseResult.getData(), PayMethod.class);
                            for (int i = 0; i < payMethods.size(); i++) {
                                //這裡有對象為null的情況 排除掉
                                if (payMethods.get(i) == null) {
                                    payMethods.remove(i);
                                }
//                                if (BuildConfig.DEBUG) {
//                                    if (i == 0) {
//                                        payMethods.get(i).setPayType(PayMethod.PAY_TYPE_INTEGRAL);
//                                        payMethods.get(i).setPayName("測試積分支付");
//                                    }
//                                }
                            }
                            mRootView.loadPayMethodsSuccess(payMethods);
                        }
                    }
                });
    }

    /**
     * 結賬
     */
    public void toOrderPay(boolean show) {
        if (mDoshokuOrder.isModifyOrder()) {
            //修改訂單
            updateOrderPay();
            return;
        }
        OrderPayView orderPayView = IActivity.getGsaPayView();
        if (orderPayView.getBillMoneyList() == null || orderPayView.getBillMoneyList().size() == 0) {
            return;
        }

        String payRequest = GsonUtils.GsonString(getOrderPayRequest(orderPayView));
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), payRequest);

        mModel.toOrderPay(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> {
                    if (show) {
                        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(BaseResult baseResult) {
                        mRootView.hideLoading();
                        if (baseResult.isSuccess()) {
                            OrderPayResponse orderPayRespose = JsonUtils.parseObject(baseResult.getData(), OrderPayResponse.class);
                            if (orderPayRespose != null) {
                                if (mDoshokuOrder.getMemberInfo() != null) {
                                    mDoshokuOrder.setAddPoints(orderPayRespose.getAddPoints());
                                    mDoshokuOrder.setNowPoints(orderPayRespose.getNowPoints());
                                    mDoshokuOrder.setOldPoints(orderPayRespose.getOldPoints());
                                } else {
                                    if (!TextUtils.isEmpty(orderPayRespose.getVerifyCode())) {
                                        mDoshokuOrder.setIntegralQrcode(HttpsConstans.PRINT_QRCODE_ADDRESS + orderPayRespose.getVerifyCode());
                                    }
                                }
                            }
                            LoganManager.w_pay(TAG, "支付成功");
                            mRootView.showMessage("支付成功");
                            //結賬成功
                            mRootView.paySuccess();
                        } else {
                            LoganManager.w_pay(TAG, "支付失敗=" + baseResult.getErrMsg());
                            mRootView.showMessage(baseResult.getErrMsg());
                        }
                    }

                    @Override
                    public void onError(Throwable t) {
                        super.onError(t);
                        mRootView.hideLoading();
                    }
                });
    }

    public MealOrderPayRequest getOrderPayRequest(OrderPayView orderPayView) {

        MemberInfo memberInfo = mDoshokuOrder.getMemberInfo();

        List<PayMethod> payMethodList = orderPayView.getBillMoneyList();

        MealOrderPayRequest payRequest = new MealOrderPayRequest();
        payRequest.setOrderId(mDoshokuOrder.getOrderId());
        payRequest.setOrderPayType(orderPayType);
        payRequest.setLinePayType(orderPayView.getLinePayType());
        payRequest.setTableId(mTableInfo.getId());
        payRequest.setTableNumber(mTableInfo.getTableNumber());
        if (memberInfo != null) {
            payRequest.setMemberId(memberInfo.getId());
            payRequest.setCouponId(getCouponDiscountId());
        }
        payRequest.setPointsAdd(getPointsAdd());
        payRequest.setPointsUse(getPointsRedeem());

        int whetherFreeService = 0;
        for (int i = 0; i < payMethodList.size(); i++) {
            PayMethod payMethod = payMethodList.get(i);
            MealOrderPayRequest.OrderPay orderPay = new MealOrderPayRequest.OrderPay();
            orderPay.setPayType(payMethod.getPayType());
            if (payMethodList.size() == 2) {
                if (i == 1) {
                    //小费放在第二种支付方式里面
                    orderPay.setTipsPrice(orderPayView.getTipsPrice());
                }
            } else {
                orderPay.setTipsPrice(orderPayView.getTipsPrice());
            }
            if (orderPay.getPayType() == PayMethod.PAY_TYPE_INTEGRAL) {
                double consumptionPoints = orderPayView.getPayForConsumptionPoints(null, memberInfo.getPointRedeemCash());
                orderPay.setConsumptionPoints(consumptionPoints);
//                //減去積分支付所用的積分
//                payRequest.setPointsUse(MoneyUtil.sum(payRequest.getPointsUse(), consumptionPoints));
            }
            whetherFreeService = payMethod.getWhetherFreeService();
            orderPay.setAmount(payMethod.getPayMoney());
            payRequest.getOrderPays().add(orderPay);
        }
        payRequest.setWhetherFreeService(whetherFreeService);

        return payRequest;
    }

    /**
     * 修改訂單更新支付方式
     */
    public void updateOrderPay() {
        OrderPayView orderPayView = IActivity.getGsaPayView();
        if (orderPayView.getBillMoneyList() == null || orderPayView.getBillMoneyList().size() == 0) {
            return;
        }

        String payRequest = GsonUtils.GsonString(getOrderPayRequest(orderPayView));
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), payRequest);

        mModel.updateOrderPay(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(BaseResult baseResult) {
                        if (baseResult.isSuccess()) {
                            LoganManager.w_pay(TAG, "修改訂單支付成功");
                            //結賬成功
                            mRootView.paySuccess();
                        }else {
                            LoganManager.w_pay(TAG, "修改訂單支付失敗=" + baseResult.getErrMsg());
                        }
                    }
                });
    }

    /**
     * 結賬前創建訂單或添加食品
     */
    public void sendOrderBefore() {
//        if (hasNesOrderFoods() || getNesOrderDiscount() != null || hasDeleteFood()) {
//            //有食品或折扣未送單 先送單
//            sendOrder(false);
//        } else {
        //去結賬
        toOrderPay(true);
//        }
    }

    public void setFreeServiceStauts(boolean useFreeServicePayMethod) {
        //更新服務費中劃線
        mBillItemAdapter.setFreeServiceStauts(useFreeServicePayMethod);
        //更新總金額
        updateBillInfo(new UpdateBillInfoEndListener() {
            @Override
            public void onUpdateEnd() {
                OrderPayView orderPayView = IActivity.getGsaPayView();
                if (orderPayView != null) {
                    orderPayView.updateOrderPay(getTotalAmount());
                }
            }
        });
    }

    /**
     * 獲取找零或貼士金額
     *
     * @return
     */
    public double getTipsPrice() {
        double tips = 0.0;
        double difference = getDifferenceMoney();
        if (difference < 0) {
            tips = difference;
        }
        return Math.abs(tips);
    }

    /**
     * 獲取支付差額
     *
     * @return
     */
    public double getDifferenceMoney() {
        double differenceMoney = MoneyUtil.sub(getTotalAmount(), getBillMoney());
        return MoneyUtil.get_ItemDecimals_money(differenceMoney);
    }

    /**
     * 獲取支付總額
     *
     * @return
     */
    private double getBillMoney() {
        double totalMoney = 0.0;
        for (PayMethod method : mBillMoneyList) {
            totalMoney = MoneyUtil.sum(totalMoney, method.getPayMoney());
        }
        return totalMoney;
    }

    /**
     * 額外食品加分
     *
     * @return
     */
    public double getPointsAdd() {
        double pointsAdd = 0;
        for (OrderDetail orderDetail : mOrderMealList) {
            if (orderDetail.getType() == OrderDetail.FOOD_TYPE) {
                pointsAdd = MoneyUtil.sum(pointsAdd, MoneyUtil.multiply(orderDetail.getPointsAdd(), orderDetail.getNumber()));
            }
        }
        return pointsAdd;
    }

    /**
     * 換購食品所需積分
     *
     * @return
     */
    public double getPointsRedeem() {
        double pointsRedeem = 0;
        for (OrderDetail orderDetail : mOrderMealList) {
            if (orderDetail.getType() == OrderDetail.FOOD_TYPE) {
                pointsRedeem = MoneyUtil.sum(pointsRedeem, MoneyUtil.multiply(orderDetail.getPointsRedeem(), orderDetail.getNumber()));
            }
        }
        return pointsRedeem;
    }

    public List<PayMethod> getBillMoneyList() {
        return mBillMoneyList;
    }

    public void setBillMoneyList(List<PayMethod> mBillMoneyList) {
        this.mBillMoneyList = mBillMoneyList;
    }
}
