package dev.lions.unionflow.server.exception;

import static io.restassured.RestAssured.given;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.fasterxml.jackson.core.JsonProcessingException;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import jakarta.ws.rs.core.Response;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

@QuarkusTest
class JsonProcessingExceptionMapperTest {

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = { "ADMIN" })
    @DisplayName("JSON invalide (body mal formé) → 400")
    void toResponse_invalidJson_returns400() {
        given()
                .contentType(ContentType.JSON)
                .body("{ invalid json }")
                .when()
                .post("/api/evenements")
                .then()
                .statusCode(400);
    }

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = { "ADMIN" })
    @DisplayName("Body vide ou type incorrect → 400")
    void toResponse_mismatchedInput_returns400() {
        given()
                .contentType(ContentType.JSON)
                .body("[]")
                .when()
                .post("/api/evenements")
                .then()
                .statusCode(400);
    }

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = { "ADMIN" })
    @DisplayName("Format de données invalide (type) → 400")
    void toResponse_invalidFormat_returns400() {
        given()
                .contentType(ContentType.JSON)
                .body("{\"titre\":\"x\",\"capaciteMax\":\"not-a-number\"}")
                .when()
                .post("/api/evenements")
                .then()
                .statusCode(400);
    }

    @Test
    @DisplayName("toResponse: originalMessage non null → utilise originalMessage")
    void toResponse_withOriginalMessage_usesOriginalMessage() {
        JsonProcessingExceptionMapper mapper = new JsonProcessingExceptionMapper();
        JsonProcessingException ex = mock(JsonProcessingException.class);
        when(ex.getMessage()).thenReturn("full message");
        when(ex.getOriginalMessage()).thenReturn("original message");
        Response response = mapper.toResponse(ex);
        assertThat(response.getStatus()).isEqualTo(400);
    }

    @Test
    @DisplayName("toResponse: originalMessage null → utilise getMessage")
    void toResponse_nullOriginalMessage_usesGetMessage() {
        JsonProcessingExceptionMapper mapper = new JsonProcessingExceptionMapper();
        JsonProcessingException ex = mock(JsonProcessingException.class);
        when(ex.getMessage()).thenReturn("full message");
        when(ex.getOriginalMessage()).thenReturn(null);
        Response response = mapper.toResponse(ex);
        assertThat(response.getStatus()).isEqualTo(400);
    }
}
