package com.gingersoft.gsa.cloud.order.cart;

import com.gingersoft.gsa.cloud.common.core.member.MemberInfo;
import com.gingersoft.gsa.cloud.common.core.delivery.OrderDetails;
import com.gingersoft.gsa.cloud.database.bean.Discount;
import com.gingersoft.gsa.cloud.order.bean.discount.CouponDiscountBean;
import com.gingersoft.gsa.cloud.order.bean.discount.MemberWalletCoupon;
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.MemberLevelDiscount;
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 java.util.ArrayList;
import java.util.List;

import lombok.Getter;
import lombok.Setter;

/**
 * 作者：ELEGANT_BIN
 * 版本：1.6.0
 * 创建日期：2020-09-19
 * 修订历史：2020-09-19
 * 描述: 購物車
 */
@Setter
@Getter
public class ShoppingCart {

    private static ShoppingCart shoppingCart;

    public static ShoppingCart getInstance() {
        if (shoppingCart == null) {
            synchronized (ShoppingCart.class) {
                if (shoppingCart == null) {
                    shoppingCart = new ShoppingCart();
                }
            }
        }
        return shoppingCart;
    }

    /**
     * 外送/自取 的訂單數據
     */
    protected OrderDetails.DataBean deliveryAndPickupData;
    /**
     * 商品列表
     */
    protected List<OrderDetail> orderCommodityList = new ArrayList<>();
    /**
     * 賬單項列表
     *
     * @see
     */
    protected List<BillItem> billItemList = new ArrayList<>();
    /**
     * 折扣列表
     *
     * @see NomalDiscount
     * @see MemberLevelDiscount
     * @see MemberCouponDiscount
     */
    protected List<MultyDiscount> multyDiscountList;
    /**
     * 服務費
     */
    protected Double serviceCharge;
    /**
     * 賬單小數
     */
    protected Double rounding;
    /**
     * 合計
     */
    protected double wholeAmount = 0.0;
    /**
     * 總金額
     */
    protected double totalAmount = 0.0;

    /**
     * 調整購物車商品數量
     */
    private ShoppingCartNumberChange cartNumberChange = new ShoppingCartNumberChange(orderCommodityList);


    public void changeNumber(int number, OrderDetail orderFood, OrderDetail orderMainFood, int select_Full_start_position, int select_Full_end_position, ShoppingCartNumberChange.OnNumberChangeListener listener) {
        cartNumberChange.changeNumber(number, orderFood, orderMainFood, select_Full_start_position, select_Full_end_position, listener);
    }

    /**
     * 將商品添加到購物車
     *
     * @param commodityList
     */
    public void addCommodityList(List<OrderDetail> commodityList) {
        orderCommodityList.addAll(commodityList);
    }

    /**
     * 將商品添加到購物車
     *
     * @param commodity
     */
    public void addCommodity(OrderDetail commodity) {
        orderCommodityList.add(commodity);
    }

    /**
     * 將商品移出購物車
     *
     * @param commodity
     */
    public void delCommodity(OrderDetail commodity) {
        orderCommodityList.remove(commodity);
    }

    /**
     * 修改商品數量
     *
     * @param commodity
     */
    public void setCommodityNum(OrderDetail commodity, int number) {
        for (OrderDetail c : orderCommodityList) {
            if (c == commodity) {
                c.setNumber(number);
                break;
            }
        }
    }

    /**
     * 添加賬單項
     *
     * @param billItem
     */
    public void addBillItem(BillItem billItem) {
        billItemList.add(billItem);
    }

    /**
     * 添加賬單項
     *
     * @param billItems
     */
    public void addBillItems(List<BillItem> billItems) {
        billItemList.addAll(billItems);
    }

    /**
     * 刪除張單項
     *
     * @param billItem
     */
    public void delBillItem(BillItem billItem) {
        billItemList.remove(billItem);
    }

    /**
     * 添加折扣
     *
     * @param multyDiscount
     */
    public void addMultyDiscount(MultyDiscount multyDiscount) {
        getMultyDiscountList().add(multyDiscount);
    }

    /**
     * 刪除目標狀態折扣
     * @param status
     */
    public void delMultyDiscountByStatus(int status) {
        final List<MultyDiscount> multyDiscountList = getMultyDiscountList();
        for (int i = multyDiscountList.size() - 1; i >= 0; i--) {
            final MultyDiscount multyDiscount = multyDiscountList.get(i);
            if(multyDiscount.getStatus() == status){
                multyDiscountList.remove(multyDiscount);
            }
        }
    }

    /**
     * 刪除折扣
     *
     * @param multyDiscount
     */
    public void delMultyDiscount(MultyDiscount multyDiscount) {
        getMultyDiscountList().remove(multyDiscount);
    }

