package xtools.boot.mq.base.handle;

import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;
import xtools.boot.api.model.dto.log.LogTrack;
import xtools.boot.core.utils.SpringContextUtils;
import xtools.boot.log.LogBus;
import xtools.boot.log.enums.LogBusBaseType;
import xtools.boot.log.holder.LogTrackHolder;
import xtools.boot.mq.base.enums.MqEnums;
import xtools.boot.mq.base.model.dto.MessageDto;
import xtools.boot.mq.base.utils.MqMessageUtils;
import xtools.core.enums.LogLevel;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

/**
 * <p>Title : BaseMessageHandle</p>
 * <p>Description : BaseMessageHandle</p>
 * <p>DevelopTools : Idea_x64_v2026.1</p>
 * <p>DevelopSystem : macOS Sequoia 15.7.5</p>
 * <p>Company : org.xujun</p>
 *
 * @author : XuJun
 * @version : 5.0.0
 * @date : 2026/2/11 17:03
 */
@Slf4j
public abstract class BaseMessageHandle<T> {

    /**
     * 消息泛型类
     */
    private final Class<T> clazz;

    /**
     * 构造方法
     *
     * @param clazz 泛型类
     */
    public BaseMessageHandle(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * 获取队列
     *
     * @return 队列
     */
    public abstract MqEnums queue();

    /**
     * 获取监听方法
     *
     * @return 监听方法
     */
    public String listenerMethod() {
        return null;
    }

    /**
     * 获取参数
     *
     * @return 参数
     */
    public Object params() {
        return null;
    }

    /**
     * 自定义处理消息
     *
     * @param message 消息内容
     * @throws Exception 异常信息
     */
    public abstract void handleMessage(T message) throws Exception;

    /**
     * 基础消息处理
     *
     * @param message 消息内容
     */
    public void baseHandleMessage(String message) {
        // 解包消息
        MessageDto<T> msg = MqMessageUtils.from(message, clazz);
        final T data = msg.getData();
        if (Objects.isNull(data)) {
            log.warn("消息内容为空");
            return;
        }
        AtomicReference<Exception> err = new AtomicReference<>();
        LogTrack logTrack = msg.getLog();
        if (Objects.isNull(logTrack)) {
            try {
                handleMessage(data);
            } catch (Exception e) {
                err.set(e);
            }
        } else {
            ScopedValue.where(LogTrackHolder.getScoped(), LogTrackHolder.newHolderLogTrack(logTrack)).run(() -> {
                long startTime = System.currentTimeMillis();
                try {
                    if (logTrack.save()) {
                        LogBus.init(LogBusBaseType.MQ).title("MQ接收").data(msg).save();
                    }
                    handleMessage(data);
                } catch (Exception e) {
                    err.set(e);
                } finally {
                    if (logTrack.save()) {
                        long endTime = System.currentTimeMillis();
                        LogLevel level = Objects.isNull(err.get()) ? LogLevel.INFO : LogLevel.ERROR;
                        LogBus.init(level, LogBusBaseType.MQ)
                                .title("MQ处理完成")
                                .error(err.get())
                                .data(JSONObject.of("execTime", endTime - startTime))
                                .save();
                    }
                }
            });
        }
        Exception exception = err.get();
        if (Objects.isNull(exception)) {
            return;
        }
        log.error("消息处理异常", exception);
        BaseErrorHandle errorHandle = SpringContextUtils.getBeanDefNull(BaseErrorHandle.class);
        if (Objects.nonNull(errorHandle)) {
            errorHandle.messageHandle(message, exception);
        }
    }
}
