package com.gingersoft.gsa.cloud.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.gingersoft.gsa.cloud.app.GsaCloudApplication;
import com.gingersoft.gsa.cloud.base.R;
import com.gingersoft.gsa.cloud.base.common.bean.MemberInfo;
import com.gingersoft.gsa.cloud.base.common.bean.PayMethod;
import com.gingersoft.gsa.cloud.base.utils.BigDecimalUtils;
import com.gingersoft.gsa.cloud.base.utils.LanguageUtils;
import com.gingersoft.gsa.cloud.base.utils.MoneyUtil;
import com.gingersoft.gsa.cloud.base.utils.VibratorUtils;
import com.gingersoft.gsa.cloud.base.utils.toast.ToastUtils;
import com.gingersoft.gsa.cloud.ui.adapter.BillMethodAdapter;
import com.gingersoft.gsa.cloud.ui.adapter.BillMoneyAdapter;
import com.jess.arms.utils.ArmsUtils;
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.Nullable;

public class OrderPayView extends LinearLayout {

    private Context mContext;

    /**
     * 用戶已選中的支付方式
     */
    private List<PayMethod> mBillMoneyList;
    private BillMoneyAdapter mBillMoneyAdapter;
    private BillMethodAdapter mBillMethodAdapter;
    private OnSelectPayClickLisenter onSelectPayClickLisenter;
    private OnSureClickLisenter mOnSureClickLisenter;
    private OnFreeServiceStatusChangeLisenter onFreeServiceStatusChangeLisenter;

    private int foodCount;
    /**
     * 總金額
     */
    private double totalAmount;
    /**
     * 服務費金額
     */
    private Double serviceCharge = 0.0;

    private MemberInfo memberInfo;

    private RelativeLayout rl_difference;
    private TextView tvDifferenceName;
    private TextView tvDifferenceMoney;
    private TextView btn_order_count;
    private TextView tv_total;

    /**
     * 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;

    /**
     * 最大支付方式數
     */
    public static final int MAX_COUNT_PAY_MEMBER = 2;

    public OrderPayView(Context context) {
        this(context, null);
    }

