package com.czg.mq;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.czg.config.RabbitConstants;
import com.czg.config.RedisCst;
import com.czg.order.entity.MqLog;
import com.czg.order.service.MqLogService;
import com.czg.service.order.print.PrinterHandler;
import com.czg.service.order.utils.FunUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.function.Consumer;

/**
 * 打印mq消息处理器
 *
 * @author Administrator
 */
@Component
@Slf4j
public class PrintMqListener {
    @Resource
    private MqLogService mqLogService;
    @Resource
    private FunUtil funUtil;

    // 注入自定义线程池（建议单独配置，避免使用默认线程池）
    @Resource
    private ThreadPoolTaskExecutor asyncExecutor;
    @Lazy
    @Resource
    private PrinterHandler printerHandler;

    private <T> void invokeFun(String type, String plat, T data, Consumer<T> consumer) {
        long startTime = DateUtil.date().getTime();
        log.info("接收到{}打印消息：{}", type, data);
        MqLog mqLog = new MqLog().setQueue(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE).setMsg(data.toString())
                .setType(type).setPlat(plat).setCreateTime(DateUtil.date().toLocalDateTime());
        try {
            consumer.accept(data);
        } catch (Exception e) {
            log.error("订单打印失败", e);
            mqLog.setErrInfo(JSONObject.toJSONString(e));
            mqLog.setDuration(DateUtil.date().getTime() - startTime);
            mqLog.setFailTime(DateUtil.date().toLocalDateTime());
            mqLogService.save(mqLog);
        }
    }

    @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE})
    public void orderPrint(String req) {
        // 执行核心打印逻辑
        invokeFun("orderPrint", "java.order", req, (data) -> {
            JSONObject jsonObject = JSONObject.parseObject(data);
            String orderId = jsonObject.getString("orderId");
            if (orderId == null) {
                throw new RuntimeException("订单打印失败，未传递orderId");
            }
            Boolean printOrder = jsonObject.getBoolean("printOrder");
            funUtil.runFunAndCheckKey(() -> {
                printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER);
                return null;
            }, RedisCst.getLockKey("orderPrint", orderId));
        });
//        // 使用异步线程池执行延迟任务，不阻塞当前消费者线程
//        CompletableFuture.runAsync(() -> {
//            try {
//                // 延迟3秒处理
//                TimeUnit.SECONDS.sleep(3);
//                // 执行核心打印逻辑
//                invokeFun("orderPrint", "java.order", req, (data) -> {
//                    JSONObject jsonObject = JSONObject.parseObject(data);
//                    String orderId = jsonObject.getString("orderId");
//                    if (orderId == null) {
//                        throw new RuntimeException("订单打印失败，未传递orderId");
//                    }
//                    Boolean printOrder = jsonObject.getBoolean("printOrder");
//                    funUtil.runFunAndCheckKey(() -> {
//                        printerHandler.handler(orderId, printOrder != null && !printOrder ? PrinterHandler.PrintTypeEnum.ONE : PrinterHandler.PrintTypeEnum.ONE_AND_ORDER);
//                        return null;
//                    }, RedisCst.getLockKey("orderPrint", orderId));
//                });
//            } catch (InterruptedException e) {
//                Thread.currentThread().interrupt();
//                // 记录中断日志
//                log.warn("打印任务被中断，req:{}", req, e);
//            } catch (Exception e) {
//                // 记录业务异常日志
//                log.error("打印任务处理失败，req:{}", req, e);
//            }
//        }, asyncExecutor);
    }

    /**
     * 交班打印
     */
    @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.ORDER_HANDOVER_PRINT_QUEUE})
    public void handoverPrint(String id) {
        invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.HANDOVER));
    }

    /**
     * 交班打印
     */
    @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.CALL_TABLE_PRINT_QUEUE})
    public void callTablePrint(String id) {
        invokeFun("handoverPrint", "java.order", id, (data) -> printerHandler.handler(data, PrinterHandler.PrintTypeEnum.CALL));
    }
}
