package dev.lions.unionflow.server.resource;

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

import dev.lions.unionflow.server.api.dto.logs.request.LogSearchRequest;
import dev.lions.unionflow.server.api.dto.logs.response.SystemLogResponse;
import dev.lions.unionflow.server.service.LogsMonitoringService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.security.TestSecurity;
import java.util.List;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * Tests complémentaires pour {@link LogsMonitoringResource#exportLogs} — cas avec details non null.
 */
@QuarkusTest
class LogsMonitoringResourceCoverageTest {

    @InjectMock
    LogsMonitoringService logsMonitoringService;

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
    @DisplayName("GET /api/logs/export avec details non null → details inclus dans le CSV")
    void exportLogs_withNonNullDetails_coversDetailsBranch() {
        // details non null → inclus dans le CSV
        SystemLogResponse logWithDetails = SystemLogResponse.builder()
                .level("ERROR")
                .source("service")
                .message("Erreur critique")
                .details("Stack trace ligne 42")
                .build();

        // log avec details contenant des guillemets → teste aussi le replace("\"", "\"\"")
        SystemLogResponse logWithQuotedDetails = SystemLogResponse.builder()
                .level("WARN")
                .source("api")
                .message("Warning avec \"guillemets\"")
                .details("Details avec \"guillemets\" dans le texte")
                .build();

        when(logsMonitoringService.searchLogs(any(LogSearchRequest.class)))
                .thenReturn(List.of(logWithDetails, logWithQuotedDetails));

        given()
                .queryParam("level", "ERROR")
                .queryParam("source", "service")
                .queryParam("timeRange", "1H")
                .when()
                .get("/api/logs/export")
                .then()
                .statusCode(200)
                .body(containsString("Stack trace ligne 42"));
    }

    // -------------------------------------------------------------------------
    // Error cases
    // -------------------------------------------------------------------------

    @Test
    @DisplayName("GET /api/logs/export sans authentification retourne 401")
    void exportLogs_sansAuthentification_returns401() {
        given()
                .queryParam("level", "ERROR")
                .when()
                .get("/api/logs/export")
                .then()
                .statusCode(401);
    }

    @Test
    @TestSecurity(user = "membre@test.com", roles = {"MEMBRE"})
    @DisplayName("GET /api/logs/export avec rôle MEMBRE retourne 403")
    void exportLogs_avecRoleMembre_returns403() {
        given()
                .queryParam("level", "ERROR")
                .when()
                .get("/api/logs/export")
                .then()
                .statusCode(403);
    }

    @Test
    @TestSecurity(user = "admin@unionflow.com", roles = {"ADMIN"})
    @DisplayName("GET /api/logs/export quand service lève exception retourne 500")
    void exportLogs_serviceException_returns500() {
        when(logsMonitoringService.searchLogs(any(LogSearchRequest.class)))
                .thenThrow(new RuntimeException("Erreur de lecture des logs"));

        given()
                .queryParam("level", "ERROR")
                .when()
                .get("/api/logs/export")
                .then()
                .statusCode(500);
    }
}
