package cn.nianxx.thhotel.integrations.messaging.agentbus.adapter;

import cn.nianxx.thhotel.platform.message.common.request.CaptureSourceMessageCommand;
import cn.nianxx.thhotel.platform.message.common.request.CaptureSourceMessageMedia;
import cn.nianxx.thhotel.platform.message.common.enums.SourceMessageMediaType;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import org.springframework.stereotype.Component;

/**
 * AgentBus Outlook 邮件 payload 适配器。外部协议字段只在适配层解析，不泄漏到平台消息领域。
 */
@Component
public class AgentBusSourceMessageAdapter {

    private static final String PROVIDER_AGENTBUS = "AGENTBUS";
    private static final String SCHEMA_VERSION = "agentbus-outlook-v1";

    private final ObjectMapper objectMapper;

    public AgentBusSourceMessageAdapter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    /**
     * 将 AgentBus frame 转换为平台 SourceMessage 捕获命令。
     */
    public CaptureSourceMessageCommand toCaptureCommand(String hotelId, JsonNode frame) {
        JsonNode payload = frame.path("payload").isMissingNode() ? frame : frame.path("payload");
        JsonNode source = payload.path("source");
        JsonNode body = payload.path("body");
        String channel = uppercaseOrDefault(text(source, "channel"), "EMAIL");

        return new CaptureSourceMessageCommand(
                hotelId,
                PROVIDER_AGENTBUS,
                channel,
                text(source, "external_message_id"),
                text(source, "external_conversation_id"),
                text(frame, "id"),
                text(frame, "session_id"),
                firstInstant(source, "received_at", payload, "received_at"),
                parseInstant(text(source, "sent_at")),
                text(source, "sender"),
                text(source, "subject"),
                firstText(body, "text", payload, "text"),
                text(body, "html"),
                toPayloadJson(payload),
                SCHEMA_VERSION,
                mediaItems(payload)
        );
    }

    /**
     * 从 AgentBus payload 中提取内嵌图片和附件引用。
     */
    private List<CaptureSourceMessageMedia> mediaItems(JsonNode payload) {
        List<CaptureSourceMessageMedia> result = new ArrayList<>();
        addMedia(result, SourceMessageMediaType.INLINE_IMAGE.code(), payload.path("inline_images"));
        addMedia(result, SourceMessageMediaType.ATTACHMENT.code(), payload.path("attachments"));
        return List.copyOf(result);
    }

    /**
     * 将指定媒体数组追加为平台统一媒体请求项。
     */
    private void addMedia(List<CaptureSourceMessageMedia> result, String mediaType, JsonNode items) {
        if (!items.isArray()) {
            return;
        }
        for (JsonNode item : items) {
            result.add(new CaptureSourceMessageMedia(
                    mediaType,
                    firstText(item, "file_name", item, "filename", item, "name"),
                    firstText(item, "content_type", item, "mime_type"),
                    firstLong(item, "size_bytes", item, "size"),
                    firstText(item, "external_url", item, "url"),
                    text(item, "id")
            ));
        }
    }

    /**
     * 将规范化后的 AgentBus payload 序列化，供 SourceMessage 原始载荷追溯。
     */
    private String toPayloadJson(JsonNode payload) {
        try {
            return objectMapper.writeValueAsString(payload);
        } catch (JsonProcessingException exception) {
            throw new IllegalArgumentException("AgentBus payload 无法序列化为规范 JSON", exception);
        }
    }

    /**
     * 解析 AgentBus 来源时间，格式非法时保持为空，避免阻断消息入站。
     */
    private Instant parseInstant(String value) {
        if (value == null) {
            return null;
        }
        try {
            return Instant.parse(value);
        } catch (DateTimeParseException exception) {
            return null;
        }
    }

    /**
     * 从两个候选字段中读取第一个可解析的时间，格式非法时继续尝试后续字段。
     */
    private Instant firstInstant(JsonNode firstNode, String firstField, JsonNode secondNode, String secondField) {
        Instant firstValue = parseInstant(text(firstNode, firstField));
        if (firstValue != null) {
            return firstValue;
        }
        return parseInstant(text(secondNode, secondField));
    }

    /**
     * 将渠道等稳定代码转为大写，缺失时使用服务端默认值。
     */
    private String uppercaseOrDefault(String value, String defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        return value.toUpperCase(Locale.ROOT);
    }

    /**
     * 从两个候选字段中读取第一个非空文本。
     */
    private String firstText(JsonNode firstNode, String firstField, JsonNode secondNode, String secondField) {
        String firstValue = text(firstNode, firstField);
        if (firstValue != null) {
            return firstValue;
        }
        return text(secondNode, secondField);
    }

    /**
     * 从三个候选字段中读取第一个非空文本。
     */
    private String firstText(
            JsonNode firstNode,
            String firstField,
            JsonNode secondNode,
            String secondField,
            JsonNode thirdNode,
            String thirdField) {
        String firstValue = text(firstNode, firstField);
        if (firstValue != null) {
            return firstValue;
        }
        String secondValue = text(secondNode, secondField);
        if (secondValue != null) {
            return secondValue;
        }
        return text(thirdNode, thirdField);
    }

    /**
     * 从两个候选字段中读取第一个可转换为 Long 的值。
     */
    private Long firstLong(JsonNode firstNode, String firstField, JsonNode secondNode, String secondField) {
        Long firstValue = longValue(firstNode, firstField);
        if (firstValue != null) {
            return firstValue;
        }
        return longValue(secondNode, secondField);
    }

    /**
     * 读取并清理 AgentBus JSON 文本字段，空白字符串按缺失处理。
     */
    private String text(JsonNode node, String fieldName) {
        if (node == null || node.isMissingNode() || node.path(fieldName).isMissingNode() || node.path(fieldName).isNull()) {
            return null;
        }
        String value = node.path(fieldName).asText();
        String trimmed = value == null ? "" : value.trim();
        return trimmed.isEmpty() ? null : trimmed;
    }

    /**
     * 读取 AgentBus JSON 数字字段，非数字或缺失时返回空。
     */
    private Long longValue(JsonNode node, String fieldName) {
        if (node == null || node.isMissingNode() || node.path(fieldName).isMissingNode() || node.path(fieldName).isNull()) {
            return null;
        }
        JsonNode value = node.path(fieldName);
        if (value.canConvertToLong()) {
            return value.asLong();
        }
        return null;
    }
}