    public OrderPayView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public OrderPayView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
    }

    public void setMemberInfo(MemberInfo memberInfo) {
        this.memberInfo = memberInfo;
    }

    public void setTotalAmount(double totalAmount) {
        this.totalAmount = totalAmount;
    }

    public void setServiceCharge(Double serviceCharge) {
        this.serviceCharge = serviceCharge;
    }

    public void loadInfo(Context context, List<PayMethod> mBillMethodList, double totalAmount, int foodCount) {
        this.totalAmount = totalAmount;
        this.mBillMoneyList = new ArrayList<>();
        this.foodCount = foodCount;
        init(context, mBillMethodList);
    }

    public void init(Context context, List<PayMethod> mBillMethodList) {
        View view = LayoutInflater.from(context).inflate(R.layout.layout_order_pay, null);

        MaxHeightRecyclerView rv_bill_money = view.findViewById(R.id.rv_bill_money);
        mBillMoneyAdapter = new BillMoneyAdapter(mBillMoneyList);
        rv_bill_money.setAdapter(mBillMoneyAdapter);

        rl_difference = view.findViewById(R.id.rl_difference);
        tvDifferenceName = view.findViewById(R.id.tv_difference_name);
        tvDifferenceMoney = view.findViewById(R.id.tv_difference_money);
        btn_order_count = view.findViewById(R.id.btn_order_count);
        tv_total = view.findViewById(R.id.tv_total);
        initOrderDetail();
        setDifferenceText(context);

        MaxHeightRecyclerView rv_bill_method = view.findViewById(R.id.rv_bill_method);

        mBillMethodAdapter = new BillMethodAdapter(mBillMethodList);
        mBillMethodAdapter.setOnItemClickListener((adapter, view1, position) -> {

            recordOperat(context);

            PayMethod method = (PayMethod) adapter.getItem(position);
            method.setPayMoney(0);

            if (!mBillMoneyList.contains(method)) {

                double paymentDifference = getPaymentDifference();

                if (!addPayMethodCondtion(method, paymentDifference)) {
                    return;
                }

                if (mBillMoneyList.size() == MAX_COUNT_PAY_MEMBER) {
                    //替换掉第一个
                    mBillMoneyList.remove(0);
                }

                boolean useFreeServicePayMethod = isUseFreeServicePayMethod(method);
                if (useFreeServicePayMethod) {
                    //有使用免服務費支付方式 重新獲取一遍尚欠金額
                    paymentDifference = getPaymentDifference();
                }
                setWhetherFreeServiceCallback(useFreeServicePayMethod);

                if (!isIntegralPayMethod(method)) {
                    //是否同步金額
                    //固定金額 (0:否 1:是)
                    if (method.getWhetherFixedAmount() == 1) {
                        //直接补足余额
                        if (Double.doubleToLongBits(method.getMinPayAmount()) != 0) {
                            //補足最小支付金額
                            if (paymentDifference > method.getMinPayAmount()) {
                                method.setPayMoney(paymentDifference);
                            } else {
                                method.setPayMoney(method.getMinPayAmount());
                            }
                        } else {
                            //補足差額
                            if (paymentDifference > -1 && Double.doubleToLongBits(paymentDifference) != totalAmount) {
                                method.setPayMoney(paymentDifference);
                            }
                        }
                    } else {
                        if (Double.doubleToLongBits(method.getMinPayAmount()) != 0) {
                            //補足最小支付金額
                            method.setPayMoney(method.getMinPayAmount());
                        }
                    }
                }

                //添加選中支付方式
                mBillMoneyList.add(method);

                int notifyPosition = mBillMoneyList.size() - 1;
                mBillMoneyAdapter.setSelect_position(notifyPosition);
                mBillMoneyAdapter.notifyDataSetChanged();
                rv_bill_money.scrollToPosition(notifyPosition);

                //設置差額狀態
                setDifferenceText(context);

                if (onSelectPayClickLisenter != null) {
                    onSelectPayClickLisenter.addClick(method);
                }
            }
        });
        mBillMoneyAdapter.setOnItemClickListener(new BillMoneyAdapter.OnItemClickListener() {

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

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

                setWhetherFreeServiceCallback(isUseFreeServicePayMethod(null));

                if (onSelectPayClickLisenter != null) {
                    onSelectPayClickLisenter.delClick(datasBean);
                }
            }
        });


        rv_bill_method.setAdapter(mBillMethodAdapter);
