package dev.rheinsw.shared.mail;

import dev.rheinsw.shared.mail.dto.MailRequest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.HttpEntity;
import org.springframework.web.client.RestTemplate;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.mockito.Mockito.*;

class MailServiceClientTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private MailServiceClient mailServiceClient;

    @Captor
    private ArgumentCaptor<HttpEntity<MailRequest>> httpEntityCaptor;

    private AutoCloseable closeable;

    @BeforeEach
    void setUp() {
        closeable = MockitoAnnotations.openMocks(this);
    }

    @Test
    void sendMail_shouldSendCorrectRequest() {
        // Arrange
        String email = "user@example.com";
        String subject = "Test Subject";
        String message = "This is a test message.";

        // Act
        mailServiceClient.sendMail(email, subject, message);

        // Assert
        verify(restTemplate).postForEntity(
                eq("http://gateway/api/mail/send"),
                httpEntityCaptor.capture(),
                eq(String.class)
        );

        MailRequest captured = httpEntityCaptor.getValue().getBody(); // extract the MailRequest
        assert captured != null;
        assert captured.getTo().equals(email);
        assert captured.getSubject().equals(subject);
        assert captured.getMessage().equals(message);
    }

    @Test
    void sendMail_shouldHandleExceptionDuringPost() {
        // Arrange
        String email = "user@example.com";
        String subject = "Test Subject";
        String message = "This is a test message.";

        doThrow(new RuntimeException("Simulated error")).when(restTemplate).postForEntity(
                anyString(),
                any(),
                eq(String.class)
        );

        // Act & Assert
        assertDoesNotThrow(() -> mailServiceClient.sendMail(email, subject, message),
                "sendMail should handle exception internally and not throw it");
    }


    @AfterEach
    void tearDown() throws Exception {
        closeable.close();
    }
}
