package dev.rheinsw.contactService.controller;

import dev.rheinsw.contactService.dto.ContactRequestDto;
import dev.rheinsw.contactService.model.ContactRequest;
import dev.rheinsw.contactService.repository.ContactRequestsRepo;
import dev.rheinsw.contactService.service.HCaptchaValidator;
import dev.rheinsw.shared.mail.MailServiceClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

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

class ContactControllerTest {

    @Mock
    private HCaptchaValidator hCaptchaValidator;

    @Mock
    private ContactRequestsRepo repository;

    @Mock
    private MailServiceClient mailServiceClient;

    @InjectMocks
    private ContactController controller;

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

    @Test
    void submitContact_ShouldReturnSuccess_WhenDevCaptchaTokenUsed() {
        // Arrange
        ContactRequestDto request = new ContactRequestDto();
        request.name = "Test User";
        request.email = "test@example.com";
        request.message = "Hello!";
        request.captcha = "10000000-aaaa-bbbb-cccc-000000000001";

        // Act
        ResponseEntity<String> response = controller.submitContact(request);

        // Assert
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("Contact form submitted successfully", response.getBody());

        verify(repository, times(1)).save(any(ContactRequest.class));
        verify(mailServiceClient, times(2)).sendMail(anyString(), anyString(), anyString());
        verifyNoInteractions(hCaptchaValidator);
    }

    @Test
    void submitContact_ShouldReturnSuccess_WhenCaptchaValid() {
        // Arrange
        ContactRequestDto request = new ContactRequestDto();
        request.name = "Valid User";
        request.email = "valid@example.com";
        request.message = "Some message";
        request.captcha = "real-token";

        when(hCaptchaValidator.isValid("real-token")).thenReturn(true);

        // Act
        ResponseEntity<String> response = controller.submitContact(request);

        // Assert
        assertEquals(HttpStatus.OK, response.getStatusCode());
        assertEquals("Contact form submitted successfully", response.getBody());

        verify(hCaptchaValidator, times(1)).isValid("real-token");
        verify(repository, times(1)).save(any(ContactRequest.class));
        verify(mailServiceClient, times(2)).sendMail(anyString(), anyString(), anyString());
    }

    @Test
    void submitContact_ShouldReturnForbidden_WhenCaptchaInvalid() {
        // Arrange
        ContactRequestDto request = new ContactRequestDto();
        request.name = "Bot User";
        request.email = "bot@example.com";
        request.message = "Spam spam spam";
        request.captcha = "invalid-token";

        when(hCaptchaValidator.isValid("invalid-token")).thenReturn(false);

        // Act
        ResponseEntity<String> response = controller.submitContact(request);

        // Assert
        assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode());
        assertEquals("Captcha verification failed", response.getBody());

        verify(hCaptchaValidator).isValid("invalid-token");
        verifyNoInteractions(repository);
        verifyNoInteractions(mailServiceClient);
    }

    @Test
    void submitContact_ShouldHandleNullOptionalFields() {
        // Arrange
        ContactRequestDto request = new ContactRequestDto();
        request.name = "No Company";
        request.email = "user@example.com";
        request.message = "Just a message";
        request.captcha = "real-token";
        request.company = null;
        request.phone = null;
        request.website = null;

        when(hCaptchaValidator.isValid("real-token")).thenReturn(true);

        // Act
        ResponseEntity<String> response = controller.submitContact(request);

        // Assert
        assertEquals(HttpStatus.OK, response.getStatusCode());
        verify(repository).save(any(ContactRequest.class));
        verify(mailServiceClient, times(2)).sendMail(anyString(), anyString(), anyString());
    }
}
