package com.sonic.lion.job;

import com.sonic.common.AppRuntime;
import com.sonic.common.client.JobmanClient;
import com.sonic.common.utils.LogUtils;
import com.sonic.common.utils.RedisLock;
import com.sonic.lion.service.ProcessingChargeService;
import com.sonic.lion.service.ProcessingWithdrawReviewService;
import com.sonic.lion.service.ProcessingWithdrawService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class ProcessingJob {

    @Autowired
    private JobmanClient jobmanClient;
    @Autowired
    private ProcessingChargeService processingChargeService;
    @Autowired
    private ProcessingWithdrawService processingWithdrawService;
    @Autowired
    private ProcessingWithdrawReviewService processingWithdrawReviewService;
    @Autowired
    private RedisLock.RedisWrapper redisWrapper;
    @Autowired
    private AppRuntime appRuntime;

    /**
     * 每1分钟跑一次
     * 扫描正在充值中的数据，获取最终的充值状态
     */
    @Scheduled(cron = "10 0/1 * * * ?")
    public void startChargeProcessingJobSchedule() {
        // 锁 1 分钟过期
        jobmanClient.run("chargeProcessingJob", TimeUnit.SECONDS.toSeconds(5 * 60), this::chargeProcessingJob);
    }

    /**
     * 每1分钟跑一次
     * 扫描过了1天审核时间，可以在三方发起提现转账操作的数据进行提现转账
     */
    @Scheduled(cron = "20 0/1 * * * ?")
    public void startWithdrawReviewProcessingJobSchedule() {
        // 锁 1 分钟过期
        jobmanClient.run("withdrawReviewProcessingJob", TimeUnit.SECONDS.toSeconds(5 * 60), this::withdrawReviewProcessingJob);
    }

    /**
     * 每1分钟跑一次
     * 扫描提现中的数据获取最终的提现结果
     */
    @Scheduled(cron = "30 0/1 * * * ?")
    public void startWithdrawProcessingJobSchedule() {
        // 锁 1 分钟过期
        jobmanClient.run("withdrawProcessingJob", TimeUnit.SECONDS.toSeconds(5 * 60), this::withdrawProcessingJob);
    }

    /**
     * 扫描正在充值中的数据，获取最终的充值状态
     */
    public JobmanClient.JobResult chargeProcessingJob(JobmanClient.JobContext jobContext) {
        try {
            LogUtils.setTraceId();
            log.info("===> chargeProcessingJob start");
            long startTime = System.currentTimeMillis();
            //加锁，避免定时任务并发重复处理
            RedisLock redisLock = new RedisLock(appRuntime.buildPrefixKey("lock", "chargeProcessingJob"), redisWrapper);
            redisLock.tryAcquireRun(10 * 60 * 1000, () -> {
                processingChargeService.hand();
                return true;
            });
            log.info("===> chargeProcessingJob end {} ms", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            log.error("===> chargeProcessingJob error : ", e);
        } finally {
            LogUtils.removeTraceId();
        }
        return JobmanClient.JobResult.success(0);
    }

    /**
     * 扫描过了1天审核时间，可以在三方发起提现转账操作的数据进行提现转账
     * @param jobContext
     * @return
     */
    public JobmanClient.JobResult withdrawReviewProcessingJob(JobmanClient.JobContext jobContext) {
        try {
            LogUtils.setTraceId();
            log.info("===> withdrawReviewProcessingJob start");
            long startTime = System.currentTimeMillis();
            //加锁，避免定时任务并发重复处理
            RedisLock redisLock = new RedisLock(appRuntime.buildPrefixKey("lock", "withdrawReviewProcessingJob"), redisWrapper);
            redisLock.tryAcquireRun(10 * 60 * 1000, () -> {
                processingWithdrawReviewService.hand();
                return true;
            });
            log.info("===> withdrawReviewProcessingJob end {} ms", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            log.error("===> withdrawReviewProcessingJob error : ", e);
        } finally {
            LogUtils.removeTraceId();
        }
        return JobmanClient.JobResult.success(0);
    }

    /**
     * 扫描提现中的数据获取最终的提现结果
     * @param jobContext
     * @return
     */
    public JobmanClient.JobResult withdrawProcessingJob(JobmanClient.JobContext jobContext) {
        try {
            LogUtils.setTraceId();
            log.info("===> withdrawProcessingJob start");
            long startTime = System.currentTimeMillis();
            processingWithdrawService.hand();
            log.info("===> withdrawProcessingJob end {} ms", System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            log.error("===> withdrawProcessingJob error : ", e);
        } finally {
            LogUtils.removeTraceId();
        }
        return JobmanClient.JobResult.success(0);
    }

}
