package dev.lions.unionflow.server.resource;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import dev.lions.unionflow.server.api.dto.suggestion.response.SuggestionResponse;
import dev.lions.unionflow.server.service.KeycloakService;
import dev.lions.unionflow.server.service.SuggestionService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import io.restassured.http.ContentType;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * Tests de couverture complémentaires pour FeedbackResource.
 * Couvre les branches manquantes :
 *  - subject == null → utilise "Commentaire utilisateur"
 *  - userId null ou blank → utilise UUID "00000000-..."
 */
@QuarkusTest
class FeedbackResourceCoverageTest {

    @InjectMock
    KeycloakService keycloakService;

    @InjectMock
    SuggestionService suggestionService;

    @Test
    @TestSecurity(user = "user@unionflow.com", roles = { "USER" })
    @DisplayName("POST /api/feedback sans subject utilise 'Commentaire utilisateur' (branche subject == null)")
    void sendFeedback_nullSubject_usesDefaultSubject() {
        SuggestionResponse response = new SuggestionResponse();
        response.setId(UUID.randomUUID());
        when(keycloakService.getCurrentUserId()).thenReturn(UUID.randomUUID().toString());
        when(keycloakService.getCurrentUserFullName()).thenReturn("Test User");
        when(suggestionService.creerSuggestion(any())).thenReturn(response);

        given()
                .contentType(ContentType.JSON)
                // subject absent → branche false : utilise "Commentaire utilisateur"
                .body("{\"message\":\"Un message de feedback sans sujet\"}")
                .when()
                .post("/api/feedback")
                .then()
                .statusCode(201)
                .body("success", equalTo(true))
                .body("id", notNullValue());
    }

    @Test
    @TestSecurity(user = "user@unionflow.com", roles = { "USER" })
    @DisplayName("POST /api/feedback avec subject vide utilise 'Commentaire utilisateur' (branche isBlank)")
    void sendFeedback_blankSubject_usesDefaultSubject() {
        SuggestionResponse response = new SuggestionResponse();
        response.setId(UUID.randomUUID());
        when(keycloakService.getCurrentUserId()).thenReturn(UUID.randomUUID().toString());
        when(keycloakService.getCurrentUserFullName()).thenReturn("Test User");
        when(suggestionService.creerSuggestion(any())).thenReturn(response);

        given()
                .contentType(ContentType.JSON)
                // subject blank → branche false : utilise "Commentaire utilisateur"
                .body("{\"subject\":\"   \",\"message\":\"Un message avec sujet vide\"}")
                .when()
                .post("/api/feedback")
                .then()
                .statusCode(201)
                .body("success", equalTo(true));
    }

    @Test
    @TestSecurity(user = "user@unionflow.com", roles = { "USER" })
    @DisplayName("POST /api/feedback userId null → UUID sentinel 00000000-... (branche userId == null)")
    void sendFeedback_userIdNull_usesSentinelUuid() {
        SuggestionResponse response = new SuggestionResponse();
        response.setId(UUID.randomUUID());
        // getCurrentUserId retourne null → branche false : utilise "00000000-..."
        when(keycloakService.getCurrentUserId()).thenReturn(null);
        when(keycloakService.getCurrentUserFullName()).thenReturn(null);
        when(suggestionService.creerSuggestion(any())).thenReturn(response);

        given()
                .contentType(ContentType.JSON)
                .body("{\"subject\":\"Test\",\"message\":\"Feedback anonyme\"}")
                .when()
                .post("/api/feedback")
                .then()
                .statusCode(201)
                .body("success", equalTo(true));
    }

    @Test
    @TestSecurity(user = "user@unionflow.com", roles = { "USER" })
    @DisplayName("POST /api/feedback userId blank → UUID sentinel 00000000-... (branche userId isBlank)")
    void sendFeedback_userIdBlank_usesSentinelUuid() {
        SuggestionResponse response = new SuggestionResponse();
        response.setId(UUID.randomUUID());
        // getCurrentUserId retourne chaîne vide → branche false : utilise "00000000-..."
        when(keycloakService.getCurrentUserId()).thenReturn("   ");
        when(keycloakService.getCurrentUserFullName()).thenReturn("");
        when(suggestionService.creerSuggestion(any())).thenReturn(response);

        given()
                .contentType(ContentType.JSON)
                .body("{\"subject\":\"Test\",\"message\":\"Feedback userId blank\"}")
                .when()
                .post("/api/feedback")
                .then()
                .statusCode(201)
                .body("success", equalTo(true));
    }

    @Test
    @TestSecurity(user = "user@unionflow.com", roles = { "USER" })
    @DisplayName("POST /api/feedback request null (corps absent) → 400 (branche request == null)")
    void sendFeedback_requestNull_returns400() {
        // No body sent → JAX-RS passes null to the method → branche request == null
        given()
                .contentType(ContentType.JSON)
                .when()
                .post("/api/feedback")
                .then()
                .statusCode(400)
                .body("error", notNullValue());
    }

    @Test
    @TestSecurity(user = "user@unionflow.com", roles = { "USER" })
    @DisplayName("POST /api/feedback message null → 400 (branche message == null)")
    void sendFeedback_messageNull_returns400() {
        // message absent → request.message == null → branche true → 400
        given()
                .contentType(ContentType.JSON)
                .body("{\"subject\":\"Test\"}")
                .when()
                .post("/api/feedback")
                .then()
                .statusCode(400)
                .body("error", notNullValue());
    }
}