    /**
     * 刪除所有折扣
     */
    public void delAllMultyDiscount() {
        List<MultyDiscount> multyDiscountList = getMultyDiscountList();
        boolean result = multyDiscountList.removeAll(multyDiscountList);
    }

    /**
     * 刪除所有單折扣
     */
    public boolean delAllNomalDiscountList(List<NomalDiscount> nomalDiscountList) {
        return getMultyDiscountList().removeAll(nomalDiscountList);
    }

    /**
     * 根據折扣類型,獲取對應的折扣
     *
     * @param discountType
     */
    public MultyDiscount getDiscountByType(int discountType) {
        for (BillItem item : billItemList) {
            if (item instanceof DiscountItem && item.getType() == discountType) {
                DiscountItem discountItem = (DiscountItem) item;
                return discountItem.getDiscount();
            }
        }
        return null;
    }

    /**
     * 將普通折扣添加到鏈條中
     *
     * @param discount
     * @return
     */
    public MultyDiscount addNomalDiscountToLinked(MultyDiscount multyDiscounts, Discount discount, int status) {
        MultyDiscount nomalDiscount = new NomalDiscount(discount.getRemark(), status, multyDiscounts, discount);
        return nomalDiscount;
    }

    /**
     * 將會員等級折扣添加到鏈條中
     *
     * @param discount
     * @return
     */
    public MultyDiscount addMemberLevelDiscountToLinked(MultyDiscount multyDiscounts, MemberInfo discount, int status) {
        MultyDiscount memberLevelDiscount = new MemberLevelDiscount(discount.getMemberName(), status, multyDiscounts, discount);
        return memberLevelDiscount;
    }

    /**
     * 將會員優惠券折扣添加到鏈條中
     *
     * @param walletCoupon
     * @return
     */
    public MultyDiscount addMemberWalletCouponDiscountToLinked(MultyDiscount multyDiscounts, MemberWalletCoupon walletCoupon, int status) {
        MultyDiscount couponDiscount = new MemberWalletCouponDiscount(walletCoupon.getCouponTypeName(), status, multyDiscounts, walletCoupon);
        return couponDiscount;
    }

    public MultyDiscount createNomalDiscount(Discount discount, int status) {
        MultyDiscount nomalDiscount = new NomalDiscount(discount.getRemark(), status, null, discount);
        return nomalDiscount;
    }

    public MultyDiscount createMemberDiscount(MemberInfo discount, int status) {
        MultyDiscount memberLevelDiscount = new MemberLevelDiscount(discount.getMemberName(), status, null, discount);
        return memberLevelDiscount;
    }

    public MultyDiscount createCouponDiscount(CouponDiscountBean discount, int status) {
        MultyDiscount couponDiscount = new MemberCouponDiscount(discount.getName(), status, null, discount);
        return couponDiscount;
    }

    public MultyDiscount createMemberWalletCoupon(MemberWalletCoupon walletCoupon, int status) {
        MultyDiscount walletCouponDiscount = new MemberWalletCouponDiscount(walletCoupon.getCouponTypeName(), status, null, walletCoupon);
        return walletCouponDiscount;
    }

    /**
     * 計算折扣鏈金額
     */
    public double calculateLinkedDiscounts(double money) {
        //折扣集合保存每個已經計算過的折扣
        List<MultyDiscount> multyDiscountArrays = new ArrayList<>();
        //折扣鏈對象
        MultyDiscount multyDiscounts = null;
        for (int i = getMultyDiscountList().size() - 1; i >= 0; i--) {
            MultyDiscount discount = getMultyDiscountList().get(i);
            if (discount instanceof NomalDiscount) {
                multyDiscounts = addNomalDiscountToLinked(multyDiscounts, ((NomalDiscount) discount).getDiscount(), discount.getStatus());
            } else if (discount instanceof MemberLevelDiscount) {
                multyDiscounts = addMemberLevelDiscountToLinked(multyDiscounts, ((MemberLevelDiscount) discount).getMemberDiscount(), discount.getStatus());
            }
//            else if (discount instanceof MemberCouponDiscount) {
//                multyDiscounts = addMemberCouponDiscountToLinked(multyDiscounts, ((MemberCouponDiscount) discount).getCouponDiscount(), discount.getStatus());
//            }
            else if (discount instanceof MemberWalletCouponDiscount) {
                multyDiscounts = addMemberWalletCouponDiscountToLinked(multyDiscounts, ((MemberWalletCouponDiscount) discount).getWalletCoupon(), discount.getStatus());
            }
            multyDiscountArrays.add(multyDiscounts);
        }
        if (money != 0 && multyDiscounts != null) {
            //計算折扣金額
            money = multyDiscounts.calculate(money);
        }
        //更新折扣billItem數據
        updateDiscountBillItem(multyDiscountArrays);
        return money;
    }

