/*
 * Copyright (c) 2018-2999 楠炲灝绐炴禍姘辫儗娣団剝浼呯粔鎴炲Η閺堝妾洪崗顒€寰?All rights reserved.
 *
 * https://www.gz-yami.com/
 *
 * 閺堫亞绮￠崗浣筋啅閿涘奔绗夐崣顖氫粵閸熷棔绗熼悽銊┾偓鏃撶磼
 *
 * 閻楀牊娼堥幍鈧張澶涚礉娓氬灚娼堣箛鍛敀閿?
 */

package com.yami.shop.api.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.excel.util.StringUtils;
import com.google.common.collect.Lists;
import com.yami.shop.bean.app.dto.*;
import com.yami.shop.bean.app.param.*;
import com.yami.shop.bean.event.ConfirmOrderEvent;
import com.yami.shop.bean.event.PlatformConfirmOrderEvent;
import com.yami.shop.bean.event.ScoreConfirmOrderEvent;
import com.yami.shop.bean.event.SubmitSeckillOrderEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.common.exception.GlobalException;
import com.yami.shop.common.util.Arith;
import com.yami.shop.dao.PointsRecordMapper;
import com.yami.shop.dao.ShopSkuMapper;
import com.yami.shop.security.api.util.SecurityUtils;
import com.yami.shop.service.*;
import com.yami.shop.service.hb.IHBOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/p/order")
@Api(tags = "Order API")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private MapperFacade mapperFacade;
    @Autowired
    private SkuService skuService;
    @Autowired
    private ProductService productService;
    @Autowired
    private UserAddrService userAddrService;
    @Autowired
    private BasketService basketService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private UserAddrOrderService userAddrOrderService;
    @Autowired
    private IQnhService qnhService;
    @Autowired
    private PointsRecordMapper pointsRecordMapper;

    @Autowired
    private IHBOrderService hbOrderService;
    @Autowired
    private ShopSkuMapper shopSkuMapper;
    @Autowired
    private SysConfigService sysConfigService;

    /**
     * 瀵湱鐛ュ鈧崗鎶藉帳缂冪敿ey
     */
    private static final String POPUP_SWITCH = "POPUP_SWITCH";

    /**
     * 閻㈢喐鍨氱拋銏犲礋
     */
    @PostMapping("/confirm")
    @ApiOperation(value = "Confirm order", notes = "Build order confirmation data from cart items or direct-buy items")
    public ResponseEntity<ShopCartOrderMergerDto> confirm(@Valid @RequestBody OrderParam orderParam) {
        // 濡偓閺屻儱鑴婄粣妤€绱戦崗绛圭礉婵″倹鐏夊鈧崥顖氬灟閺嗗倸浠犳稉瀣礋
        String popupSwitch = sysConfigService.getValue(POPUP_SWITCH);
        if ("true".equalsIgnoreCase(popupSwitch)) {
            throw new GlobalException("Ordering is temporarily unavailable");
        }

        if (orderParam.getShopId() == null) {
//            orderParam.setShopId(1L);
            throw new GlobalException("Shop id is required");
        }
        String userId = SecurityUtils.getUser().getUserId();

        if (orderParam.getOrderItem() == null) {
            orderParam.getBasketIds().forEach(basketId -> {
                Basket byId = basketService.getById(basketId);
                Sku byIdss = skuService.getById(byId);
                ShopSku shopSku = shopSkuMapper.selectByShopAndSku(byIdss.getSkuId(), orderParam.getShopId());
                if (shopSku.getShopSkuStocks() == null || shopSku.getShopSkuStocks() == 0) {
                    throw new GlobalException("Product[" + byIdss.getSkuName() + "] is sold out");
                }
                if (shopSku.getShopSkuStocks() < byId.getBasketCount()) {
                    throw new GlobalException("Product[" + byIdss.getSkuName() + "] has insufficient stock");
                }

            });
        } else {
            ShopSku shopSku = shopSkuMapper.selectByShopAndSku(orderParam.getOrderItem().getSkuId(), orderParam.getShopId());
            if (shopSku.getShopSkuStocks() == null || shopSku.getShopSkuStocks() == 0) {
                throw new GlobalException("Product[" + shopSku.getSkuName() + "] is sold out");
            }
            if (shopSku.getShopSkuStocks() < orderParam.getOrderItem().getProdCount()) {
                throw new GlobalException("Product[" + shopSku.getSkuName() + "] has insufficient stock");
            }
        }

        UserAddr userAddr = userAddrService.getUserAddrByUserId(orderParam.getAddrId(), userId);
        validateGuizhouAddress(userAddr);
        UserAddrDto userAddrDto = mapperFacade.map(userAddr, UserAddrDto.class);
        // 缂佸嫯顥婇懢宄板絿閻劍鍩涢幓鎰唉閻ㄥ嫯鍠橀悧鈺勬簠閸熷棗鎼фい?
        OrderItemParam orderItem = orderParam.getOrderItem();
        if (null != orderItem) {
            orderItem.setChannelId(orderParam.getChannelId());
        }

        System.out.println("orderParam.getBasketIds()" + orderParam.getBasketIds());
        System.out.println("orderItem" + orderItem);
        System.out.println("userId" + userId);
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartItemsByOrderItems(orderParam.getBasketIds(), orderItem, userId, orderParam.getChannelId());
        if (CollectionUtil.isEmpty(shopCartItems)) {
            throw new GlobalException("No valid cart items were found");
        }
        // 閺嶈宓佹惔妤呮懙缂佸嫯顥婄拹顓℃簠娑擃厾娈戦崯鍡楁惂娣団剝浼呴敍宀冪箲閸ョ偞鐦℃稉顏勭暗闁捐桨鑵戦惃鍕枠閻椻晞婧呴崯鍡楁惂娣団剝浼?
        List<ShopCartDto> shopCarts = basketService.getShopCarts(shopCartItems, 0L);

        Long point = pointsRecordMapper.statisticsPoint(userId, orderParam.getChannelId());
        double v = 0.0;
        // 鐏忓棜顩︽潻鏂挎礀缂佹瑥澧犵粩顖滄畱鐎瑰本鏆ｉ惃鍕吂閸楁洑淇婇幁?
        ShopCartOrderMergerDto shopCartOrderMergerDto = new ShopCartOrderMergerDto();
        shopCartOrderMergerDto.setUserAddr(userAddrDto);
        shopCartOrderMergerDto.setIsScorePay(orderParam.getIsScorePay());
        if (null != point) {
            v = ((double) point / 100);
            //閹崵娈戦崣顖滄暏缁夘垰鍨?
//        shopCartOrderMergerDto.setTotalAvailableScore(point);
        }

        // 閹碘偓閺堝绨甸柧铏规畱鐠併垹宕熸穱鈩冧紖
        List<ShopCartOrderDto> shopCartOrders = new ArrayList<>();

        double actualTotal = 0.0;
        double total = 0.0;
        int totalCount = 0;
        double allOrderReduce = 0.0;
        double totalTransfee = 0.0;
        double weight = 0.0;

        // 閹碘偓閺堝绨甸柧鐑樺閺堝娈戦崯鍡楁惂item
        List<ShopCartItemDto> allCartItem = new ArrayList<>();

//        List<CouponOrderDto> coupons = new ArrayList<>();
        for (ShopCartDto shopCart : shopCarts) {
            // 濮ｅ繋閲滄惔妤呮懙閻ㄥ嫯顓归崡鏇氫繆閹?
            ShopCartOrderDto shopCartOrder = new ShopCartOrderDto();
            shopCartOrder.setShopId(shopCart.getShopId());
            shopCartOrder.setShopName(shopCart.getShopName());

            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();
            // 鎼存鎽垫稉顓犳畱閹碘偓閺堝鏅㈤崫渚€銆嶆穱鈩冧紖
            List<ShopCartItemDto> shopAllShopCartItems = new ArrayList<>();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> discountShopCartItems = shopCartItemDiscount.getShopCartItems();
                shopAllShopCartItems.addAll(discountShopCartItems);
            }
            shopCartOrder.setShopCartItemDiscounts(shopCartItemDiscounts);
            allCartItem.addAll(shopAllShopCartItems);

            applicationContext.publishEvent(new ConfirmOrderEvent(shopCartOrder, orderParam, shopAllShopCartItems));

            total = Arith.add(total, shopCartOrder.getTotal());
            totalCount = totalCount + shopCartOrder.getTotalCount();
            allOrderReduce = Arith.add(allOrderReduce, shopCartOrder.getShopReduce());
            totalTransfee = Arith.add(totalTransfee, shopCartOrder.getTransfee());
            weight = Arith.add(weight, shopCartOrder.getTotalWeight());
            shopCartOrders.add(shopCartOrder);
        }
        shopCartOrderMergerDto.setDvyType(orderParam.getDvyType());

        //閺嶈宓佹禒閿嬬壐鏉╂稖顢戞惔妤呮懙閵嗕焦寮ч崙蹇嬧偓浣告櫌閸濅線銆嶉惃鍕幆閺嶇厧宕屾惔蹇旀惙娴?
        for (int n = 0; n < shopCartOrders.size(); n++) {
            shopCartOrders = shopCartOrders.stream().sorted(Comparator.comparing(ShopCartOrderDto::getActualTotal)).collect(Collectors.toList());
            ShopCartOrderDto shopCartOrderDto = shopCartOrders.get(n);

            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCartOrderDto.getShopCartItemDiscounts();
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> sortShopCartItems = shopCartItemDiscount.getShopCartItems();
                sortShopCartItems = sortShopCartItems.stream().sorted(Comparator.comparing(ProductItemDto::getActualTotal)).collect(Collectors.toList());
                shopCartItemDiscount.setShopCartItems(sortShopCartItems);
                double totalAmount = shopCartItemDiscount.getShopCartItems().stream().mapToDouble(ProductItemDto::getActualTotal).sum();
                shopCartItemDiscount.setTotalAmount(totalAmount);
            }
            // 婵″倹鐏夐弰顖涘閹碉絿澹掗崚顐㈢毈閻ㄥ嫭鍎忛崘鍏哥瑓閿涘苯顕遍懛鏉戠杽闂勫懘鍣炬０婵呰礋0閺勵垽绱濋弨鐟板綁閺堚偓鐏忓繑鏁禒姗€鍣炬０婵呰礋0.01閸?楠炴湹绗栨导妯诲劕闁叉垿顤傞崙蹇撳箵0.01閵?
            if (shopCartOrderDto.getActualTotal() <= 0) {
                shopCartOrderDto.setActualTotal(0.01);
                shopCartOrderDto.setShopReduce(Arith.sub(shopCartOrderDto.getShopReduce(), 0.01));
                List<ShopCartItemDto> sortItems = shopCartItemDiscounts.get(shopCartItemDiscounts.size() - 1).getShopCartItems();
                ShopCartItemDto shopCartItemDto = sortItems.get(sortItems.size() - 1);
                shopCartItemDto.setActualTotal(0.01);
                shopCartItemDto.setShareReduce(Arith.sub(shopCartItemDto.getShareReduce(), 0.01));
            }
            shopCartItemDiscounts = shopCartItemDiscounts.stream().sorted(Comparator.comparing(ShopCartItemDiscountDto::getTotalAmount)).collect(Collectors.toList());
            shopCartOrders.get(n).setShopCartItemDiscounts(shopCartItemDiscounts);
            actualTotal = Arith.add(actualTotal, shopCartOrderDto.getActualTotal());
        }
        //v
        shopCartOrderMergerDto.setActualTotal(Arith.sub(actualTotal, v) < 0 ? 0 : Arith.sub(actualTotal, v));
        shopCartOrderMergerDto.setTotalUsableScore(Arith.sub(actualTotal, v) < 0 ? actualTotal : v);//閹鍙″☉鍫ｂ偓妤冩畱缁夘垰鍨?
