package cn.nianxx.thhotel.platform.message.service.impl;

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

import cn.nianxx.thhotel.platform.message.common.dto.ParsedEmlMediaItem;
import cn.nianxx.thhotel.platform.message.common.dto.ParsedEmlMessage;
import cn.nianxx.thhotel.platform.message.service.EmlMessageParseService;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import org.junit.jupiter.api.Test;

class EmlMessageParseServiceImplTest {

    private final EmlMessageParseService parseService = new EmlMessageParseServiceImpl();

    @Test
    void shouldParseHeadersBodiesInlineImagesAndAttachmentsFromEml() {
        ParsedEmlMessage message = parseService.parse(emlBytes(), "booking.eml");

        assertThat(message.messageId()).isEqualTo("debug-message-001@example.test");
        assertThat(message.conversationId()).isEqualTo("debug-message-001@example.test");
        assertThat(message.sender()).isEqualTo("guest@example.test");
        assertThat(message.subject()).isEqualTo("Booking Request");
        assertThat(message.sentAt()).isEqualTo(Instant.parse("2026-07-09T01:30:00Z"));
        assertThat(message.textBody()).contains("Plain booking body");
        assertThat(message.htmlBody()).contains("cid:inline-001");
        assertThat(message.mediaItems()).hasSize(2);

        ParsedEmlMediaItem inlineImage = message.mediaItems().get(0);
        assertThat(inlineImage.mediaType()).isEqualTo("INLINE_IMAGE");
        assertThat(inlineImage.fileName()).isEqualTo("inline.png");
        assertThat(inlineImage.contentType()).isEqualTo("image/png");
        assertThat(inlineImage.contentId()).isEqualTo("inline-001");
        assertThat(inlineImage.bytes()).isEqualTo("inline-image".getBytes(StandardCharsets.UTF_8));

        ParsedEmlMediaItem attachment = message.mediaItems().get(1);
        assertThat(attachment.mediaType()).isEqualTo("ATTACHMENT");
        assertThat(attachment.fileName()).isEqualTo("booking.pdf");
        assertThat(attachment.contentType()).isEqualTo("application/pdf");
        assertThat(attachment.bytes()).isEqualTo("pdf-content".getBytes(StandardCharsets.UTF_8));
    }

    @Test
    void shouldUseThreadIndexAsConversationIdWhenReplyHeadersMissing() {
        ParsedEmlMessage message = parseService.parse(threadIndexEmlBytes(), "thread-index.eml");

        assertThat(message.messageId()).isEqualTo("thread-index-message-001@example.test");
        assertThat(message.conversationId()).isEqualTo("AcvThreadIndexDebug001");
        assertThat(message.textBody()).contains("Thread index body");
    }

    private byte[] emlBytes() {
        return """
                From: Guest <guest@example.test>
                To: Reservations <reservations@example.test>
                Subject: Booking Request
                Date: Thu, 09 Jul 2026 01:30:00 +0000
                Message-ID: <debug-message-001@example.test>
                MIME-Version: 1.0
                Content-Type: multipart/related; boundary="rel-boundary"

                --rel-boundary
                Content-Type: multipart/alternative; boundary="alt-boundary"

                --alt-boundary
                Content-Type: text/plain; charset=UTF-8

                Plain booking body

                --alt-boundary
                Content-Type: text/html; charset=UTF-8

                <html><body><p>HTML booking body</p><img src="cid:inline-001"></body></html>

                --alt-boundary--
                --rel-boundary
                Content-Type: image/png; name="inline.png"
                Content-Transfer-Encoding: base64
                Content-ID: <inline-001>
                Content-Disposition: inline; filename="inline.png"

                aW5saW5lLWltYWdl
                --rel-boundary
                Content-Type: application/pdf; name="booking.pdf"
                Content-Transfer-Encoding: base64
                Content-Disposition: attachment; filename="booking.pdf"

                cGRmLWNvbnRlbnQ=
                --rel-boundary--
                """.replace("\n", "\r\n").getBytes(StandardCharsets.UTF_8);
    }

    private byte[] threadIndexEmlBytes() {
        return """
                From: Guest <guest@example.test>
                To: Reservations <reservations@example.test>
                Subject: Thread Index Booking Request
                Date: Thu, 09 Jul 2026 01:30:00 +0000
                Message-ID: <thread-index-message-001@example.test>
                Thread-Index: AcvThreadIndexDebug001
                MIME-Version: 1.0
                Content-Type: text/plain; charset=UTF-8

                Thread index body
                """.replace("\n", "\r\n").getBytes(StandardCharsets.UTF_8);
    }
}
