
package com.tmerclub.cloud.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tmerclub.cloud.api.multishop.bo.OrderChangeShopWalletAmountBO;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.order.bo.RefundReductionStockBO;
import com.tmerclub.cloud.common.order.bo.RefundStockOperateBO;
import com.tmerclub.cloud.common.order.constant.OrderCloseType;
import com.tmerclub.cloud.common.order.vo.OrderItemVO;
import com.tmerclub.cloud.common.order.vo.OrderPreSaleInfoVO;
import com.tmerclub.cloud.common.product.constant.SupplierDeliveryType;
import com.tmerclub.cloud.common.response.ResponseEnum;
import com.tmerclub.cloud.common.rocketmq.config.RocketMqConstant;
import com.tmerclub.cloud.common.util.PriceUtil;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.order.mapper.OrderMapper;
import com.tmerclub.cloud.order.mapper.OrderPreSaleInfoMapper;
import com.tmerclub.cloud.order.model.Order;
import com.tmerclub.cloud.order.model.OrderPreSaleInfo;
import com.tmerclub.cloud.order.service.OrderPreSaleInfoService;
import com.tmerclub.cloud.order.vo.OrderAndPreSaleVO;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单预售信息
 *
 * @author lhd
 * @date 2022-08-17 16:36:47
 */
@Service
public class OrderPreSaleInfoServiceImpl implements OrderPreSaleInfoService {

    @Autowired
    private OrderPreSaleInfoMapper orderPreSaleInfoMapper;
    @Autowired
    private RocketMQTemplate orderRefundSuccessStockTemplate;
    @Autowired
    private RocketMQTemplate orderPreSaleFailSettlementTemplate;
    @Autowired
    private RocketMQTemplate couponMqTemplate;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private SegmentManager segmentManager;

    @Override
    public OrderPreSaleInfoVO getByOrderId(Long orderId) {
        return orderPreSaleInfoMapper.getByOrderId(orderId);
    }

    @Override
    public List<OrderPreSaleInfo> listByOrderIds(List<Long> orderIds) {

        return orderPreSaleInfoMapper.listByOrderIds(orderIds);
    }