//        shopCartOrderMergerDto.setTotalAvailableScore(point);

        shopCartOrderMergerDto.setTotalAvailableScore((long) Arith.mul(shopCartOrderMergerDto.getTotalUsableScore(), 100));//閹鍙″☉鍫ｂ偓妤冩畱缁夘垰鍨?
        shopCartOrderMergerDto.setTotal(total);
        shopCartOrderMergerDto.setTotalCount(totalCount);
        shopCartOrderMergerDto.setOrderReduce(allOrderReduce);
        shopCartOrderMergerDto.setTotalTransfee(totalTransfee);
        shopCartOrderMergerDto.setUuid(orderParam.getUuid());
        shopCartOrderMergerDto.setShopCartOrders(shopCartOrders);
        shopCartOrderMergerDto.setWeight(weight);

        applicationContext.publishEvent(new PlatformConfirmOrderEvent(shopCartOrderMergerDto, orderParam, allCartItem));

        // ============  闁俺绻冪拋銏犲礋妞ゅ湱娈戦柌鎴︻杺閿涘矁顓哥粻妤€鍤拋銏犲礋閹鍣炬０? ==============

        //閹碘偓閺堝顓归崡鏇炵杽闂勫懘鍣炬０?
        actualTotal = 0.00;
        //閹碘偓閺堝顓归崡鏇氱喘閹娀鍣炬０?
        allOrderReduce = 0.00;
        totalTransfee = 0.00;
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            //鐠併垹宕熺€圭偤妾柌鎴︻杺
            double orderActualTotal = 0.00;
            //閸熷棗顔嶆导妯诲劕闁叉垿顤?
            double orderReduceAmount = 0.00;
            //閸熷棗顔嶆导妯诲劕闁叉垿顤?
            double orderPlatformAmount = 0.00;

            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    shopCartItem.setPlatformShareReduce(Arith.round(shopCartItem.getPlatformShareReduce(), 2));
                    shopCartItem.setShareReduce(Arith.add(Arith.round(shopCartItem.getShareReduce(), 2), shopCartItem.getPlatformShareReduce()));
                    shopCartItem.setActualTotal(Arith.sub(shopCartItem.getProductTotalAmount(), shopCartItem.getShareReduce()));
                    orderActualTotal = Arith.add(orderActualTotal, shopCartItem.getActualTotal());
                    orderReduceAmount = Arith.add(orderReduceAmount, shopCartItem.getShareReduce());
                    orderPlatformAmount = Arith.add(orderPlatformAmount, shopCartItem.getPlatformShareReduce());
                }
            }
            shopCartOrder.setActualTotal(Arith.add(orderActualTotal, shopCartOrder.getTransfee()));
