package org.dromara.pay.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.pay.core.PayStrategy;
import org.dromara.pay.core.PayStrategyFactory;
import org.dromara.pay.domain.PayChannel;
import org.dromara.pay.domain.PayOrder;
import org.dromara.pay.enums.PayOrderStatusEnum;
import org.dromara.pay.mapper.PayChannelMapper;
import org.dromara.pay.mapper.PayOrderMapper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

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

/**
 * 支付订单过期处理任务
 *
 * @author pengles
 */
@Slf4j
@RequiredArgsConstructor
@Component
public class PayOrderExpireJob {

    private final PayOrderMapper payOrderMapper;
    private final PayChannelMapper payChannelMapper;
    private final PayStrategyFactory payStrategyFactory;

    /**
     * 每分钟检查一次过期订单
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    public void expireOrder() {
        // 查询未支付且已过期的订单
        Date now = new Date();
        List<PayOrder> expiredOrders = payOrderMapper.selectList(new LambdaQueryWrapper<PayOrder>()
                .eq(PayOrder::getStatus, PayOrderStatusEnum.WAITING.getStatus())
                .lt(PayOrder::getExpireTime, now)
                .last("LIMIT 100")); // 每次处理100条，防止积压

        for (PayOrder order : expiredOrders) {
            try {
                log.info("处理过期订单: {}", order.getNo());
                PayChannel channel = payChannelMapper.selectById(order.getChannelId());
                if (channel != null) {
                    PayStrategy strategy = payStrategyFactory.getStrategy(channel.getCode());
                    // 调用三方关单
                    strategy.closeOrder(order, channel);
                }
                
                // 更新本地状态为已关闭
                order.setStatus(PayOrderStatusEnum.CLOSED.getStatus());
                payOrderMapper.updateById(order);
            } catch (Exception e) {
                log.error("处理过期订单异常: {}", order.getNo(), e);
            }
        }
    }
}
