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.dromara.pay.service.PayOrderService;
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 PayOrderSyncJob {

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

    /**
     * 每2分钟检查一次"支付中"的订单 (防掉单)
     * 针对创建时间超过2分钟，且未过期的订单
     */
    @Scheduled(cron = "0 0/2 * * * ?")
    public void syncOrder() {
        Date now = new Date();
        Date twoMinutesAgo = new Date(now.getTime() - 2 * 60 * 1000);
        
        // 查询 WAITING 状态，创建时间 < 2分钟前，过期时间 > 现在的订单
        List<PayOrder> waitingOrders = payOrderMapper.selectList(new LambdaQueryWrapper<PayOrder>()
                .eq(PayOrder::getStatus, PayOrderStatusEnum.WAITING.getStatus())
                .lt(PayOrder::getCreateTime, twoMinutesAgo)
                .gt(PayOrder::getExpireTime, now)
                .last("LIMIT 100"));

        for (PayOrder order : waitingOrders) {
            try {
                log.info("同步支付订单状态: {}", order.getNo());
                PayChannel channel = payChannelMapper.selectById(order.getChannelId());
                if (channel == null) {
                    continue;
                }
                
                PayStrategy strategy = payStrategyFactory.getStrategy(channel.getCode());
                Integer status = strategy.queryOrder(order, channel);
                
                if (PayOrderStatusEnum.SUCCESS.getStatus().equals(status)) {
                    log.info("同步发现订单已支付: {}", order.getNo());
                    // 触发支付成功逻辑
                    payOrderService.notifyOrderSuccess(order.getNo(), null);
                } else if (PayOrderStatusEnum.CLOSED.getStatus().equals(status)) {
                    log.info("同步发现订单已关闭: {}", order.getNo());
                    order.setStatus(PayOrderStatusEnum.CLOSED.getStatus());
                    payOrderMapper.updateById(order);
                }
                
            } catch (Exception e) {
                log.error("同步订单异常: {}", order.getNo(), e);
            }
        }
    }
}
