package com.ruoyi.task.bill;

import com.ruoyi.ss.transactionBill.service.TransactionBillService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 延迟队列管理
 * @author wjh
 * 2024/3/14
 */
@Component
@Slf4j
public class BillDelayedManager {
    @Autowired
    private ApplicationContext context;

    // 延时任务列表
    private static final DelayQueue<BillDelayed> queue = new DelayQueue<>();

    @PostConstruct
    public void init() {
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    try {
                        BillDelayed task = queue.take();
                        task.run();
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }
            }
        });
    }

    @Bean
    @Scope("prototype")
    public BillDelayed billDelayed() {
        TransactionBillService transactionBillService = context.getBean(TransactionBillService.class);
        BillDelayed delayed = new BillDelayed();
        delayed.setTransactionBillService(transactionBillService);
        return delayed;
    }

    /**
     * 添加一个延时删除订单任务
     * @param delayed 延时对象
     */
    public void add(BillDelayed delayed){
        if(queue.contains(delayed)){
            return;
        }
        queue.add(delayed);
    }

    /**
     * 添加一个延时删除订单任务
     * @param billNo 订单编号
     * @param timeout 延时时间
     * @param timeUnit 时间单位
     */
    public void add(String billNo, Long timeout, TimeUnit timeUnit) {
        BillDelayed delayed = context.getBean(BillDelayed.class);
        delayed.setBillNo(billNo);
        delayed.setTimestamp(TimeUnit.MILLISECONDS.convert(timeout, timeUnit) + System.currentTimeMillis());
        this.add(delayed);
    }

    /**
     * 添加一个定时删除订单任务
     * @param billNo 订单编号
     * @param timestamp 定时时间时间戳
     */
    public void add(String billNo, Long timestamp) {
        BillDelayed delayed = context.getBean(BillDelayed.class);
        delayed.setBillNo(billNo);
        delayed.setTimestamp(timestamp);
        this.add(delayed);
    }

    /**
     * 删除一个延时订单任务
     * @param delayed 延时对象
     */
    public boolean remove(BillDelayed delayed){
        return queue.remove(delayed);
    }

}