//            shopCartOrder.setActualTotal(100.0);
            //閺€鎯у弳娴兼ɑ鍎柌鎴︻杺
            shopCartOrder.setShopReduce(Arith.add(orderReduceAmount, shopCartOrder.getFreeTransfee()));
            //閺€鎯у弳楠炲啿褰存导妯诲劕闁叉垿顤?婵″倹鐏夐悽銊﹀煕缁涘楠囬崗宥堝殰閽€銉ョ暗鏉╂劘鍨傛稊鐔活洣閺€鎹愮箻閸?
            shopCartOrder.setPlatformAmount(Arith.add(orderPlatformAmount, shopCartOrder.getFreeTransfee()));

            actualTotal = Arith.add(actualTotal, shopCartOrder.getActualTotal());
            allOrderReduce = Arith.add(allOrderReduce, shopCartOrder.getShopReduce());
            totalTransfee = Arith.add(totalTransfee, shopCartOrder.getTransfee());
        }
        shopCartOrderMergerDto.setActualTotal(Arith.sub(actualTotal, v) < 0 ? 0 : Arith.sub(actualTotal, v));
        shopCartOrderMergerDto.setTotalUsableScore(Arith.sub(actualTotal, v) < 0 ? actualTotal : v);//閹鍙″☉鍫ｂ偓妤冩畱缁夘垰鍨?
        shopCartOrderMergerDto.setTotalAvailableScore((long) Arith.mul(shopCartOrderMergerDto.getTotalUsableScore(), 100));
        shopCartOrderMergerDto.setTotalTransfee(totalTransfee);
        shopCartOrderMergerDto.setOrderReduce(allOrderReduce);

        applicationContext.publishEvent(new ScoreConfirmOrderEvent(shopCartOrderMergerDto, orderParam, allCartItem));
        mergeMemberDiscount(shopCartOrderMergerDto);
        orderService.putConfirmOrderCache(userId + orderParam.getUuid(), shopCartOrderMergerDto);

        return ResponseEntity.ok(shopCartOrderMergerDto);
    }

    /**
     * 鐠愵厾澧挎潪?缁斿宓嗙拹顓濇嫳  閹绘劒姘︾拋銏犲礋,閺嶈宓佹惔妤呮懙閹峰棗宕?
     */
    @PostMapping("/submit")
    @ApiOperation(value = "Submit order", notes = "Submit the confirmed order and create order numbers")
    public ResponseEntity<OrderNumbersDto> submitOrders(@Valid @RequestBody SubmitOrderParam submitOrderParam) {
        //閹碉絽鍣虹粔顖氬瀻,閸忓牐骞忛崣鏍х秼閸撳秶鏁ら幋椋庢畱閹碘偓娴犮儳袧閸掑棴绱濈拋锛勭暬閹碉綁娅庢稊瀣倵閺勵垰鎯佹潻姗€娓剁憰浣镐簳娣団剝鏁禒?
        String userId = SecurityUtils.getUser().getUserId();
        ShopCartOrderMergerDto mergerOrder = orderService.getConfirmOrderCache(userId + submitOrderParam.getUuid());

        if (mergerOrder == null) {
            throw new GlobalException("Order confirmation has expired, please confirm again");
        }
        // 閺嶏繝鐛欓崯鍡楁惂閺勵垰鎯侀崚鐘绘珟


        List<OrderShopParam> orderShopParams = submitOrderParam.getOrderShopParam();
        List<ShopCartOrderDto> shopCartOrders = mergerOrder.getShopCartOrders();
        // 鐠佸墽鐤嗘径鍥ㄦ暈
        if (CollectionUtil.isNotEmpty(orderShopParams)) {
            for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
                for (OrderShopParam orderShopParam : orderShopParams) {
                    if (Objects.equals(shopCartOrder.getShopId(), orderShopParam.getShopId())) {
                        shopCartOrder.setRemarks(orderShopParam.getRemarks());
                    }
                }
            }
        }
        mergerOrder.setChannelId(submitOrderParam.getChannelId());
        List<Order> orders = orderService.submit(userId, mergerOrder);

        StringBuilder orderNumbers = new StringBuilder();
        for (Order order : orders) {
            orderNumbers.append(order.getOrderNumber()).append(",");
        }
        orderNumbers.deleteCharAt(orderNumbers.length() - 1);

        boolean isShopCartOrder = false;
        // 缁夊娅庣紓鎾崇摠
        for (ShopCartOrderDto shopCartOrder : shopCartOrders) {
            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartOrder.getShopCartItemDiscounts()) {
                for (ShopCartItemDto shopCartItem : shopCartItemDiscount.getShopCartItems()) {
                    Long basketId = shopCartItem.getBasketId();
                    if (basketId != null && basketId != 0) {
                        isShopCartOrder = true;
                    }
                    skuService.removeSkuCacheBySkuId(shopCartItem.getSkuId(), shopCartItem.getProdId());
                    productService.removeProductCacheByProdId(shopCartItem.getProdId());
                }
            }
        }
        // 鐠愵厾澧挎潪锔藉絹娴溿倛顓归崡鏇熸(閸楄櫕婀佺拹顓犲⒖鏉烆毌D閺?
        if (isShopCartOrder) {
            basketService.removeShopCartItemsCacheByUserId(userId);
        }
        orderService.removeConfirmOrderCache(userId + submitOrderParam.getUuid());
        for (Order order : orders) {
            if (!order.getNextPay()) {
                //娑撳秵濯堕崡鏇炴嫲瀹稿弶濯堕崡鏇熷腹閸掔増鎹ｉ崡?
//                if (order.getSplitStatus() == 1 || order.getOrderLevel() == 1) {
                    //閹恒劑鈧焦鎹ｉ崡姘愁吂閸?
                    hbOrderService.createOrderAsync(order.getOrderNumber());
//                }
            }
        }

        return ResponseEntity.ok(new OrderNumbersDto(orderNumbers.toString(), mergerOrder.getNextPay()));
    }

    @GetMapping("/getOrderPayInfoByOrderNumber")
    @ApiOperation(value = "Get order pay info", notes = "Load payment info by order numbers")
    @ApiImplicitParam(name = "orderNumbers", value = "Comma-separated order numbers", required = true, dataType = "String")
    public ResponseEntity<OrderPayInfoParam> getOrderPayInfoByOrderNumber(@RequestParam("orderNumbers") String orderNumbers) {
        List<String> orderNumberList = Arrays.asList(orderNumbers.split(","));
        //閼惧嘲褰囩拋銏犲礋娣団剝浼?
        List<Order> orderList = orderService.getOrderPayInfoByOrderNumber(orderNumberList);
        List<String> prodNameList = Lists.newArrayList();
        Long addrOrderId = null;
        Date endTime = null;
        int totalScore = 0;
        double totalFee = 0.0;
        //閼惧嘲褰囬崯鍡楁惂閸氬秹娉﹂崥?
        for (Order order : orderList) {
            for (OrderItem orderItem : order.getOrderItems()) {
                prodNameList.add(orderItem.getProdName());
                totalScore += orderItem.getUseScore() != null ? orderItem.getUseScore() : 0;
            }
            //缁楊兛绔村▎鈥虫儕閻滎垽绱濋懢宄板絿鐠併垹宕熼崷鏉挎絻id閿涘矁顓归崡鏇＄箖閺堢喐妞傞梻?
            if (Objects.isNull(addrOrderId)) {
                addrOrderId = order.getAddrOrderId();
                if (Objects.equals(2, order.getOrderType())) {
                    // 閼惧嘲褰囩粔鎺撴絻鐠併垹宕熼惃鍕絿濞戝牐顓归崡鏇熸闂?
                    Integer maxCancelTime = 0;
                    SubmitSeckillOrderEvent event = new SubmitSeckillOrderEvent(order, maxCancelTime);
                    applicationContext.publishEvent(event);
                    maxCancelTime = event.getMaxCancelTime();
                    if (maxCancelTime <= 0) {
                        maxCancelTime = 30;
                    }
                    endTime = DateUtil.offsetMinute(order.getCreateTime(), maxCancelTime);
                } else {
                    endTime = DateUtil.offsetMinute(order.getCreateTime(), 30);
                }
            }
            totalFee = Arith.add(totalFee, order.getActualTotal());
        }
        //閸愭瑥鍙嗛崯鍡楁惂閸氬秲鈧焦鏁圭拹褍婀撮崸鈧?閻絻鐦?
        UserAddrOrder userAddrOrder = userAddrOrderService.getById(addrOrderId);
        String addr = userAddrOrder.getProvince() + userAddrOrder.getCity() + userAddrOrder.getArea() + userAddrOrder.getAddr();
        OrderPayInfoParam orderPayInfoParam = new OrderPayInfoParam();
        orderPayInfoParam.setProdNameList(prodNameList);
        orderPayInfoParam.setReceiver(userAddrOrder.getReceiver());
        orderPayInfoParam.setUserAddr(addr);
        orderPayInfoParam.setMobile(userAddrOrder.getMobile());
        orderPayInfoParam.setEndTime(endTime);
        orderPayInfoParam.setTotalFee(totalFee);
        orderPayInfoParam.setTotalScore(totalScore);
        return ResponseEntity.ok(orderPayInfoParam);
    }


    private void mergeMemberDiscount(ShopCartOrderMergerDto shopCartOrderMergerDto) {
        if (shopCartOrderMergerDto == null) {
            return;
        }
        if (CollectionUtil.isEmpty(shopCartOrderMergerDto.getShopCartOrders())) {
            shopCartOrderMergerDto.setMemberDiscountAmount(0.0);
            shopCartOrderMergerDto.setMemberDiscountDesc(null);
            shopCartOrderMergerDto.setMemberBenefitDesc(null);
            shopCartOrderMergerDto.setMemberDiscountRate(null);
            return;
        }
        double memberDiscountAmount = 0.0;
        String memberDiscountDesc = null;
        String memberBenefitDesc = null;
        Double memberDiscountRate = null;
        for (ShopCartOrderDto shopCartOrder : shopCartOrderMergerDto.getShopCartOrders()) {
            Double orderMemberDiscount = shopCartOrder.getMemberDiscountAmount();
            if (orderMemberDiscount != null && orderMemberDiscount > 0) {
                memberDiscountAmount = Arith.add(memberDiscountAmount, orderMemberDiscount);
                if (memberDiscountDesc == null) {
                    memberDiscountDesc = shopCartOrder.getMemberDiscountDesc();
                }
                if (memberBenefitDesc == null) {
                    memberBenefitDesc = shopCartOrder.getMemberBenefitDesc();
                }
                if (memberDiscountRate == null) {
                    memberDiscountRate = shopCartOrder.getMemberDiscountRate();
                }
            }
        }
        shopCartOrderMergerDto.setMemberDiscountAmount(memberDiscountAmount);
        shopCartOrderMergerDto.setMemberDiscountDesc(memberDiscountAmount > 0 ? memberDiscountDesc : null);
        shopCartOrderMergerDto.setMemberBenefitDesc(memberDiscountAmount > 0 ? memberBenefitDesc : null);
        shopCartOrderMergerDto.setMemberDiscountRate(memberDiscountAmount > 0 ? memberDiscountRate : null);
    }
    private void validateGuizhouAddress(UserAddr userAddr) {
        if (userAddr == null) {
            throw new GlobalException("Shipping address is required");
        }
        String fullAddress = safeString(userAddr.getProvince())
                + safeString(userAddr.getCity())
                + safeString(userAddr.getArea())
                + safeString(userAddr.getAddr())
                + safeString(userAddr.getAddress())
                + safeString(userAddr.getAddressName())
                + safeString(userAddr.getAddrDetail());
        if (!containsGuizhou(userAddr.getProvince()) && !containsGuizhou(fullAddress)) {
            throw new GlobalException("Only Guizhou addresses are supported");
        }
    }

    private boolean containsGuizhou(String text) {
        return text != null && text.contains("??");
    }

    private String safeString(String text) {
        return text == null ? "" : text;
    }
}