//        rv_bill_method.addItemDecoration(new GridDividerItemDecoration(QMUIDisplayHelper.dpToPx(1), ArmsUtils.getColor(context, R.color.theme_hint_color)));

        //Exact
        view.findViewById(R.id.btn_exact).setOnClickListener(v -> {
            PayMethod selectPayMethod = getSelectBillMoney();
            if (selectPayMethod == null) {
                ToastUtils.show(context, "請選擇支付方式");
                return;
            }
            boolean useFreeServicePayMethod = isUseFreeServicePayMethod(selectPayMethod);
            setWhetherFreeServiceCallback(useFreeServicePayMethod);

            pressExact();
            setDifferenceText(context);
        });

        //sure
        view.findViewById(R.id.btn_sure_pay).setOnClickListener(v -> {
            if (mBillMoneyList.size() == 0) {
                ToastUtils.show(context, "請選擇支付方式");
                return;
            }
            if (!canPay()) {
                tipMoneyInsufficient(context);
                return;
            }
            if (mOnSureClickLisenter != null) {
                mOnSureClickLisenter.onClick(mBillMoneyList);
            }
        });

        //Keypad
        view.findViewById(R.id.layout_keypad).setOnClickListener(v -> {
            PayMethod payMethod = getSelectBillMoney();
            if (payMethod == null) {
                ToastUtils.show(context, "請選擇支付方式");
                return;
            }
            if (isIntegralPayMethod(payMethod)) {
                showIntergralKeypadDialog(context, payMethod);
            } else {
                showPayKeypadDialog(context, payMethod);
            }
        });
        this.addView(view);
    }

    private boolean addPayMethodCondtion(PayMethod method, double paymentDifference) {
        boolean isIntegralPayMethod = isIntegralPayMethod(method);
        if (isIntegralPayMethod) {
            //積分支付
            if (memberInfo == null) {
                //提示沒有登錄會員 不能使用積分支付
                showTipWord(LanguageUtils.get_language_system(mContext, "member.not.logged.cannot.be.used", "會員尚未登錄,不能使用") + method.getPayName());
                return false;
            }
            //驗證積分數是否滿足
            boolean verifyStatus = verifyIntegralNumber(method, memberInfo.getMemberPoint(), memberInfo.getPointRedeemCash(), paymentDifference, true);
            if (!verifyStatus) {
                return false;
            }
        }
        return true;
    }

    /**
     * 設置是否免服務費回調
     */
    public void setWhetherFreeServiceCallback(boolean isUseFreeServicePayMethod) {
        if (onFreeServiceStatusChangeLisenter != null) {
            onFreeServiceStatusChangeLisenter.onFreeServiceStautsChange(isUseFreeServicePayMethod);
        }
    }

    /**
     * 是否有使用免服務費的支付方式
     *
     * @param method
     * @return
     */
    private boolean isUseFreeServicePayMethod(PayMethod method) {
        boolean freeServiceStatus = false;
        if (method != null) {
            if (method.getWhetherFreeService() == 1) {
                freeServiceStatus = true;
            }
        }
        if (freeServiceStatus == false) {
            for (PayMethod payMethod : mBillMoneyList) {
                if (payMethod.getWhetherFreeService() == 1) {
                    freeServiceStatus = true;
                    break;
                }
            }
        }
        return freeServiceStatus;
    }

    public void notifyBillMethodAdapter(List<PayMethod> mBillMethodList) {
        if (mBillMethodAdapter != null) {
            mBillMethodAdapter.setNewInstance(mBillMethodList);
        }
    }

    private void recordOperat(Context context) {
        VibratorUtils.pressButtonSound(context);
    }

    private void tipMoneyInsufficient(Context context) {
        QMUITipDialog tipDialog = new QMUITipDialog.Builder(context)
                .setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
                .setTipWord("金額不足!")
                .create();
        tipDialog.show();
        this.postDelayed(tipDialog::dismiss, 1500);
    }

    private void showTipWord(String tipWord) {
        QMUITipDialog tipDialog = new QMUITipDialog.Builder(getContext())
                .setIconType(QMUITipDialog.Builder.ICON_TYPE_INFO)
                .setTipWord(tipWord)
                .create();
        tipDialog.show();
        btn_order_count.postDelayed(new Runnable() {
            @Override
            public void run() {
                tipDialog.dismiss();
            }
        }, 1500);
    }

    /**
     * Exact
     */
    public void pressExact() {
        PayMethod billMoneyBean = getSelectBillMoney();
        double paymentDifference = getDifferenceMoney();
        if (billMoneyBean != null && paymentDifference > 0) {
            //這裡需要加上現有的金額
            paymentDifference = MoneyUtil.sum(paymentDifference, billMoneyBean.getPayMoney());
            boolean isIntegralPayMethod = isIntegralPayMethod(billMoneyBean);
            if (isIntegralPayMethod) {
                //積分支付
                boolean verifyStatus = verifyIntegralNumber(billMoneyBean, memberInfo.getMemberPoint(), memberInfo.getPointRedeemCash(), paymentDifference, false);
                if (!verifyStatus) {
                    return;
                }
                if (onSelectPayClickLisenter != null) {
                    onSelectPayClickLisenter.updateIntegralInfo();
                }
            } else {
                billMoneyBean.setPayMoney(paymentDifference);
            }
            mBillMoneyAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 是否滿足支付條件
     *
     * @return
     */
    public boolean canPay() {
        double difference = MoneyUtil.sub(totalAmount, getBillMoney());
        if (Double.doubleToLongBits(difference) <= 0) {
            return true;
        }
        return false;
    }

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

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

    /**
     * 獲取支付差額
     *
     * @return
     */
    public double getPaymentDifference() {
        double paymentDifference;
        if (mBillMoneyList.size() == 0) {
            paymentDifference = totalAmount;
        } else {
            paymentDifference = MoneyUtil.sub(totalAmount, getBillMoney());
        }
        return MoneyUtil.get_ItemDecimals_money(paymentDifference);
    }

    /**
     * 獲取總差額
     *
     * @return
     */
    public double getDifferenceMoney() {
        double paymentDifference = MoneyUtil.sub(totalAmount, getBillMoney());
        return MoneyUtil.get_ItemDecimals_money(paymentDifference);
    }

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

    /**
     * 獲取積分支付金額
     *
     * @return
     */
    public double getIntegralPayMoney() {
        double totalMoney = 0.0;
        if (mBillMoneyList != null) {
            for (PayMethod method : mBillMoneyList) {
                if (isIntegralPayMethod(method)) {
                    totalMoney = MoneyUtil.sum(totalMoney, method.getPayMoney());
                }
            }
        }
        return totalMoney;
    }

    /**
     * 獲取積分支付金額
     *
     * @return
     */
    public double getIntegralPayMoney(PayMethod filterPayMethod) {
        double totalMoney = 0.0;
        if (mBillMoneyList != null) {
            for (PayMethod method : mBillMoneyList) {
                if (filterPayMethod != method && isIntegralPayMethod(method)) {
                    totalMoney = MoneyUtil.sum(totalMoney, method.getPayMoney());
                }
            }
        }
        return totalMoney;
    }

    /**
     * 獲取積分支付抵扣金額
     *
     * @param memberIntegral        當前會員積分數
     * @param memberPointRedeemCash 積分兌換金額比例 MemberPointRedeemCash=2 （理解為每2分=1元)
     * @return
     */
    public double getIntegralDeductionAmount(double memberIntegral, double memberPointRedeemCash) {
        if (memberIntegral < 1 || memberPointRedeemCash < 1) {
            return 0;
        }
        double deductionAmount = MoneyUtil.divide(memberIntegral, memberPointRedeemCash, 2);
        if (deductionAmount > 0) {
            return MoneyUtil.get_ItemDecimals_money(deductionAmount);
        } else {
            return 0;
        }
    }

    /**
     * 獲取積分支付消費積分
     *
     * @param filterPayMethod       需要過濾掉的支付方式
     * @param memberPointRedeemCash 積分兌換金額比例 MemberPointRedeemCash=2 （理解為每2分=1元)
     * @return
     */
    public double getPayForConsumptionPoints(PayMethod filterPayMethod, double memberPointRedeemCash) {
        double consumptionPoints;
        if (filterPayMethod != null) {
            consumptionPoints = MoneyUtil.multiply(getIntegralPayMoney(filterPayMethod), memberPointRedeemCash);
        } else {
            consumptionPoints = MoneyUtil.multiply(getIntegralPayMoney(), memberPointRedeemCash);
        }
        if (consumptionPoints > 0) {
            return MoneyUtil.get_ItemDecimals_money(consumptionPoints);
        } else {
            return 0;
        }
    }

    /**
     * 是不是积分支付方式
     *
     * @param method
     * @return
     */
    private boolean isIntegralPayMethod(PayMethod method) {
        if (method.getPayType() == PayMethod.PAY_TYPE_INTEGRAL) {
            return true;
        }
        return false;
    }

    /**
     * @param payMethod
     * @param memberIntegral        會員積分
     * @param memberPointRedeemCash 積分兌換現金比率
     * @param paymentDifference     還差多少錢
     * @param addPayMethod          新增積分支付
     * @return
     */
    public boolean verifyIntegralNumber(PayMethod payMethod, double memberIntegral, double memberPointRedeemCash, double paymentDifference, boolean addPayMethod) {
        //總積分可兌換金額
        double deductionAmount = getIntegralDeductionAmount(memberIntegral, memberPointRedeemCash);
        double consumptionPoints = 0;
        if (!addPayMethod) {
            consumptionPoints = getPayForConsumptionPoints(payMethod, memberPointRedeemCash);
        }
        //積分支付總額
        double totalIntegralPayMoney;
        double integralPayMoney = 0;
        if (!addPayMethod) {
            integralPayMoney = getIntegralPayMoney(deductionAmount, paymentDifference);
        }
        totalIntegralPayMoney = integralPayMoney + getIntegralPayMoney(payMethod);

        if (deductionAmount == 0 || deductionAmount < totalIntegralPayMoney || memberIntegral < consumptionPoints) {
            ArmsUtils.makeText(mContext, "積分不足!");
            return false;
        }
        if (!addPayMethod) {
            payMethod.setPayMoney(integralPayMoney);
        }
        return true;
    }


    public double getIntegralPayMoney(double deductionAmount, double paymentDifference) {
        if (deductionAmount > paymentDifference) {
            //補足差額
            return paymentDifference;
        } else {
            return deductionAmount;
        }
    }

    public void showPayKeypadDialog(Context context, PayMethod method) {
        new PayKeypadDialog(context)
                .setPayMethod(method.getPayName())
                .builder()
                .setComfirmListener(money -> {
                    method.setPayMoney(Double.parseDouble(money));
                    mBillMoneyAdapter.notifyDataSetChanged();
                    setDifferenceText(context);
                })
                .show();
    }

    public void showIntergralKeypadDialog(Context context, PayMethod method) {
        new IntergralKeypadDialog(context)
                .setPayMethod(method.getPayName())
                .builder()
                .setComfirmListener(money -> {

                    boolean verifyStatus = verifyIntegralNumber(method, memberInfo.getMemberPoint(), memberInfo.getPointRedeemCash(), Double.parseDouble(money), false);
                    if (!verifyStatus) {
                        return;
                    }

                    mBillMoneyAdapter.notifyDataSetChanged();
                    setDifferenceText(context);

                    if (onSelectPayClickLisenter != null) {
                        onSelectPayClickLisenter.updateIntegralInfo();
                    }
                })
                .show();
    }

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

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

    public void setDifferenceText(Context context) {
        //還需付多少金額
        double difference = getDifferenceMoney();
        if (difference < 0) {
            //貼士
            if (getLinePayType() == 1) {
                tvDifferenceName.setText("找零");
                tvDifferenceMoney.setTextColor(ArmsUtils.getColor(context, R.color.red));
            } else {
                tvDifferenceName.setText("貼士");
                tvDifferenceMoney.setTextColor(ArmsUtils.getColor(context, R.color.Grass_green));
            }
            tvDifferenceMoney.setText("$" + Math.abs(difference));
        } else {
            //尚欠
            tvDifferenceName.setText("尚欠金額");
            tvDifferenceMoney.setTextColor(ArmsUtils.getColor(context, R.color.red));
            if (Double.doubleToLongBits(difference) == 0) {
                tvDifferenceMoney.setText("$" + Math.abs(difference));
            } else {
                tvDifferenceMoney.setText("-$" + Math.abs(difference));
            }
        }
    }

    public void initOrderDetail() {
        if (foodCount > 0) {
            btn_order_count.setText(String.valueOf(foodCount));
            btn_order_count.setVisibility(View.VISIBLE);
        } else {
            btn_order_count.setVisibility(View.INVISIBLE);
        }
        tv_total.setText("$" + totalAmount);
    }

    public void updateOrderPay(double totalAmount) {
        setTotalAmount(totalAmount);
        initOrderDetail();
        setDifferenceText(GsaCloudApplication.getAppContext());
    }

    public void setOnFreeServiceStatusChangeLisenter(OnFreeServiceStatusChangeLisenter onFreeServiceStatusChangeLisenter) {
        this.onFreeServiceStatusChangeLisenter = onFreeServiceStatusChangeLisenter;
    }

    public void setOnSelectPayClickLisenter(OnSelectPayClickLisenter onSelectPayClickLisenter) {
        this.onSelectPayClickLisenter = onSelectPayClickLisenter;
    }

    public void setmOnSureClickLisenter(OnSureClickLisenter mOnSureClickLisenter) {
        this.mOnSureClickLisenter = mOnSureClickLisenter;
    }

    public interface OnFreeServiceStatusChangeLisenter {
        void onFreeServiceStautsChange(boolean isUseFreeServicePayMethod);
    }

    public interface OnSelectPayClickLisenter {
        void addClick(PayMethod method);

        void delClick(PayMethod method);

        void updateIntegralInfo();
    }

    public interface OnSureClickLisenter {
        void onClick(List<PayMethod> mBillMoneyList);
    }

}
