package com.platform.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.platform.annotation.IgnoreAuth;
import com.platform.annotation.LoginUser;
import com.platform.cache.J2CacheUtils;
import com.platform.entity.*;
import com.platform.enums.ResultCodeEnum;
import com.platform.exception.CommonBaseException;
import com.platform.service.*;
import com.platform.util.ApiBaseAction;

import com.qiniu.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

import static com.platform.interceptor.AuthorizationInterceptor.LOGIN_TOKEN_KEY;

/**
 * 作者: @author Harmon <br>
 * 时间: 2017-08-11 08:32<br>
 * @gitee https://gitee.com/fuyang_lipengjun/platform
 * 描述: ApiIndexController <br>
 */
@Api(tags = "购物车")
@RestController
@RequestMapping("/api/cart")
@Slf4j
public class ApiCartController extends ApiBaseAction {
    @Autowired
    private ApiCartService cartService;
    @Autowired
    private ApiGoodsService goodsService;
    @Autowired
    private ApiProductService productService;
    @Autowired
    private ApiGoodsSpecificationService goodsSpecificationService;
    @Autowired
    private ApiAddressService addressService;
    @Autowired
    private ApiCouponService apiCouponService;

    @Autowired
    private ApiUserCouponService apiUserCouponService;

    /**
     * 获取购物车中的数据
     */
    @ApiOperation(value = "获取购物车中的数据")
    @PostMapping("getCart")
    @Transactional(rollbackFor = Exception.class)
    public Object getCart(@LoginUser UserVo loginUser) {
        Map<String, Object> resultObj = new HashMap();
        //查询列表数据
        Map param = new HashMap();
        param.put("user_id", loginUser.getUserId());
        List<CartVo> cartList = cartService.queryList(param);
        //获取购物车统计信息
        Integer goodsCount = 0;
        BigDecimal goodsAmount = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_UP);
        Integer checkedGoodsCount = 0;
        BigDecimal checkedGoodsAmount = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_UP);
        for (CartVo cartItem : cartList) {
            goodsCount += cartItem.getNumber();
            goodsAmount = goodsAmount.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            if (null != cartItem.getChecked() && 1 == cartItem.getChecked()) {
                checkedGoodsCount += cartItem.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            }
            //这里还会去修改商品的价格
            updateGoodsPrice(cartItem);
        }

        resultObj.put("cartList", cartList);
        Map<String, Object> cartTotal = new HashMap();
        cartTotal.put("goodsCount", goodsCount);
        cartTotal.put("goodsAmount", goodsAmount);
        cartTotal.put("checkedGoodsCount", checkedGoodsCount);
        cartTotal.put("checkedGoodsAmount", checkedGoodsAmount);
        resultObj.put("cartTotal", cartTotal);
        return resultObj;
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateGoodsPrice(CartVo cartVo){
        if(null == cartVo.getGoods_id()){
            return;
        }
        GoodsVo dbGoods = goodsService.queryObject(cartVo.getGoods_id());
        if(null == dbGoods){
            return;
        }
        boolean needUpdateCart = false;
        if(null != dbGoods.getRetail_price() && null == cartVo.getRetail_price()){
            needUpdateCart = true;
            cartVo.setRetail_price(dbGoods.getRetail_price());
        }

        if(null != dbGoods.getMarket_price() && null == cartVo.getMarket_price()){
            needUpdateCart = true;
            cartVo.setMarket_price(dbGoods.getMarket_price());
        }

        if(needUpdateCart){
            log.info("需要修改购物车的商品价格");
            cartService.update(cartVo);
        }
    }

    /**
     * 获取购物车信息，所有对购物车的增删改操作，都要重新返回购物车的信息
     */
    @ApiOperation(value = "获取购物车信息")
    @PostMapping("index")
    public Object index() {
        Map<String, Object> resultObj = new HashMap();
        //查询列表数据
        Map param = new HashMap();
        param.put("user_id", getUserId());
        List<CartVo> cartList = cartService.queryList(param);
        //获取购物车统计信息
        Integer goodsCount = 0;
        BigDecimal goodsAmount = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_UP);
        Integer checkedGoodsCount = 0;
        BigDecimal checkedGoodsAmount = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_UP);
        for (CartVo cartItem : cartList) {
            goodsCount += cartItem.getNumber();
            goodsAmount = goodsAmount.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            if (null != cartItem.getChecked() && 1 == cartItem.getChecked()) {
                checkedGoodsCount += cartItem.getNumber();
                checkedGoodsAmount = checkedGoodsAmount.add(cartItem.getRetail_price().multiply(new BigDecimal(cartItem.getNumber())));
            }
            //这里还会去修改商品的价格
            updateGoodsPrice(cartItem);
        }

        resultObj.put("cartList", cartList);
        Map<String, Object> cartTotal = new HashMap();
        cartTotal.put("goodsCount", goodsCount);
        cartTotal.put("goodsAmount", goodsAmount);
        cartTotal.put("checkedGoodsCount", checkedGoodsCount);
        cartTotal.put("checkedGoodsAmount", checkedGoodsAmount);
        resultObj.put("cartTotal", cartTotal);
        return toResponsSuccess(resultObj);
    }

    private String[] getSpecificationIdsArray(String ids) {
        String[] idsArray = null;
        if (org.apache.commons.lang.StringUtils.isNotEmpty(ids)) {
            String[] tempArray = ids.split("_");
            if (null != tempArray && tempArray.length > 0) {
                idsArray = tempArray;
            }
        }
        return idsArray;
    }

    /**
     * 添加商品到购物车
     */
    @ApiOperation(value = "添加商品到购物车")
    @PostMapping("add")
    public Object add(@LoginUser UserVo loginUser) {
        JSONObject jsonParam = getJsonRequest();
        Integer goodsId = jsonParam.getInteger("goodsId");
        Integer productId = jsonParam.getInteger("productId");
        Integer number = jsonParam.getInteger("number");
        String goodsSpecificationIds = jsonParam.getString("goodsSpecificationIds");

        log.info("添加到购物车的商品:[{}]，数量[{}],产品ID[{}]" , goodsId , number , productId);
        //判断商品是否可以购买
        GoodsVo goodsInfo = goodsService.queryObject(goodsId);
        if (null == goodsInfo || goodsInfo.getIs_delete() == 1 || goodsInfo.getIs_on_sale() != 1) {
            return this.toResponsObject(400, "商品已下架", "");
        }
        //取得规格的信息,判断规格库存
        ProductVo productInfo = productService.queryObject(productId);
        if(null == number){
            number = 0;
        }
        log.info("当前的规则id=[{}]，库存数量={} , 需要购买的数据量=[{}]" , productId , null!=productInfo ? productInfo.getGoods_number() : 0,number);
        if (null == productInfo || null == productInfo.getGoods_number() || productInfo.getGoods_number().compareTo(number) < 0) {
            return this.toResponsObject(400, "库存不足", "");
        }

        //判断购物车中是否存在此规格商品
        Map cartParam = new HashMap();
        cartParam.put("goods_id", goodsId);
        cartParam.put("product_id", productId);
        cartParam.put("user_id", loginUser.getUserId());
        cartParam.put("goods_specification_ids", goodsSpecificationIds);
        List<CartVo> cartInfoList = cartService.queryList(cartParam);
        CartVo cartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
        if (null == cartInfo) {
            //添加操作
            //添加规格名和值
            String[] goodsSepcifitionValue = null;
            String listPicUrl = "";
            if (null != productInfo.getGoods_specification_ids() && productInfo.getGoods_specification_ids().length() > 0) {
                Map specificationParam = new HashMap();
                String[] idsArray = getSpecificationIdsArray(goodsSpecificationIds);
                specificationParam.put("ids", idsArray);
                specificationParam.put("goods_id", goodsId);
                List<GoodsSpecificationVo> specificationEntities = goodsSpecificationService.queryList(specificationParam);
                goodsSepcifitionValue = new String[specificationEntities.size()];
                for (int i = 0; i < specificationEntities.size(); i++) {
                    goodsSepcifitionValue[i] = specificationEntities.get(i).getValue();
                    listPicUrl = specificationEntities.get(i).getPic_url();
                }
            }
            cartInfo = new CartVo();
            if("".equals(listPicUrl)){
                listPicUrl = goodsInfo.getList_pic_url();
            }

            cartInfo.setGoods_id(goodsId);
            cartInfo.setProduct_id(productId);
            cartInfo.setGoods_sn(productInfo.getGoods_sn());
            cartInfo.setGoods_name(goodsInfo.getName());
            cartInfo.setList_pic_url(listPicUrl);
            cartInfo.setNumber(number);
            cartInfo.setSession_id("1");
            cartInfo.setUser_id(loginUser.getUserId());
            cartInfo.setRetail_price(productInfo.getRetail_price());
            cartInfo.setMarket_price(productInfo.getMarket_price());
            if (null != goodsSepcifitionValue) {
                cartInfo.setGoods_specifition_name_value(StringUtils.join(goodsSepcifitionValue, ";"));
            }
            cartInfo.setGoods_specifition_ids(goodsSpecificationIds);
            cartInfo.setChecked(0);
            //这里还有很多修改价格的逻辑!!!狗血的写法
            cartService.save(cartInfo);
        } else {
            //如果已经存在购物车中，则数量增加
            if (productInfo.getGoods_number() < (number + cartInfo.getNumber())) {
                return this.toResponsObject(400, "库存不足", "");
            }
            cartInfo.setNumber(cartInfo.getNumber() + number);
            cartService.update(cartInfo);
        }
        //这里返回值从新捞取了整个购物车的商品数据
        return toResponsSuccess(getCart(loginUser));
    }

    /**
     * 减少商品到购物车
     */
    @ApiOperation(value = "减少商品到购物车")
    @PostMapping("minus")
    public Object minus(@LoginUser UserVo loginUser) {
        JSONObject jsonParam = getJsonRequest();
        Integer goodsId = jsonParam.getInteger("goodsId");
        Integer productId = jsonParam.getInteger("productId");
        Integer number = jsonParam.getInteger("number");
        //判断购物车中是否存在此规格商品
        Map cartParam = new HashMap();
        cartParam.put("goods_id", goodsId);
        cartParam.put("product_id", productId);
        cartParam.put("user_id", loginUser.getUserId());
        List<CartVo> cartInfoList = cartService.queryList(cartParam);
        CartVo cartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
        int cart_num = 0;
        if (null != cartInfo) {
            if (cartInfo.getNumber() > number) {
                cartInfo.setNumber(cartInfo.getNumber() - number);
                cartService.update(cartInfo);
                cart_num = cartInfo.getNumber();
            } else if (cartInfo.getNumber() == 1) {
                cartService.delete(cartInfo.getId());
                cart_num = 0;
            }
        }
        return toResponsSuccess(cart_num);
    }

    /**
     * 更新指定的购物车信息
     */
    @ApiOperation(value = "更新指定的购物车信息")
    @PostMapping("update")
    public Object update(@LoginUser UserVo loginUser, @RequestParam Integer goodsId,
                         @RequestParam Integer productId, @RequestParam Integer number,
                         @RequestParam Integer id) {
        JSONObject jsonParam = getJsonRequest();
//        Integer goodsId = jsonParam.getInteger("goodsId");
//        Integer productId = jsonParam.getInteger("productId");
//        Integer number = jsonParam.getInteger("number");
//        Integer id = jsonParam.getInteger("id");
        //取得规格的信息,判断规格库存
        ProductVo productInfo = productService.queryObject(productId);
        if (null == productInfo || productInfo.getGoods_number() < number) {
            return this.toResponsObject(400, "库存不足", "");
        }
        //判断是否已经存在product_id购物车商品
        CartVo cartInfo = cartService.queryObject(id);
        //只是更新number
        if (cartInfo.getProduct_id().equals(productId)) {
            cartInfo.setNumber(number);
            cartService.update(cartInfo);
            return toResponsSuccess(getCart(loginUser));
        }

        Map cartParam = new HashMap();
        cartParam.put("goodsId", goodsId);
        cartParam.put("productId", productId);
        List<CartVo> cartInfoList = cartService.queryList(cartParam);
        CartVo newcartInfo = null != cartInfoList && cartInfoList.size() > 0 ? cartInfoList.get(0) : null;
        if (null == newcartInfo) {
            //添加操作
            //添加规格名和值
            String[] goodsSepcifitionValue = null;
            if (null != productInfo.getGoods_specification_ids()) {
                Map specificationParam = new HashMap();
                specificationParam.put("ids", productInfo.getGoods_specification_ids());
                specificationParam.put("goodsId", goodsId);
                List<GoodsSpecificationVo> specificationEntities = goodsSpecificationService.queryList(specificationParam);
                goodsSepcifitionValue = new String[specificationEntities.size()];
                for (int i = 0; i < specificationEntities.size(); i++) {
                    goodsSepcifitionValue[i] = specificationEntities.get(i).getValue();
                }
            }
            cartInfo.setProduct_id(productId);
            cartInfo.setGoods_sn(productInfo.getGoods_sn());
            cartInfo.setNumber(number);
            cartInfo.setRetail_price(productInfo.getRetail_price());
            cartInfo.setMarket_price(productInfo.getRetail_price());
            if (null != goodsSepcifitionValue) {
                cartInfo.setGoods_specifition_name_value(StringUtils.join(goodsSepcifitionValue, ";"));
            }
            cartInfo.setGoods_specifition_ids(productInfo.getGoods_specification_ids());
            cartService.update(cartInfo);
        } else {
            //合并购物车已有的product信息，删除已有的数据
            Integer newNumber = number + newcartInfo.getNumber();
            if (null == productInfo || productInfo.getGoods_number() < newNumber) {
                return this.toResponsObject(400, "库存不足", "");
            }
            cartService.delete(newcartInfo.getId());
            //添加规格名和值
            String[] goodsSepcifitionValue = null;
            if (null != productInfo.getGoods_specification_ids()) {
                Map specificationParam = new HashMap();
                specificationParam.put("ids", productInfo.getGoods_specification_ids());
                specificationParam.put("goodsId", goodsId);
                List<GoodsSpecificationVo> specificationEntities = goodsSpecificationService.queryList(specificationParam);
                goodsSepcifitionValue = new String[specificationEntities.size()];
                for (int i = 0; i < specificationEntities.size(); i++) {
                    goodsSepcifitionValue[i] = specificationEntities.get(i).getValue();
                }
            }
            cartInfo.setProduct_id(productId);
            cartInfo.setGoods_sn(productInfo.getGoods_sn());
            cartInfo.setNumber(number);
            cartInfo.setRetail_price(productInfo.getRetail_price());
            cartInfo.setMarket_price(productInfo.getRetail_price());
            if (null != goodsSepcifitionValue) {
                cartInfo.setGoods_specifition_name_value(StringUtils.join(goodsSepcifitionValue, ";"));
            }
            cartInfo.setGoods_specifition_ids(productInfo.getGoods_specification_ids());
            cartService.update(cartInfo);
        }
        return toResponsSuccess(getCart(loginUser));
    }

    /**
     * 是否选择商品，如果已经选择，则取消选择，批量操作
     */
    @ApiOperation(value = "是否选择商品")
    @PostMapping("checked")
    public Object checked(@LoginUser UserVo loginUser) {
        JSONObject jsonParam = getJsonRequest();
        String productIds = jsonParam.getString("productIds");
        Integer isChecked = jsonParam.getInteger("isChecked");
        if (StringUtils.isNullOrEmpty(productIds)) {
            return this.toResponsFail("删除出错");
        }
        String[] productIdArray = productIds.split(",");
        cartService.updateCheck(productIdArray, isChecked, loginUser.getUserId());
        return toResponsSuccess(getCart(loginUser));
    }

    //删除选中的购物车商品，批量删除
    @ApiOperation(value = "删除商品")
    @PostMapping("delete")
    public Object delete(@LoginUser UserVo loginUser) {
        Long userId = loginUser.getUserId();

        JSONObject jsonObject = getJsonRequest();
        String productIds = jsonObject.getString("productIds");

        if (StringUtils.isNullOrEmpty(productIds)) {
            return toResponsFail("删除出错");
        }
        String[] productIdsArray = productIds.split(",");
        cartService.deleteByUserAndProductIds(userId, productIdsArray);

        return toResponsSuccess(getCart(loginUser));
    }

    //  获取购物车商品的总件件数
    @ApiOperation(value = "获取购物车商品的总件件数")
    @IgnoreAuth
    @PostMapping("goodscount")
    public Object goodscount() {
        Map<String, Object> resultObj = new HashMap();
        Map<String, Object> cartTotal = new HashMap();
        cartTotal.put("goodsCount", 0);
        //
        resultObj.put("cartTotal", cartTotal);
        //从header中获取token
        String token = request.getHeader(LOGIN_TOKEN_KEY);
        //如果header中不存在token，则从参数中获取token
        if (org.apache.commons.lang.StringUtils.isBlank(token)) {
            token = request.getParameter(LOGIN_TOKEN_KEY);
        }

        //token为空
        if (org.apache.commons.lang.StringUtils.isBlank(token)) {
            return toResponsSuccess(resultObj);
        }
        //查询token信息
        TokenEntity tokenEntity = tokenService.queryByToken(token);
        if (tokenEntity == null || tokenEntity.getExpireTime().getTime() < System.currentTimeMillis()) {
            return toResponsSuccess(resultObj);
        }

        if (null == tokenEntity.getUserId()) {
            return toResponsSuccess(resultObj);
        }

        //查询列表数据
        Map param = new HashMap();
        param.put("user_id", tokenEntity.getUserId());
        List<CartVo> cartList = cartService.queryList(param);
        //获取购物车统计信息
        Integer goodsCount = 0;
        for (CartVo cartItem : cartList) {
            goodsCount += cartItem.getNumber();
        }
        resultObj.put("cartList", cartList);
        //
        cartTotal = new HashMap();
        cartTotal.put("goodsCount", goodsCount);
        //
        resultObj.put("cartTotal", cartTotal);
        return toResponsSuccess(resultObj);
    }

    /**
     * 订单提交前的检验和填写相关订单信息
     */
    @ApiOperation(value = "订单提交前的检验和填写相关订单信息")
    @PostMapping("checkout")
    @Transactional(rollbackFor = Exception.class)
    public Object checkout(@LoginUser UserVo loginUser, Integer couponId, @RequestParam(defaultValue = "cart") String type) {
        Map<String, Object> resultObj = new HashMap<>();

        //默认收货地址
        Map<String ,Object> param = new HashMap<>();
        param.put("user_id", loginUser.getUserId());
        List<AddressVo> addressEntities = addressService.queryList(param);

        if (null == addressEntities || addressEntities.size() == 0) {
            resultObj.put("checkedAddress", new AddressVo());
        } else {
            resultObj.put("checkedAddress", addressEntities.get(0));
            for(AddressVo vo : addressEntities){
                if(vo.getIs_default() == 1){
                    resultObj.put("checkedAddress", vo);
                    break;
                }
            }
        }
        // * 获取要购买的商品和总价
        List<CartVo> checkedGoodsList = new ArrayList<>();
        BigDecimal goodsTotalPrice = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_UP);
        if (type.equals("cart")) {
            Map<String, Object> cartData = (Map<String, Object>) this.getCart(loginUser);
            if(!CollectionUtils.isEmpty(cartData)){
                List<CartVo> cartDataList = (List<CartVo>) cartData.get("cartList");
                if(!CollectionUtils.isEmpty(cartDataList)){
                    for (CartVo cartEntity : cartDataList) {
                        if (cartEntity.getChecked().compareTo(1) == 0) {
                            checkedGoodsList.add(cartEntity);
                        }
                    }
                }
                Map<String , Object> cartTotalMap = (Map<String, Object>) cartData.get("cartTotal");
                if(!CollectionUtils.isEmpty(cartTotalMap) && cartTotalMap.containsKey("checkedGoodsAmount")){
                    goodsTotalPrice = (BigDecimal) cartTotalMap.get("checkedGoodsAmount");
                }
            }

        } else { // 是直接购买的
            BuyGoodsVo goodsVO = (BuyGoodsVo) J2CacheUtils.get(J2CacheUtils.SHOP_CACHE_NAME, "goods" + loginUser.getUserId() + "");
            if(null == goodsVO){
                log.error("购买的商品不存在");
                Result.failure("商品不存在");
            }
//            log.info("从缓存中获取到的商品为:{}" , JSON.toJSONString(goodsVO));
            ProductVo productInfo = productService.queryObject(goodsVO.getProductId());
            //计算订单的费用
            //商品总价
            if(null == goodsVO.getNumber()){
                log.error("购买的商品的数量不能为空");
                return Result.failure("购买的商品的数量不能为空");
            }
            goodsTotalPrice = productInfo.getRetail_price().multiply(new BigDecimal(goodsVO.getNumber()));

            CartVo cartVo = new CartVo();
            cartVo.setGoods_id(goodsVO.getGoodsId());
            cartVo.setGoods_name(productInfo.getGoods_name());
            cartVo.setNumber(goodsVO.getNumber());
            cartVo.setRetail_price(productInfo.getRetail_price());
            cartVo.setList_pic_url(productInfo.getList_pic_url());
            cartVo.setGoods_specifition_ids(goodsVO.getGoodsSpecifitionIds());
            checkedGoodsList.add(cartVo);
        }
         log.info("计算得到总价为:{}" , goodsTotalPrice);
         log.info("购物车商品列表为:{}" , JSON.toJSONString(checkedGoodsList));
        //根据收货地址计算运费
        BigDecimal freightPrice = new BigDecimal(0.00);
        if(goodsTotalPrice.intValue() < 99){
            //TODO:需要修改回来10块钱
//            freightPrice = new BigDecimal(0.01);
        }

        //订单的总价
        BigDecimal orderTotalPrice = goodsTotalPrice.add(freightPrice);

        log.info("带上邮费的总价为:{}" , orderTotalPrice);
        //获取可用的优惠券信息
        BigDecimal couponPrice = BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_DOWN);
        Map<String , Object> requestParam = new HashMap<>();
        requestParam.put("user_id" , loginUser.getUserId());
        //只获取可用的优惠券(用户优惠券使用状态，对应表 nideshop_user_coupon的coupon_status字段)
        //用户使用状态 1. 可用 2. 已用 3. 过期，4.作废
        requestParam.put("coupon_status" , 1);
        List<CouponVo>  userAllCouponVoList = apiCouponService.queryUserCoupons(requestParam);
        if(CollectionUtils.isEmpty(userAllCouponVoList)){
            log.info("该用户下，可用的优惠券为空");
        }
        if(CollectionUtils.isEmpty(checkedGoodsList)){
            log.info("该用户下，购物车内勾选的商品列表为空");
        }
        Map<String , BigDecimal> goodsBrandPriceMap = classifyGoodsPriceByBrand(checkedGoodsList);
        if(CollectionUtils.isEmpty(goodsBrandPriceMap)){
            log.info("该用户下，分类的价格为空");
        }
        List<CouponVo> userTotallyUseCouponList = getUserCanUseCouponList(userAllCouponVoList , goodsBrandPriceMap);
        List<Integer> totallyCouponIdList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(userTotallyUseCouponList)){
            for (CouponVo couponVo : userTotallyUseCouponList){
                totallyCouponIdList.add(couponVo.getId());
                couponPrice = couponPrice.add(couponVo.getTypeMoney());
            }
        }
        BigDecimal actualPrice = orderTotalPrice.subtract(couponPrice);  //减去其它支付的金额后，要实际支付的金额
        log.info("扣减优惠券的总价为:{}" , actualPrice);
        resultObj.put("freightPrice", freightPrice);

        resultObj.put("couponPrice", couponPrice);
        resultObj.put("checkedGoodsList", checkedGoodsList);
        resultObj.put("goodsTotalPrice", goodsTotalPrice);
        resultObj.put("orderTotalPrice", orderTotalPrice);
        resultObj.put("actualPrice", actualPrice);
        if(!CollectionUtils.isEmpty(totallyCouponIdList)){
            resultObj.put("couponIdList", totallyCouponIdList);
        }
        log.info("返回的价钱信息为:{}", JSON.toJSONString(resultObj));
        return toResponsSuccess(resultObj);
    }

    private Map<String , BigDecimal> classifyGoodsPriceByBrand(List<CartVo> cartList){
        Map<String , BigDecimal> result = new HashMap<>();
        if(!CollectionUtils.isEmpty(cartList)){
            for(CartVo cartVo : cartList){
                GoodsVo goodsVo = goodsService.queryObject(cartVo.getGoods_id());
                if(null != goodsVo){
                    if(result.containsKey(goodsVo.getBrand_id().toString())){
                        //存在，则累加
                        BigDecimal tmpPrice = result.get(goodsVo.getBrand_id().toString());
                        if (null != tmpPrice){
                            tmpPrice = tmpPrice.add(goodsVo.getRetail_price());
                            result.put(goodsVo.getBrand_id().toString() , tmpPrice);
                        }
                    }else{
                        //不存在，则新增
                        result.put(goodsVo.getBrand_id().toString() , cartVo.getRetail_price().multiply(new BigDecimal(cartVo.getNumber())));
                    }
                }else{
                    log.info("获取不到商品name = [{}], id = [{}]跳过" , cartVo.getGoods_name() , cartVo.getGoods_id());
                }
            }
        }else{
            log.info("购物车商品列表为空，无法计算分类价格");
        }
        log.info("获取到的价格分类为:{}", JSON.toJSONString(result));
        return result;
    }

    /**
     *
     * 获取用户所有可用的优惠券
     * 支持多张优惠券叠加
     *
     * */
    private List<CouponVo> getUserCanUseCouponList(List<CouponVo> userAllValidCouponList ,Map<String , BigDecimal> goodsBrandPriceMap){
        List<CouponVo> usedCouponList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(userAllValidCouponList) && !CollectionUtils.isEmpty(goodsBrandPriceMap)){
            Map<String , List<CouponVo>> classifyCoupons = classifyCouponByBrand(userAllValidCouponList);
            if(CollectionUtils.isEmpty(classifyCoupons)){
                log.error("分类后得到的优惠券Map为空，无法叠加使用优惠券计算价格");
                return null;
            }
            for(Map.Entry<String , BigDecimal> entry : goodsBrandPriceMap.entrySet()){
                List<CouponVo> brandCouponList = classifyCoupons.get(entry.getKey());
                if(!CollectionUtils.isEmpty(brandCouponList)){
                    log.info("当前用户，在品牌:{}下面可用优惠券数量为:{}" , entry.getKey() , brandCouponList.size());
                    CouponVo tmpBest = getBestOfBrandCoupons(brandCouponList , entry.getValue());
                    if(null != tmpBest){
                        usedCouponList.add(tmpBest);
                        log.info("当前用户在品牌[{}]下最优的优惠券金额为:{},当前需要支付的金额为:{}" , tmpBest.getBrandId() ,
                                tmpBest.getTypeMoney(),entry.getValue());
                    }else{
                        log.info("当前用户在，品牌:{}下面无最适合的优惠券可使用，当前需要支付的金额为:{}" , entry.getKey() , entry.getValue());
                    }
                }
            }
        }else{
            log.info("价格分类或者优惠券分类有其一为空，无法计算最优优惠券");
        }
        return usedCouponList;
    }

    /**
     * 根据品牌，分类当前用户下面各个品牌可用的优惠券
     * */
    private Map<String , List<CouponVo>> classifyCouponByBrand(List<CouponVo> couponVoList){
        Map<String , List<CouponVo>> result = new HashMap<>();
        if(!CollectionUtils.isEmpty(couponVoList)){
            for(CouponVo couponVo : couponVoList){
                if(null == couponVo.getBrandId()){
                    log.warn("优惠券[{}]的品牌id为空，无法分类改优惠券" , couponVo.getId());
                    continue;
                }
                String brandIdStr = couponVo.getBrandId().toString();
                if(result.containsKey(brandIdStr)){
                    //已经存在，则累加到链表后面
                    List<CouponVo> thisList = result.get(brandIdStr);
                    if(null == thisList){
                        log.warn("获取map中的品牌[{}]的优惠券失败，无法累加该品牌下面的优惠券" , brandIdStr);
                    }else{
                        thisList.add(couponVo);
                        result.put(brandIdStr , thisList);
                    }
                }else{
                    //不存在，则新增
                    List<CouponVo> newList = new ArrayList<>();
                    newList.add(couponVo);
                    result.put(couponVo.getBrandId().toString() , newList);
                }
            }
        }
        log.info("用户优惠券分类如下:{}" , JSON.toJSONString(result));
        return result;
    }

    /**
     * 计算某个用户在某个品牌下所有可用的优惠券中
     * 优惠金额最大的一个优惠券
     * */
    private CouponVo getBestOfBrandCoupons(List<CouponVo> couponVoList , BigDecimal orderTotalPrice){
        if(!CollectionUtils.isEmpty(couponVoList)){
            int useCouponId = -1;
            CouponVo bestCoupon = null;
            BigDecimal maxCoupon =  BigDecimal.ZERO.setScale(2 , RoundingMode.HALF_DOWN);
            for (CouponVo couponVo : couponVoList){
                log.info("该用户名下可用优惠券数量为:{}，当前优惠券Id={}，可优惠金额={}" , couponVoList.size() , couponVo.getId() , couponVo.getTypeMoney());
                //优惠券状态为2才是有效状态(对应表: nideshop_coupon的coupon_status字段)
                //优惠券状态 1 未生效 2 生效中 3 已失效 4 停止发放
                if(null != couponVo.getCouponStatus() && couponVo.getCouponStatus().compareTo(2) == 0){
                    log.info("可以用优惠券[{}]最低消费金额为:{}，当前消费金额为:{}" , couponVo.getName() , couponVo.getMinGoodsAmount() , orderTotalPrice);
                    if(null != couponVo.getMinGoodsAmount() && couponVo.getMinGoodsAmount().compareTo(orderTotalPrice) > 0){
                        //未达到使用优惠券的条件,则跳过
                        log.info("当前订单金额为:{}，优惠券[{}]的最小消费金额为:{}，不符合使用优惠券的条件，跳过",orderTotalPrice , couponVo.getId() , couponVo.getMinGoodsAmount());
                        continue;
                    }else{
                        if(null != couponVo.getTypeMoney() && couponVo.getTypeMoney().compareTo(maxCoupon) > 0){
                            log.info("当前的最大优惠金额为:{}，将替换为:{}" , maxCoupon , couponVo.getTypeMoney());
                            maxCoupon = couponVo.getTypeMoney();
                            bestCoupon = couponVo;
                        }else{
                            log.info("当前最大优惠金额为:{}" , maxCoupon);
                        }
                    }
                }else{
                    log.info("优惠券[{}]状态为不可用:{}" ,couponVo.getId() , couponVo.getCouponStatus());
                }
            }
            if(null != bestCoupon){
                log.info("使用了优惠券，将进行金额扣减金额:{}，使用的优惠券ID={}" , bestCoupon.getTypeMoney() , useCouponId);
            }else{
                log.info("没有合适的优惠券使用");
            }
            return bestCoupon;
        }else{
            log.info("优惠券列表为空，无法获取最优优惠券");
            return null;
        }
    }

    /**
     * 选择优惠券列表
     */
    @ApiOperation(value = "选择优惠券列表")
    @PostMapping("checkedCouponList")
    public Object checkedCouponList(@LoginUser UserVo loginUser) {
        //
        Map param = new HashMap();
        param.put("user_id", loginUser.getUserId());
        List<CouponVo> couponVos = apiCouponService.queryUserCouponList(param);
        if (null != couponVos && couponVos.size() > 0) {
            // 获取要购买的商品
            Map<String, Object> cartData = (Map<String, Object>) this.getCart(loginUser);
            List<CartVo> checkedGoodsList = new ArrayList();
            List<Integer> checkedGoodsIds = new ArrayList();
            for (CartVo cartEntity : (List<CartVo>) cartData.get("cartList")) {
                if (cartEntity.getChecked() == 1) {
                    checkedGoodsList.add(cartEntity);
                    checkedGoodsIds.add(cartEntity.getId());
                }
            }
            // 计算订单的费用
            BigDecimal goodsTotalPrice = (BigDecimal) ((HashMap) cartData.get("cartTotal")).get("checkedGoodsAmount");  //商品总价
            // 如果没有用户优惠券直接返回新用户优惠券
            for (CouponVo couponVo : couponVos) {
                if (couponVo.getMinAmount().compareTo(goodsTotalPrice) <= 0) {
                    couponVo.setEnabled(1);
                }
            }
        }
        return toResponsSuccess(couponVos);
    }
}
