package dev.lions.unionflow.server.resource;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.*;

import io.quarkus.test.junit.QuarkusTest;
import io.restassured.http.ContentType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

/**
 * Tests d'intégration simples pour MembreResource
 *
 * @author Lions Dev Team
 * @since 2025-01-10
 */
@QuarkusTest
@DisplayName("Tests d'intégration simples MembreResource")
class MembreResourceSimpleIntegrationTest {

  @Test
  @DisplayName("GET /api/membres - Lister tous les membres actifs")
  void testListerMembres() {
    given()
        .when()
        .get("/api/membres")
        .then()
        .statusCode(200)
        .contentType(ContentType.JSON)
        .body("$", notNullValue());
  }

  @Test
  @DisplayName("GET /api/membres/999 - Membre non trouvé")
  void testObtenirMembreNonTrouve() {
    given()
        .when()
        .get("/api/membres/999")
        .then()
        .statusCode(404)
        .contentType(ContentType.JSON)
        .body("message", equalTo("Membre non trouvé"));
  }

  @Test
  @DisplayName("POST /api/membres - Données invalides")
  void testCreerMembreDonneesInvalides() {
    String membreJson =
        """
        {
            "prenom": "",
            "nom": "",
            "email": "email-invalide",
            "telephone": "123",
            "dateNaissance": "2030-01-01"
        }
        """;

    given()
        .contentType(ContentType.JSON)
        .body(membreJson)
        .when()
        .post("/api/membres")
        .then()
        .statusCode(400);
  }

  @Test
  @DisplayName("PUT /api/membres/999 - Membre non trouvé")
  void testMettreAJourMembreNonTrouve() {
    String membreJson =
        """
        {
            "prenom": "Pierre",
            "nom": "Martin",
            "email": "pierre.martin@test.com"
        }
        """;

    given()
        .contentType(ContentType.JSON)
        .body(membreJson)
        .when()
        .put("/api/membres/999")
        .then()
        .statusCode(400); // Simplement vérifier le code de statut
  }

  @Test
  @DisplayName("DELETE /api/membres/999 - Membre non trouvé")
  void testDesactiverMembreNonTrouve() {
    given()
        .when()
        .delete("/api/membres/999")
        .then()
        .statusCode(404)
        .contentType(ContentType.JSON)
        .body("message", containsString("Membre non trouvé"));
  }

  @Test
  @DisplayName("GET /api/membres/recherche - Terme manquant")
  void testRechercherMembresTermeManquant() {
    given()
        .when()
        .get("/api/membres/recherche")
        .then()
        .statusCode(400)
        .contentType(ContentType.JSON)
        .body("message", equalTo("Le terme de recherche est requis"));
  }

  @Test
  @DisplayName("GET /api/membres/recherche - Terme vide")
  void testRechercherMembresTermeVide() {
    given()
        .queryParam("q", "   ")
        .when()
        .get("/api/membres/recherche")
        .then()
        .statusCode(400)
        .contentType(ContentType.JSON)
        .body("message", equalTo("Le terme de recherche est requis"));
  }

  @Test
  @DisplayName("GET /api/membres/recherche - Recherche valide")
  void testRechercherMembresValide() {
    given()
        .queryParam("q", "test")
        .when()
        .get("/api/membres/recherche")
        .then()
        .statusCode(200)
        .contentType(ContentType.JSON)
        .body("$", notNullValue());
  }

  @Test
  @DisplayName("GET /api/membres/stats - Statistiques")
  void testObtenirStatistiques() {
    given()
        .when()
        .get("/api/membres/stats")
        .then()
        .statusCode(200)
        .contentType(ContentType.JSON)
        .body("nombreMembresActifs", notNullValue())
        .body("timestamp", notNullValue());
  }

  @Test
  @DisplayName("POST /api/membres - Membre valide")
  void testCreerMembreValide() {
    String membreJson =
        """
        {
            "prenom": "Jean",
            "nom": "Dupont",
            "email": "jean.dupont.test@example.com",
            "telephone": "221701234567",
            "dateNaissance": "1990-05-15",
            "dateAdhesion": "2025-01-10"
        }
        """;

    given()
        .contentType(ContentType.JSON)
        .body(membreJson)
        .when()
        .post("/api/membres")
        .then()
        .statusCode(anyOf(is(201), is(400))); // 201 si succès, 400 si email existe déjà
  }

  @Test
  @DisplayName("Test des endpoints avec différents content types")
  void testContentTypes() {
    // Test avec Accept header
    given()
        .accept(ContentType.JSON)
        .when()
        .get("/api/membres")
        .then()
        .statusCode(200)
        .contentType(ContentType.JSON);

    // Test avec Accept header pour les stats
    given()
        .accept(ContentType.JSON)
        .when()
        .get("/api/membres/stats")
        .then()
        .statusCode(200)
        .contentType(ContentType.JSON);
  }

  @Test
  @DisplayName("Test des méthodes HTTP non supportées")
  void testMethodesNonSupportees() {
    // PATCH n'est pas supporté
    given().when().patch("/api/membres/1").then().statusCode(405); // Method Not Allowed
  }

  @Test
  @DisplayName("PUT /api/membres/{id} - Mise à jour avec données invalides")
  void testMettreAJourMembreAvecDonneesInvalides() {
    String membreInvalideJson =
        """
        {
            "prenom": "",
            "nom": "",
            "email": "email-invalide"
        }
        """;

    given()
        .contentType(ContentType.JSON)
        .body(membreInvalideJson)
        .when()
        .put("/api/membres/1")
        .then()
        .statusCode(400);
  }

  @Test
  @DisplayName("POST /api/membres - Données invalides")
  void testCreerMembreAvecDonneesInvalides() {
    String membreInvalideJson =
        """
        {
            "prenom": "",
            "nom": "",
            "email": "email-invalide"
        }
        """;

    given()
        .contentType(ContentType.JSON)
        .body(membreInvalideJson)
        .when()
        .post("/api/membres")
        .then()
        .statusCode(400);
  }

  @Test
  @DisplayName("GET /api/membres/recherche - Terme avec espaces seulement")
  void testRechercherMembresTermeAvecEspacesUniquement() {
    given()
        .queryParam("q", "   ")
        .when()
        .get("/api/membres/recherche")
        .then()
        .statusCode(400)
        .contentType(ContentType.JSON)
        .body("message", equalTo("Le terme de recherche est requis"));
  }
}
