
package com.tmerclub.cloud.order.listener;

import cn.hutool.core.date.DateUtil;
import com.tmerclub.cloud.api.feign.SearchOrderFeignClient;
import com.tmerclub.cloud.api.order.constant.OrderStatus;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.order.dto.OrderSearchDTO;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.order.service.OrderService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

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

/**
 * 确认收货事务监听
 *
 * @author tmerclub
 * @date 2021/1/7
 */
@Component
@RocketMQTransactionListener(rocketMQTemplateBeanName = "orderSettledShopTemplate", maximumPoolSize = 20)
public class OrderSettledTransactionListener implements RocketMQLocalTransactionListener {

    @Autowired
    private OrderService orderService;
    @DubboReference
    private SearchOrderFeignClient searchOrderFeignClient;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        List<Long> orderIds = (List<Long>) arg;
        // 众所周知，结算之后是不能改变状态的
        int updateStats = orderService.settledOrder(orderIds);
        if (updateStats == 0) {
            // 如果啥都没有更新，就检查一下
            return checkLocalTransaction(msg);
        }
        return RocketMQLocalTransactionState.COMMIT;
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        Date now = new Date();
        // 确认收货15天的订单，进行结算
        OrderSearchDTO orderSearchDTO = new OrderSearchDTO();
        orderSearchDTO.setStatus(OrderStatus.SUCCESS.value());
        orderSearchDTO.setFinallyTime(DateUtil.beginOfDay(DateUtil.offsetDay(now, -15)));
        ServerResponseEntity<Long> orderResponseEntity = searchOrderFeignClient.countOrder(orderSearchDTO);
        if (!orderResponseEntity.isSuccess()) {
            throw new LuckException(orderResponseEntity.getMsg());
        }

        if (Objects.nonNull(orderResponseEntity.getData()) && Objects.equals(orderResponseEntity.getData(), 0L)) {
            return RocketMQLocalTransactionState.COMMIT;
        }
        return RocketMQLocalTransactionState.ROLLBACK;
    }
}
