package com.czg.mq;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.czg.config.RabbitConstants;
import com.czg.config.RabbitPublisher;
import com.czg.config.RedisCst;
import com.czg.exception.CzgException;
import com.czg.order.entity.MqLog;
import com.czg.order.entity.SysPrintData;
import com.czg.order.service.MqLogService;
import com.czg.order.service.SysPrintDataService;
import com.czg.print.StockPrintDTO;
import com.czg.service.RedisService;
import com.czg.service.order.print.PrintConfig;
import com.czg.service.order.print.PrinterHandler;
import com.czg.utils.FunUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.function.Consumer;

/**
 * 打印mq消息处理器
 *
 * @author Administrator
 */
@Component
@Slf4j
public class PrintMqListener {
    @Resource
    private MqLogService mqLogService;
    @Resource
    private RedisService redisService;
    @Resource
    private PrintConfig printConfig;
    @Resource
    private RabbitPublisher rabbitPublisher;
    @Resource
    protected SysPrintDataService printDataService;

    private <T> void invokeFun(String queue, String type, String plat, T data, Consumer<T> consumer) {
        long startTime = DateUtil.date().getTime();
        log.info("接收到{}打印消息：{}", type, data);
        MqLog mqLog = new MqLog().setQueue(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(RabbitConstants.Queue.ORDER_MACHINE_PRINT_QUEUE, "orderPrint", "java.order", req, (data) -> {
            JSONObject jsonObject = JSONObject.parseObject(data);
            String orderIdStr = jsonObject.getString("orderId");

            if (StrUtil.isBlank(orderIdStr)) {
                throw new RuntimeException("订单打印失败，未传递orderId");
            }
            String[] split = orderIdStr.split("_");
            if (split.length < 3) {
                throw new CzgException("订单ID格式不正确：" + orderIdStr);
            }

            Long orderId = Long.parseLong(split[0]);
            //付费类型 0后付费/1先付费
            Integer payType = Integer.parseInt(split[1]);
            //订单状态 0未完成/1完成
            Integer orderStatus = Integer.parseInt(split[2]);
            //该字段表示 网络打印机是否打印订单 本地传参来的
//            Boolean printOrder = jsonObject.getBoolean("printOrder");
            redisService.runFunAndCheckKey(() -> {
                if (orderStatus == 1) {
                    printConfig.orderHandler(orderId, PrinterHandler.PrintTypeEnum.ORDER, null);
                }
                if (payType == 1 || orderStatus == 0) {
                    //菜品打印 全是后端
                    printConfig.orderHandler(orderId, PrinterHandler.PrintTypeEnum.ALL_KITCHEN, null);
                    printConfig.orderHandler(orderId, PrinterHandler.PrintTypeEnum.ONLY_KITCHEN, null);
                }
                return null;
            }, RedisCst.getLockKey("orderPrint", orderId));
        });
    }


    @RabbitListener(queues = {"${spring.profiles.active}-" + RabbitConstants.Queue.OTHER_PRINT_QUEUE})
    public void otherPrint(String data) {
        JSONObject jsonObject = JSONObject.parseObject(data);
        Long shopId = jsonObject.getLong("shopId");
        String printTypeEnum = jsonObject.getString("printTypeEnum");
        JSONObject data2 = jsonObject.getJSONObject("data");
        JSONArray data3;
        if (data2 == null) {
            data3 = jsonObject.getJSONArray("data");
        } else {
            data3 = null;
        }
        PrinterHandler.PrintTypeEnum typeEnum = PrinterHandler.PrintTypeEnum.valueOf(printTypeEnum);
        if (typeEnum != PrinterHandler.PrintTypeEnum.HANDOVER) {
            SysPrintData sysPrintData = new SysPrintData();
            sysPrintData.setShopId(shopId);
            if (data2 != null) {
                sysPrintData.setData(data2.toJSONString());
            } else {
                sysPrintData.setData(data3.toJSONString());
            }
            sysPrintData.setType(typeEnum.toString());
            printDataService.save(sysPrintData);
            rabbitPublisher.sendOtherPrintLocalMsg(shopId, printTypeEnum, sysPrintData.getId());
        }
        FunUtils.asyncSafeRunVoid(() -> printConfig.otherHandler(shopId, data2, data3, typeEnum));
    }
}