    @Override
    public void saveBatch(List<OrderPreSaleInfo> orderPreSaleInfo, Date createTime) {
        if (CollUtil.isEmpty(orderPreSaleInfo)) {
            return;
        }

        // 获取订单id列表
        for (OrderPreSaleInfo preSaleInfo : orderPreSaleInfo) {
            Long id = segmentManager.getSegmentIdWithDateTime(DistributedIdKey.tmerclub_ORDER_PRE_SALE, preSaleInfo.getUserId());
            preSaleInfo.setCreateTime(createTime);
            preSaleInfo.setOrderPreSaleInfoId(id);
        }
        orderPreSaleInfoMapper.saveBatch(orderPreSaleInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBatch(List<OrderPreSaleInfo> orderPreSaleInfoList) {
        for (OrderPreSaleInfo orderPreSaleInfo : orderPreSaleInfoList) {
            orderPreSaleInfoMapper.update(orderPreSaleInfo);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handleBalanceTimeExpireOrder(List<Long> orderIds, List<Long> canalOrderList) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return;
        }
        for (Long orderId : orderIds) {
            OrderAndPreSaleVO orderAndPreSaleVO = orderMapper.getBalanceTimeExpireByOrderId(orderId);

            // 幂等处理，不符合条件的跳过
            if (Objects.isNull(orderAndPreSaleVO)) {
                continue;
            }

            if (Objects.equals(orderAndPreSaleVO.getStatus(), OrderStatus.UNPAY.value())) {
                // 如果订单未支付的话，将订单设为取消状态
                canalOrderList.add(orderAndPreSaleVO.getOrderId());
                continue;
            }

            // 处理订单退款更新
            handleOrderRefund(orderAndPreSaleVO);
            // 库存回退
            OrderItemVO dbOrderItem = new OrderItemVO();
            // 供应商发货
            boolean supplierDelivery = Objects.equals(orderAndPreSaleVO.getSupplierDeliveryType(), SupplierDeliveryType.SUPPLIER_DELIVERY.value()) &&
                    !Objects.equals(orderAndPreSaleVO.getSupplierId(), 0L);
            List<RefundReductionStockBO> refundReductionStocks = new ArrayList<>(Constant.INITIAL_CAPACITY);
            for (OrderItemVO orderItem : orderAndPreSaleVO.getOrderItems()) {
                if (orderItem.getMainGiveaway() == null || orderItem.getMainGiveaway() == 1) {
                    dbOrderItem = orderItem;
                }
                RefundReductionStockBO refundReductionStockBO = new RefundReductionStockBO();
                refundReductionStockBO.setOrderId(orderAndPreSaleVO.getOrderId());
                refundReductionStockBO.setShopId(orderAndPreSaleVO.getShopId());
                refundReductionStockBO.setActivityId(orderItem.getActivityId());
                refundReductionStockBO.setSpuName(orderItem.getSpuName());
                refundReductionStockBO.setSkuName(orderItem.getSkuName());
                refundReductionStockBO.setCount(orderItem.getCount());
                refundReductionStockBO.setPrice(orderItem.getPrice());
                refundReductionStockBO.setPartyCode(orderItem.getPartyCode());
                refundReductionStockBO.setPic(orderItem.getPic());
                if (supplierDelivery) {
                    refundReductionStockBO.setSupplierProd(1);
                    refundReductionStockBO.setSkuId(orderItem.getSupplierSkuId());
                    refundReductionStockBO.setSpuId(orderItem.getSupplierSpuId());
                } else {
                    refundReductionStockBO.setSkuId(orderItem.getSkuId());
                    refundReductionStockBO.setSpuId(orderItem.getSpuId());
                }
                refundReductionStocks.add(refundReductionStockBO);
            }
            // 获取商品入库id
            Long id = segmentManager.getSegmentId(DistributedIdKey.tmerclub_STOCK_BILL_LOG);


            // 通知还原库存
            SendStatus sendStatus = orderRefundSuccessStockTemplate.syncSend(RocketMqConstant.ORDER_REFUND_SUCCESS_STOCK_TOPIC, new GenericMessage<>(new RefundStockOperateBO(refundReductionStocks, id))).getSendStatus();
            if (!Objects.equals(sendStatus, SendStatus.SEND_OK)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }

            // 订单超时未支付尾款 商家结算操作
            OrderChangeShopWalletAmountBO orderChangeShopWalletAmountBO = new OrderChangeShopWalletAmountBO();
            orderChangeShopWalletAmountBO.setActualTotal(orderAndPreSaleVO.getDepositAmount());
            orderChangeShopWalletAmountBO.setOrderId(orderAndPreSaleVO.getOrderId());
            orderChangeShopWalletAmountBO.setShopId(orderAndPreSaleVO.getShopId());
            // 平台佣金
            long platformCommission = PriceUtil.divideByBankerRounding((long) ((orderChangeShopWalletAmountBO.getActualTotal()) * dbOrderItem.getRate()), 100);
            orderChangeShopWalletAmountBO.setPlatformCommission(platformCommission);
            orderChangeShopWalletAmountBO.setPaySysType(orderAndPreSaleVO.getPaySysType());
            SendStatus status = orderPreSaleFailSettlementTemplate.syncSend(RocketMqConstant.ORDER_PRE_SALE_FAIL_SETTLEMENT_TOPIC, new GenericMessage<>(orderChangeShopWalletAmountBO)).getSendStatus();
            if (!Objects.equals(status, SendStatus.SEND_OK)) {
                throw new LuckException(ResponseEnum.EXCEPTION);
            }
        }
        // 通知退还优惠券
        SendStatus couponSendStatus = couponMqTemplate.syncSend(RocketMqConstant.COUPON_UNLOCK_TOPIC, new GenericMessage<>(orderIds)).getSendStatus();
        if (!Objects.equals(couponSendStatus, SendStatus.SEND_OK)) {
            throw new LuckException(ResponseEnum.EXCEPTION);
        }
    }

    /**
     * 处理订单退款更新
     *
     * @param orderAndPreSaleVO 订单信息
     */
    private void handleOrderRefund(OrderAndPreSaleVO orderAndPreSaleVO) {
        Order order = new Order();
        order.setOrderId(orderAndPreSaleVO.getOrderId());
        order.setStatus(OrderStatus.CLOSE.value());
        order.setCancelTime(new Date());
        order.setUpdateTime(new Date());
        order.setCloseType(OrderCloseType.REFUND.value());
        orderMapper.update(order);
    }
}
