package com.gree.mall.miniapp.schedule;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.gree.mall.miniapp.constant.Constant;
import com.gree.mall.miniapp.enums.IsYesNoEnum;
import com.gree.mall.miniapp.enums.PayTypeEnum;
import com.gree.mall.miniapp.exception.RemoteServiceException;
import com.gree.mall.miniapp.logic.common.AllInPayLogic;
import com.gree.mall.miniapp.plus.entity.WebsitSalesPayOrder;
import com.gree.mall.miniapp.plus.service.WebsitSalesPayOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

@Component
@Slf4j
@ConditionalOnProperty(name = "schedule.enable", havingValue = "true", matchIfMissing = true)
public class AllinpaySchedule {

    @Resource
    WebsitSalesPayOrderService websitSalesPayOrderService;
    @Resource
    AllInPayLogic allInPayLogic;
    @Resource
    RedisLockRegistry redisLockRegistry;

    //上一次执行完后5秒再扫支付记录表
    @Scheduled(initialDelay = 5000, fixedDelay = 5000)
    private void configureTasks() throws Exception {
        List<WebsitSalesPayOrder> payList = websitSalesPayOrderService.lambdaQuery()
                .eq(WebsitSalesPayOrder::getPayFlag, IsYesNoEnum.NO.getKey())
                .eq(WebsitSalesPayOrder::getPayType, PayTypeEnum.ALLINPAY.getKey())
                .lt(WebsitSalesPayOrder::getRunCount, 50)
                .le(WebsitSalesPayOrder::getRunTime, new Date())
                .list();

        if (CollectionUtil.isNotEmpty(payList)) {
            for (WebsitSalesPayOrder order : payList) {
                Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.QUERY_ALLINPAY_ORDER + order.getOrderId());
                try {
                    if (obtain.tryLock(5, TimeUnit.SECONDS)) {
                        allInPayLogic.queryAllinpayOrder(order);
                    }
                } catch (RemoteServiceException e) {
                    log.error("serviceQueryOrder() 查询通联订单出错：" + e.getMessage());
                    int count = order.getRunCount() + 1;
                    order.setRunCount(count)
                            .setRunTime(DateUtil.offsetSecond(DateUtil.date(), count * 5))
                            .setLastMsg("查询通联订单出错：" + e.getMessage())
                            .updateById();
                } catch(Exception e) {
                    log.error("【查询通联订单处理】失败", e);
                    throw e;
                } finally {
                    obtain.unlock();
                }
            }
        }
    }
}
