package cn.ysk.cashier.utils;

import cn.hutool.core.thread.ThreadUtil;
import cn.ysk.cashier.cons.rabbit.RabbitConstants;
import cn.ysk.cashier.dto.CallNumPrintDTO;
import cn.ysk.cashier.pojo.order.TbOrderDetail;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RabbitMsgUtils implements RabbitTemplate.ConfirmCallback {
    private final RabbitTemplate rabbitTemplate;

    public RabbitMsgUtils(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        log.info(" 回调id:{}", correlationData);
        if (ack) {
            log.info("消息成功消费");
        } else {
            log.info("消息消费失败:{}", cause);
        }
    }

    private <T> void sendMsg(String exchange, String routingKey, T data, String note, boolean isJson, Integer waitTime) {
        ThreadUtil.execAsync(() -> {
            if (waitTime != null) {
                ThreadUtil.sleep(waitTime, TimeUnit.SECONDS);
            }
            CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
            log.info("开始发送{}mq消息, msgId: {}, exchange: {}, routingKey: {}, data: {}", note, correlationId.getId(), exchange, routingKey, data);
            rabbitTemplate.convertAndSend(exchange, routingKey, isJson ? JSONObject.toJSONString(data) : data, correlationId);
        });
    }

    public <T> void sendOrderCollectMsg(T data) {
        sendMsg(RabbitConstants.CART_ORDER_COLLECT_PUT, RabbitConstants.CART_ORDER_COLLECT_ROUTINGKEY_PUT, data, "订单信息收集", true, null);
    }

    public <T> void sendOrderCollectMsg(T data, int waitTime) {
        sendMsg(RabbitConstants.CART_ORDER_COLLECT_PUT, RabbitConstants.CART_ORDER_COLLECT_ROUTINGKEY_PUT, data, "订单信息收集", true, waitTime);
    }

    public void printTicket(String orderId) {
        sendMsg(RabbitConstants.PRINT_MECHINE_COLLECT_PUT, RabbitConstants.PRINT_MECHINE_COLLECT_ROUTINGKEY_PUT, orderId, "打印票", false, null);
    }

    public <T> void sendStockMsg(T mqData) {
        // 发送库存记录mq消息
        sendMsg(RabbitConstants.EXCHANGE_STOCK_RECORD, RabbitConstants.ROUTING_STOCK_RECORD_SALE, mqData, "库存记录", true, null);
    }

    public void printDishesReturnTicket(Integer orderId, Integer... orderIds) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderId", orderId);
        jsonObject.put("orderDetailIds", orderIds);
        jsonObject.put("isReturn", true);
        buildCurrentUserInfo(jsonObject);
        sendMsg(RabbitConstants.EXCHANGE_PRINT, RabbitConstants.ROUTING_KEY_PRINT_DISHES, jsonObject, "菜品退单", true, null);
    }

    public void printDishesTicket(Integer orderId, boolean isReturn, TbOrderDetail... detailOrderIds) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderId", orderId);
        jsonObject.put("orderDetailIds", detailOrderIds);
        jsonObject.put("isReturn", isReturn);
        buildCurrentUserInfo(jsonObject);
        sendMsg(RabbitConstants.EXCHANGE_PRINT, RabbitConstants.ROUTING_KEY_PRINT_DISHES, jsonObject, "菜品打印", true, 3);
    }

    public void printPlaceTicket(Integer id, boolean isReturn) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderId", id);
        jsonObject.put("isReturn", isReturn);
        buildCurrentUserInfo(jsonObject);
        sendMsg(RabbitConstants.EXCHANGE_PRINT, RabbitConstants.ROUTING_KEY_PRINT_PLACE, jsonObject, "订单打印", true, 3);

    }

    public void printCallNumTicket(Integer callQueueId, Integer shopId) {
        CallNumPrintDTO printDTO = new CallNumPrintDTO();
        printDTO.setCallQueueId(callQueueId);
        printDTO.setShopId(shopId);
        try {
            printDTO.setCurrentUserId(SecurityUtils.getCurrentUserId());
            printDTO.setCurrentUserName(SecurityUtils.getCurrentUsername());
            printDTO.setCurrentUserNickName(SecurityUtils.getCurrentUserNickName());
        } catch (Exception e) {
            log.error("获取当前用户信息失败", e);
        }
        sendMsg(RabbitConstants.EXCHANGE_PRINT, RabbitConstants.ROUTING_KEY_CALL_TABLE, printDTO, "排号小票打印", true, null);
    }

    public void addBalanceRecord(JSONObject baObj) {
        sendMsg(RabbitConstants.EXCHANGE_BALANCE, RabbitConstants.ROUTING_KEY_BALANCE, baObj, "储值卡记录", true, null);
    }

    public void updateCons(JSONObject jsonObject1) {
        sendMsg(RabbitConstants.EXCHANGE_CONS, RabbitConstants.ROUTING_KEY_CONS, jsonObject1, "储值卡记录", true, null);

    }

    public void buildCurrentUserInfo(JSONObject jsonObject) {
        try {
            jsonObject.put("currentUserId", SecurityUtils.getCurrentUserId());
            jsonObject.put("currentUserName", SecurityUtils.getCurrentUsername());
            jsonObject.put("currentUserNickName", SecurityUtils.getCurrentUserNickName());
        } catch (Exception e) {
            log.error("获取当前用户信息失败", e);
        }
    }
}
