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

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

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.gingersoft.gsa.cloud.base.application.GsaCloudApplication;
import com.gingersoft.gsa.cloud.base.common.bean.BaseResult;
import com.gingersoft.gsa.cloud.base.common.bean.OrderDetail;
import com.gingersoft.gsa.cloud.base.common.bean.PayMethod;
import com.gingersoft.gsa.cloud.base.common.bean.mealManage.MyOrderManage;
import com.gingersoft.gsa.cloud.base.utils.JsonUtils;
import com.gingersoft.gsa.cloud.base.utils.MoneyUtil;
import com.gingersoft.gsa.cloud.base.utils.gson.GsonUtils;
import com.gingersoft.gsa.cloud.table.app.payment.PayConstant;
import com.gingersoft.gsa.cloud.table.mvp.contract.OrderPayContract;
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.ui.activity.OrderPayActivity;
import com.gingersoft.gsa.cloud.table.mvp.ui.adapter.BillMethodAdapter;
import com.gingersoft.gsa.cloud.table.mvp.ui.adapter.BillMoneyAdapter;
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.ArrayList;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.schedulers.Schedulers;
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: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 BillMethodAdapter mBillMethodAdapter;
    private ArrayList<PayMethod> mBillMethodList = new ArrayList<>();

    private BillMoneyAdapter mBillMoneyAdapter;
    private ArrayList<PayMethod> mBillMoneyList = new ArrayList<>();

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

    /**找零*/
    public static final int LINE_PAY_TYPE_CHANGE = 1;
    /**貼士*/
    public static final int LINE_PAY_TYPE_TIPS = 2;



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

    @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 (mOrderMoneyAdapter != null) {
            mRootView.setOrderDetailAdapter(mOrderMoneyAdapter);
        }
        if (mBillMethodAdapter == null) {
            mBillMethodAdapter = new BillMethodAdapter(mBillMethodList);
            mRootView.setBillMethodAdapter(mBillMethodAdapter);
        }
        if (mBillMoneyAdapter == null) {
            mBillMoneyAdapter = new BillMoneyAdapter(mBillMoneyList);
            mRootView.setBillMoneyAdapter(mBillMoneyAdapter);
        }
    }

    public void initBillListener() {
        mBillMethodAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {

                mRootView.recordOperat(true);

                PayMethod method = (PayMethod) adapter.getItem(position);
//                if (!isCashPayMethod(method)) {
//                    PayMethod N5PayMethod = getSelectN5PayMethod();
//                    if (N5PayMethod != null) {
//                        //最多選擇2中支付方式（現金+其他）
//                        mBillMoneyList.remove(N5PayMethod);
//                        mBillMoneyAdapter.notifyDataSetChanged();
//                    }
//                }
                mBillMoneyList.clear();
//                if (!mBillMoneyList.contains(method)) {
                double differenceMoney = getDifferenceMoney();
                if (differenceMoney > -1) {
                    //補足差額
                    method.setPayMoney(differenceMoney);
                }
                //添加選中支付方式
                mBillMoneyList.add(method);
                mBillMoneyAdapter.setSelect_position(mBillMoneyList.size() - 1);
                mBillMoneyAdapter.notifyDataSetChanged();
                mRootView.setBillMoneyRvScrollToPosition(mBillMoneyList.size() - 1);
                //設置差額狀態
                mRootView.setDifferenceText();
//                }
            }
        });
        mBillMoneyAdapter.setOnItemClickListener(new BillMoneyAdapter.OnItemClickListener() {

            @Override
            public void onItemClick(PayMethod datasBean, int position) {
                mRootView.recordOperat(true);
                mBillMoneyAdapter.setSelect_position(position);
                mBillMoneyAdapter.notifyDataSetChanged();
            }

            @Override
            public void onItemDeleteClick(PayMethod datasBean, int position) {
                mRootView.recordOperat(true);
                //刪除當前付款方式
                mBillMoneyList.remove(position);
                mBillMoneyAdapter.setSelect_position(mBillMoneyList.size() - 1);
                mBillMoneyAdapter.notifyDataSetChanged();
                //設置差額狀態
                mRootView.setDifferenceText();
            }
        });
    }

    public void getPayMethods() {
        int brandId = GsaCloudApplication.getBrandId(mApplication);
        int restaurantId = GsaCloudApplication.getRestaurantId(mApplication);
        mModel.getPayMethods(brandId, restaurantId)
                .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);
                            mBillMethodList.addAll(payMethods);
                            mBillMethodAdapter.notifyDataSetChanged();
                        }
                    }
                });
    }

    /**
     * 結賬
     */
    public void toOrderPay(boolean show) {
        RequestBody requestBody = new FormBody.Builder()
                .add("orderPayType", String.valueOf(orderPayType))
                .add("payType", String.valueOf(mBillMoneyList.get(0).getId()))
                .add("orderId", String.valueOf(MyOrderManage.getInstance().getOrderId()))
                .add("amount", String.valueOf(getAmount()))
                .add("linePayType", String.valueOf(getLinePayType()))
                .add("tipsPrice", String.valueOf(getTipsPrice()))
                .build();
        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) {
                        if (baseResult.isSuccess()) {
                            //結賬成功
                            mRootView.paySuccess();
                        }
                    }
                });
    }

    /**
     * 修改訂單更新支付方式
     */
    public void updateOrderPay() {
        RequestBody requestBody = new FormBody.Builder()
                .add("payType", String.valueOf(mBillMoneyList.get(0).getId()))
                .add("orderId", String.valueOf(MyOrderManage.getInstance().getOrderId()))
                .build();
        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()) {
                            //結賬成功
                            mRootView.paySuccess();
                        }
                    }
                });
    }

    protected void createOrder() {
        CreateOrderRequest request = getCreateOrderRequest(getOrderFoodLists());
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), GsonUtils.GsonString(request));
        mModel.createOrder(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {

                    @Override
                    public void onNext(@NonNull BaseResult info) {
                        if (info != null && info.isSuccess()) {
                            saveCreateTime(info.getSysTime());
                            if (info.getData() != null) {
                                setOrderId((Double) info.getData());
                            }
                            toOrderPay(false);
                        } else {
                            mRootView.showMessage("結賬失敗!");
                        }
                    }

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

    protected void addOrderFood() {
        List<OrderDetail> foodLists = getOrderFoodLists();
        for (OrderDetail food : foodLists) {
            food.setOrderId(MyOrderManage.getInstance().getOrderId());
        }
        AddOrderRequest addOrderRequest = getAddOrderRequest(foodLists);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), GsonUtils.GsonString(addOrderRequest));
        String json = GsonUtils.GsonString(addOrderRequest);
        mModel.addFood(requestBody)
                .subscribeOn(Schedulers.io())
                .doOnSubscribe(disposable -> mRootView.showLoading(null))
                .subscribeOn(AndroidSchedulers.mainThread())
                .observeOn(AndroidSchedulers.mainThread())
                .compose(RxLifecycleUtils.bindToLifecycle(mRootView))
                .subscribe(new ErrorHandleSubscriber<BaseResult>(mErrorHandler) {
                    @Override
                    public void onNext(@NonNull BaseResult info) {
                        if (info != null && info.isSuccess()) {
                            toOrderPay(false);
                        } else {
                            mRootView.showMessage("結賬失敗!");
                        }
                    }

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

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

    public void pressExact() {
        double differenceMoney = getDifferenceMoney();
        PayMethod billMoneyBean = getSelectBillMoney();
        if (billMoneyBean != null && differenceMoney > 0) {
            billMoneyBean.setPayMoney(billMoneyBean.getPayMoney() + differenceMoney);
            mBillMoneyAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 獲取當前選中的支付方式
     *
     * @return
     */
    public PayMethod getSelectBillMoney() {
        for (int i = 0; i < mBillMoneyList.size(); i++) {
            if (i == mBillMoneyAdapter.getSelect_position())
                return mBillMoneyList.get(i);
        }
        return null;
    }

    /**
     * 獲取當前n5支付方式
     *
     * @return
     */
    private PayMethod getSelectN5PayMethod() {
        for (int i = 0; i < mBillMoneyList.size(); i++) {
            if (!TextUtils.isEmpty(mBillMoneyList.get(i).getPAYWAY()) &&
                    !mBillMoneyList.get(i).getPAYWAY().equals(PayConstant.PAY_WAY_CASH)) {
                return mBillMoneyList.get(i);
            }
        }
        return null;
    }

    /**
     * 是否現金支付
     *
     * @param datasBean
     * @return
     */
    private boolean isCashPayMethod(PayMethod datasBean) {
        if (datasBean.getPAYWAY().equals(PayConstant.PAY_WAY_CASH)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 獲取超出的金額為找零還是貼士: linePayType 1 tipsPrice 为找零  2 tipsPrice为贴上
     * 現金，掃碼QR = 找零
     * 信用卡 = 貼士
     *
     * @return 第一階段默認為找零
     */
    public int getLinePayType() {
        return LINE_PAY_TYPE_CHANGE;
    }

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

    /**
     * 獲取食品總金額
     * @return 
     */
    private double getAmount() {
        //支付總額減去找零或貼士
//        return getBillMoney() - getTipsPrice();
        return getBillMoney();
    }


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

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

    /**
     * 是否滿足支付條件
     *
     * @return
     */
    public boolean canPay() {
        double difference = getDifferenceMoney();
        if (difference <= 0) {
            return true;
        }
        return false;
    }

    public ArrayList<PayMethod> getBillMethodList() {
        return mBillMethodList;
    }

    public void setBillMethodList(ArrayList<PayMethod> mBillMethodList) {
        this.mBillMethodList = mBillMethodList;
    }

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

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

    public BillMethodAdapter getBillMethodAdapter() {
        return mBillMethodAdapter;
    }

    public BillMoneyAdapter getBillMoneyAdapter() {
        return mBillMoneyAdapter;
    }
}
