package com.jeequan.jeepay.pay.task;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jeequan.jeepay.core.entity.TransferOrder;
import com.jeequan.jeepay.core.interfaces.paychannel.ITransferService;
import com.jeequan.jeepay.core.model.rqrs.msg.ChannelRetMsg;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import com.jeequan.jeepay.db.entity.TransferOrderEntity;
import com.jeequan.jeepay.pay.service.TransferOrderReissueService;
import com.jeequan.jeepay.service.impl.TransferOrderService;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ExecutorService;

/*
 * 转账补单定时任务
 *
 * @author zx
 *
 * @date 2022/12/29 17:47
 */
@Slf4j
@Component
public class TransferOrderReissueTask {

    @Autowired
    private ServerProperties serverProperties;

    private static final int QUERY_PAGE_SIZE = 100; //每次查询数量

    @Autowired
    private TransferOrderService transferOrderService;
    @Autowired
    private TransferOrderReissueService transferOrderReissueService;
    @Autowired
    private ExecutorService executorService;

    @XxlJob("transferOrderReissueTaskHandler")
    public void start() {
        //查询条件：
        LambdaQueryWrapper<TransferOrderEntity> lambdaQueryWrapper = TransferOrderEntity.gw()
                .eq(TransferOrderEntity::getState, TransferOrderEntity.STATE_INIT) // 转账中
                .ge(TransferOrderEntity::getCreatedAt, DateUtil.offsetDay(new Date(), -1)); // 只查询一天内的转账单;

        while (true) {

            try {
                IPage<TransferOrderEntity> iPage = transferOrderService.page(new Page<>(1, QUERY_PAGE_SIZE), lambdaQueryWrapper);

                if (iPage == null || iPage.getRecords() == null || iPage.getRecords().isEmpty()) { //本次查询无结果, 不再继续查询;
                    Thread.sleep(5000L);
                    continue;
                }

                for (TransferOrderEntity transferOrder : iPage.getRecords()) {
                    transferOrderReissueService.processOrder(transferOrder);
                }

            } catch (Exception e) { //出现异常，直接退出，避免死循环。
                log.error("error", e);
                break;
            }
        }
    }

    @PostConstruct
    public void init() {
        if (!Objects.equals(9216, serverProperties.getPort())) {
            return;
        }

        log.info("批量转账订单处理");
        //查询条件：
        LambdaQueryWrapper<TransferOrderEntity> lambdaQueryWrapper = TransferOrderEntity.gw()
                .eq(TransferOrderEntity::getState, TransferOrder.STATE_INIT) // 转账中
                .ge(TransferOrderEntity::getCreatedAt, DateUtil.offsetDay(new Date(), -1)); // 只查询一天内的转账单;

        executorService.execute(() -> {
            while (true) {
                try {
                    IPage<TransferOrderEntity> iPage = transferOrderService.page(new Page<>(1, QUERY_PAGE_SIZE), lambdaQueryWrapper);

                    if (iPage == null || iPage.getRecords() == null || iPage.getRecords().isEmpty()) { //本次查询无结果, 不再继续查询;
                        Thread.sleep(5000L);
                        continue;
                    }

                    for (TransferOrderEntity transferOrder : iPage.getRecords()) {
                        ITransferService transferService = SpringBeansUtil.getBean(JeepayKit.getIfCodeOrigin(transferOrder.getIfCode()) + "TransferService", ITransferService.class);
                        if (transferService == null) {
                            log.info("未获取到代付通道实现类, {}", JeepayKit.getIfCodeOrigin(transferOrder.getIfCode()));
                            continue;
                        }

                        ChannelRetMsg tradeResult;
                        try {
                            transferService.preCheck(null, transferOrder);
                            // 调起上游接口
                            tradeResult = transferService.transfer(null, transferOrder);
                        } catch (Exception e) {
                            log.info("转账发起预校验失败", e);
                            tradeResult = ChannelRetMsg.confirmFail(null ,e.getMessage());
                        }

                        //处理转账单状态
                        transferOrderReissueService.processChannelMsg(tradeResult, transferOrder);
                    }

                } catch (Exception e) { // 出现异常，直接退出，避免死循环。
                    log.error("转账处理失败", e);
                    break;
                }
            }
        });
    }
}
