package org.jeecg.modules.redission;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.system.app.entity.AppOrder;
import org.jeecg.modules.system.app.service.IAppOrderService;
import org.redisson.Redisson;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author wangzhiqiang
 * @Date 2025/8/15
 * @Desc 延迟队列实现订单超时取消
 */
@Component
@Slf4j
public class RedissonDelayQueue {

    private RedissonClient redissonClient;

    @Resource
    private IAppOrderService appOrderService;

    private RDelayedQueue<String> delayQueue;
    private RBlockingQueue<String> blockingQueue;

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.password}")
    private String password;

    @PostConstruct
    public void init() {
        initDelayQueue();
        startDelayQueueConsumer();
    }

    private void initDelayQueue() {
        Config config = new Config();

        SingleServerConfig serverConfig = config.useSingleServer();
        serverConfig.setAddress("redis://" + host +":6379");
        if (StrUtil.isNotEmpty(password)){
            serverConfig.setPassword(password);
        }
        //设置连接redis的心跳间隔（30s/次）
        serverConfig.setPingConnectionInterval(30000);
        config.useSingleServer();
        config.setEventLoopGroup(new NioEventLoopGroup(16));
        redissonClient = Redisson.create(config);

        blockingQueue = redissonClient.getBlockingQueue("OrderTimeOutTask");
        delayQueue = redissonClient.getDelayedQueue(blockingQueue);
    }

    private void startDelayQueueConsumer() {
        new Thread(() -> {
            while (true) {
                try {
                    String task = blockingQueue.take();
                    log.info("接收到延迟任务:{}", task);

                    //执行业务代码
                    String orderId = Arrays.stream(task.split("_")).collect(Collectors.toList()).get(1);
                    AppOrder appOrder = appOrderService.getById(orderId);
                    if(ObjectUtil.isNotEmpty(appOrder)){
                        if (appOrder.getOrderStatus() == 0){
                            log.info("修改订单：{},支付状态为已取消", orderId);
                            appOrder.setOrderStatus(4);
                            appOrderService.updateById(appOrder);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "OrderTimeOutTask-Consumer").start();
    }

    public void offerTask(String task, long seconds) {
        log.info("添加延迟任务:{} 延迟时间:{}s", task, seconds);
        delayQueue.offer(task, seconds, TimeUnit.SECONDS);
    }

}