    private void updateDiscountBillItem(List<MultyDiscount> multyDiscountArrays) {
        byte discountType = BillItem.NOMAL_DISCOUNT_TYPE;
        for (int i = multyDiscountArrays.size() - 1; i >= 0; i--) {
            MultyDiscount discount = multyDiscountArrays.get(i);
            String discountName = discount.getName();
            if (discount instanceof NomalDiscount) {
                discountType = BillItem.NOMAL_DISCOUNT_TYPE;
            } else if (discount instanceof MemberLevelDiscount) {
                discountType = BillItem.MEMBER_DISCOUNT_TYPE;
                discountName = discount.getName() + ((MemberLevelDiscount) discount).getMemberDiscount().getMemberDiscount() + "%";
            } else if (discount instanceof MemberCouponDiscount) {
                discountType = BillItem.COUPON_DISCOUNT_TYPE;
            }else if (discount instanceof MemberWalletCouponDiscount) {
                discountType = BillItem.COUPON_DISCOUNT_TYPE;
            }
            DiscountItem discountItem = new DiscountItem(discountName, discount.getDiscountMoney(), discount.getStatus(), discountType);
            discountItem.setDiscount(discount);
            billItemList.add(discountItem);
        }
    }

    /**
     * 獲取普通折扣列表
     *
     * @return
     */
    public List<NomalDiscount> getNomalDiscoutByMultyDiscountList() {
        List<NomalDiscount> nomalDiscountList = new ArrayList<>();
        for (MultyDiscount multyDiscount : getMultyDiscountList()) {
            if (multyDiscount instanceof NomalDiscount) {
                nomalDiscountList.add((NomalDiscount) multyDiscount);
            }
        }
        return nomalDiscountList;
    }

    /**
     * 獲取會員優惠券列表
     *
     * @return
     */
    public List<MemberWalletCoupon> getWalletCouponsByMultyDiscountList() {
        List<MemberWalletCoupon> walletCouponList = new ArrayList<>();
        for (MultyDiscount multyDiscount : getMultyDiscountList()) {
            if (multyDiscount instanceof MemberWalletCouponDiscount) {
                MemberWalletCouponDiscount walletCouponDiscount = (MemberWalletCouponDiscount) multyDiscount;
                walletCouponList.add(walletCouponDiscount.getWalletCoupon());
            }
        }
        return walletCouponList;
    }

    public List<MultyDiscount> getMultyDiscountList() {
        if (multyDiscountList == null) {
            multyDiscountList = new ArrayList<>();
        }
        return multyDiscountList;
    }

    public static void main(String[] args) {

        MultyDiscount multyDiscounts = null;
        ShoppingCart shoppingCart = new ShoppingCart();

        Discount discount = new Discount();
        discount.setRemark("9折");
        discount.setType(1);
        discount.setDiscountValue(10);
        multyDiscounts = shoppingCart.addNomalDiscountToLinked(multyDiscounts, discount, 0);
        shoppingCart.addMultyDiscount(multyDiscounts);

//        CouponDiscountBean couponDiscountBean = new CouponDiscountBean();
//        couponDiscountBean.setCouponTypeName1("魚屋立減50元券");
//        couponDiscountBean.setAmount(50);
//        couponDiscountBean.setCouponType((byte) 2);
//        multyDiscounts = shoppingCart.addMemberWalletCouponDiscountToLinked(multyDiscounts, couponDiscountBean, 0);
//        shoppingCart.addMultyDiscount(multyDiscounts);

        MemberInfo memberInfo2 = new MemberInfo();
        memberInfo2.setMemberName("白金會員20%");
        memberInfo2.setMemberDiscount(20);
        multyDiscounts = shoppingCart.addMemberLevelDiscountToLinked(multyDiscounts, memberInfo2, 0);
        shoppingCart.addMultyDiscount(multyDiscounts);

        double discountAfterMoney = shoppingCart.calculateLinkedDiscounts(200);

        System.out.println("折扣後的金額：" + discountAfterMoney);
    }

    /**
     * 具體支付類需要實現的方法
     */
    public void pay(double money) {

    }

    /**
     * 計算賬單前先重置
     */
    public void resetBeforeBillCalculation() {
        initialization(true);
    }

    public void initialization(boolean reset) {
        if (!reset) {
            if (orderCommodityList != null) {
                orderCommodityList.clear();
            }
            if (multyDiscountList != null) {
                multyDiscountList.clear();
            }
        }
        if (billItemList != null) {
            billItemList.clear();
        }
        serviceCharge = null;
        rounding = null;
        wholeAmount = 0.0;
        totalAmount = 0.0;
    }


}
