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

import static org.assertj.core.api.Assertions.assertThat;

import cn.nianxx.thhotel.platform.message.common.request.CaptureSourceMessageCommand;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.time.Instant;
import org.junit.jupiter.api.Test;

class AgentBusSourceMessageAdapterTest {

    private final ObjectMapper objectMapper = new ObjectMapper();
    private final AgentBusSourceMessageAdapter adapter = new AgentBusSourceMessageAdapter(objectMapper);

    @Test
    void shouldMapOutlookFrameToStableCaptureCommand() throws Exception {
        JsonNode frame = objectMapper.readTree("""
                {
                  "id": "frame-agentbus-001",
                  "session_id": "session-agentbus-001",
                  "payload": {
                    "text": "Fallback body text",
                    "body": {
                      "content_type": "html",
                      "html": "<html><body>Please change booking</body></html>",
                      "text": "Please change booking"
                    },
                    "inline_images": [
                      {
                        "id": "inline-001",
                        "file_name": "inline.png",
                        "content_type": "image/png",
                        "size_bytes": 1200,
                        "url": "https://media.example.test/inline.png"
                      }
                    ],
                    "attachments": [
                      {
                        "id": "attachment-001",
                        "name": "booking.pdf",
                        "content_type": "application/pdf",
                        "size": 3400,
                        "external_url": "https://media.example.test/booking.pdf"
                      }
                    ],
                    "received_at": "2026-07-09T05:56:56Z",
                    "source": {
                      "channel": "email",
                      "external_message_id": "outlook-message-001",
                      "external_conversation_id": "outlook-conversation-001",
                      "sender": "guest@example.test",
                      "subject": "Booking change",
                      "sent_at": "2026-07-06T08:00:00Z"
                    }
                  }
                }
                """);

        CaptureSourceMessageCommand command = adapter.toCaptureCommand("HOTEL-TEST", frame);

        assertThat(command.hotelId()).isEqualTo("HOTEL-TEST");
        assertThat(command.provider()).isEqualTo("AGENTBUS");
        assertThat(command.channel()).isEqualTo("EMAIL");
        assertThat(command.externalMessageId()).isEqualTo("outlook-message-001");
        assertThat(command.externalConversationId()).isEqualTo("outlook-conversation-001");
        assertThat(command.providerFrameId()).isEqualTo("frame-agentbus-001");
        assertThat(command.providerSessionId()).isEqualTo("session-agentbus-001");
        assertThat(command.sourceReceivedAt()).isEqualTo(Instant.parse("2026-07-09T05:56:56Z"));
        assertThat(command.sourceSentAt()).isEqualTo(Instant.parse("2026-07-06T08:00:00Z"));
        assertThat(command.senderIdentifier()).isEqualTo("guest@example.test");
        assertThat(command.subject()).isEqualTo("Booking change");
        assertThat(command.textBody()).isEqualTo("Please change booking");
        assertThat(command.htmlBody()).contains("Please change booking");
        assertThat(command.payloadJson()).contains("outlook-message-001");
        assertThat(command.schemaVersion()).isEqualTo("agentbus-outlook-v1");
        assertThat(command.mediaItems()).hasSize(2);
        assertThat(command.mediaItems().get(0).mediaType()).isEqualTo("INLINE_IMAGE");
        assertThat(command.mediaItems().get(0).externalUrl()).isEqualTo("https://media.example.test/inline.png");
        assertThat(command.mediaItems().get(1).mediaType()).isEqualTo("ATTACHMENT");
        assertThat(command.mediaItems().get(1).fileName()).isEqualTo("booking.pdf");
    }

    @Test
    void shouldPreferValidSourceReceivedAtAndFallbackToPayloadReceivedAt() throws Exception {
        JsonNode sourceReceivedFrame = objectMapper.readTree("""
                {
                  "id": "frame-agentbus-002",
                  "payload": {
                    "received_at": "2026-07-09T05:56:56Z",
                    "source": {
                      "channel": "email",
                      "external_message_id": "outlook-message-002",
                      "received_at": "2026-07-09T05:50:00Z"
                    }
                  }
                }
                """);
        JsonNode invalidSourceReceivedFrame = objectMapper.readTree("""
                {
                  "id": "frame-agentbus-003",
                  "payload": {
                    "received_at": "2026-07-09T05:56:56Z",
                    "source": {
                      "channel": "email",
                      "external_message_id": "outlook-message-003",
                      "received_at": "bad-time"
                    }
                  }
                }
                """);

        CaptureSourceMessageCommand sourceCommand = adapter.toCaptureCommand("HOTEL-TEST", sourceReceivedFrame);
        CaptureSourceMessageCommand fallbackCommand = adapter.toCaptureCommand("HOTEL-TEST", invalidSourceReceivedFrame);

        assertThat(sourceCommand.sourceReceivedAt()).isEqualTo(Instant.parse("2026-07-09T05:50:00Z"));
        assertThat(fallbackCommand.sourceReceivedAt()).isEqualTo(Instant.parse("2026-07-09T05:56:56Z"));
    }
}
