package com.sino.mci.inbound.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sino.mci.inbound.dto.ReceiveMessageRequest;
import com.sino.mci.inbound.entity.FlowExecutionTrace;
import com.sino.mci.inbound.entity.MessageEvent;
import com.sino.mci.inbound.engine.FlowEngine;
import com.sino.mci.inbound.mq.InboundMessageProducer;
import com.sino.mci.inbound.repository.FlowExecutionTraceMapper;
import com.sino.mci.inbound.repository.MessageEventMapper;
import com.sino.mci.shared.util.JsonUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class InboundMessageService {

    private final MessageEventMapper messageEventMapper;
    private final FlowExecutionTraceMapper flowExecutionTraceMapper;
    private final FlowEngine flowEngine;
    private final InboundContextService inboundContextService;
    private final InboundMessageProducer inboundMessageProducer;

    @Transactional
    public MessageEvent receiveMessage(String tenantCode, ReceiveMessageRequest request) {
        MessageEvent event = new MessageEvent();
        event.setEventId(request.getEventId());
        event.setTenantCode(tenantCode);
        event.setChannelType(request.getChannelType());
        event.setChannelSubjectId(request.getChannelSubjectId());
        event.setDirection(1);
        event.setEventType(request.getEventType());
        event.setMessageSource(request.getMessageSource());
        event.setConversationId(request.getConversationId());
        event.setPersonId(request.getPersonId());
        event.setAccountId(request.getAccountId());
        event.setContent(JsonUtils.toJson(request.getContent()));
        event.setRawPayload(JsonUtils.toJson(request.getRawPayload()));
        event.setBusinessContext(JsonUtils.toJson(request.getBusinessContext()));
        event.setIsProcessed(0);
        event.setStatus(1);
        messageEventMapper.insert(event);
        log.info("Inbound message received: tenant={}, eventId={}, conversationId={}",
                tenantCode, request.getEventId(), request.getConversationId());

        processInboundMessage(event);

        FlowExecutionTrace receiveTrace = new FlowExecutionTrace();
        receiveTrace.setEventId(event.getEventId());
        receiveTrace.setNodeType("receive");
        receiveTrace.setInput(JsonUtils.toJson(request));
        receiveTrace.setOutput("event_id=" + event.getId());
        receiveTrace.setStatus(1);
        flowExecutionTraceMapper.insert(receiveTrace);

        flowEngine.executeInboundFlow(event.getId());
        return messageEventMapper.selectById(event.getId());
    }

    /**
     * 处理入站消息：解析上下文、持久化并发布到 MQ。
     *
     * @param event 已持久化的入站消息事件
     */
    public void processInboundMessage(MessageEvent event) {
        Map<String, Object> context = inboundContextService.resolveContext(event);
        event.setBusinessContext(JsonUtils.toJson(context));
        messageEventMapper.updateById(event);
        inboundMessageProducer.publish(event);
        log.info("Inbound message processed and published: eventId={}, conversationId={}, personId={}",
                event.getEventId(), event.getConversationId(), event.getPersonId());
    }

    public List<FlowExecutionTrace> listTraces(String eventId) {
        return flowExecutionTraceMapper.selectList(
                new LambdaQueryWrapper<FlowExecutionTrace>()
                        .eq(FlowExecutionTrace::getEventId, eventId)
                        .orderByAsc(FlowExecutionTrace::getId));
    }
}
