package com.jeequan.jeepay.pay.task;

import cn.hutool.core.date.DateTime;
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.components.mq.model.MchAuditMQ;
import com.jeequan.jeepay.components.mq.model.MchAuditThirdNotifyMQ;
import com.jeequan.jeepay.components.mq.vender.IMQSender;
import com.jeequan.jeepay.converter.MchInfoConverter;
import com.jeequan.jeepay.core.interfaces.paychannel.IIsvmchApplymentService;
import com.jeequan.jeepay.core.utils.JeepayKit;
import com.jeequan.jeepay.db.entity.MchApplyment;
import com.jeequan.jeepay.service.impl.MchApplymentService;
import com.jeequan.jeepay.thirdparty.channel.IsvFactory;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 商户进件查询定时任务
 *
 * @author zx
 * @date 2022/2/14 10:47
 */
@Slf4j
@Component
public class MchApplymentQueryStateTask {

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

    @Autowired
    private MchApplymentService mchApplymentService;
    @Autowired
    private IMQSender mqSender;

    @Autowired
    private MchInfoConverter mchInfoConverter;

    @XxlJob("mchApplymentQueryStateTaskHandler")
    public void start() {

        // 当前时间 减去7天
        Date offsetDate = DateUtil.offsetDay(new Date(), -7);

        //查询条件： （审核中、待验证、待签约）& 查询7天内的申请单
        LambdaQueryWrapper<MchApplyment> lambdaQueryWrapper = MchApplyment.gw()
                .in(MchApplyment::getState, MchApplyment.STATE_AUDITING, MchApplyment.STATE_WAIT_VERIFY, MchApplyment.STATE_WAIT_SIGN
                        , MchApplyment.STATE_FINISH_SIGN, MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY)
                .ge(MchApplyment::getCreatedAt, offsetDate);

        int currentPageIndex = 1; //当前页码
        while (true) {

            try {
                IPage<MchApplyment> applyMentIPage = mchApplymentService.page(new Page(currentPageIndex, QUERY_PAGE_SIZE), lambdaQueryWrapper);

                if (applyMentIPage == null || applyMentIPage.getRecords().isEmpty()) { //本次查询无结果, 不再继续查询;
                    break;
                }

                for (MchApplyment tbMchApplyment : applyMentIPage.getRecords()) {
                    this.queryApplyState(tbMchApplyment);
                }

                //已经到达页码最大量，无需再次查询
                if (applyMentIPage.getPages() <= currentPageIndex) {
                    break;
                }
                currentPageIndex++;


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

        }

        int currentPageIndex2 = 1; //当前页码
        while (true) {
            try {
                DateTime dateTime = DateUtil.offsetMinute(new Date(), 10);
                Page<MchApplyment> pageData = mchApplymentService.lambdaQuery()
                        .eq(MchApplyment::getState, MchApplyment.STATE_AUDITING_WAIT)
                        .le(MchApplyment::getCreatedAt, dateTime)
                        .page(new Page<>(currentPageIndex2, QUERY_PAGE_SIZE));

                pageData.getRecords().forEach(r -> mqSender.send(MchAuditMQ.build(r.getApplyId())));

                //已经到达页码最大量，无需再次查询
                if (pageData.getPages() <= currentPageIndex) {
                    break;
                }
                currentPageIndex++;
            } catch (Exception e) {
                log.error("error", e);
                break;
            }
        }
    }


    /**
     * 进件状态查询
     **/
    public void queryApplyState(MchApplyment tbMchApplyment) {

        try {
            IIsvmchApplymentService isvMchApplymentService = IsvFactory.getIsvMchApplymentService(JeepayKit.getIfCodeOrigin(tbMchApplyment.getIfCode()));
            if (isvMchApplymentService == null) {
                return;
            }

            // 调起进件查询接口
            com.jeequan.jeepay.core.entity.MchApplyment applymentResult = isvMchApplymentService.query(mchInfoConverter.toModel(tbMchApplyment));

            MchApplyment updateRecord = mchInfoConverter.toDbEntity(applymentResult);

            // 当状态发生了变化时
            if (!tbMchApplyment.getState().equals(updateRecord.getState())) {

                boolean beforeSuccess = tbMchApplyment.getState() == MchApplyment.STATE_SUCCESS || tbMchApplyment.getState() == MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY;
                boolean resultSuccess = applymentResult.getState() == MchApplyment.STATE_SUCCESS || applymentResult.getState() == MchApplyment.STATE_SUCCESS_NEED_SECOND_VERIFY;
                boolean successFlag = resultSuccess && !beforeSuccess;

                // 更新数据
                updateRecord.setApplyId(tbMchApplyment.getApplyId());
                updateRecord.setLastApplyAt(new Date());
                mchApplymentService.updateById(updateRecord);

                // 自动配置商户应用参数，进件成功 && 自动配置应用不为空
                if (successFlag && StringUtils.isNotBlank(tbMchApplyment.getAutoConfigMchAppId())) {
                    mchApplymentService.onApplymentSuccess(tbMchApplyment.getApplyId());
                    mqSender.send(MchAuditThirdNotifyMQ.build(tbMchApplyment.getApplyId(), MchAuditThirdNotifyMQ.TYPE_AUDIT));
                }

            }

        } catch (Exception e) {  //继续下一次迭代查询
            log.error("error applyId = {}", tbMchApplyment.getApplyId(), e);
        }

    }

}
