package dev.lions.unionflow.server.api.validation;

import static org.assertj.core.api.Assertions.assertThat;

import java.lang.reflect.Constructor;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

/**
 * Tests unitaires pour ValidationConstants - Couverture 100%
 *
 * @author UnionFlow Team
 * @version 2.0
 * @since 2025-01-16
 */
@DisplayName("Tests ValidationConstants")
class ValidationConstantsTest {

  @Test
  @DisplayName("Test constructeur privé")
  void testConstructeurPrive() throws Exception {
    Constructor<ValidationConstants> constructor = ValidationConstants.class.getDeclaredConstructor();
    constructor.setAccessible(true);

    // Le constructeur doit être accessible et créer une instance
    ValidationConstants instance = constructor.newInstance();
    assertThat(instance).isNotNull();
  }

  @Nested
  @DisplayName("Tests des constantes de taille")
  class TestsConstantesTaille {

    @Test
    @DisplayName("Test constantes titre")
    void testConstantesTitre() {
      assertThat(ValidationConstants.TITRE_MIN_LENGTH).isEqualTo(5);
      assertThat(ValidationConstants.TITRE_MAX_LENGTH).isEqualTo(100);
      assertThat(ValidationConstants.TITRE_SIZE_MESSAGE).contains("5").contains("100").contains("titre");
    }

    @Test
    @DisplayName("Test constantes nom organisation")
    void testConstantesNomOrganisation() {
      assertThat(ValidationConstants.NOM_ORGANISATION_MIN_LENGTH).isEqualTo(2);
      assertThat(ValidationConstants.NOM_ORGANISATION_MAX_LENGTH).isEqualTo(200);
      assertThat(ValidationConstants.NOM_ORGANISATION_SIZE_MESSAGE)
          .contains("2")
          .contains("200")
          .contains("nom");
    }

    @Test
    @DisplayName("Test constantes description")
    void testConstantesDescription() {
      assertThat(ValidationConstants.DESCRIPTION_MIN_LENGTH).isEqualTo(20);
      assertThat(ValidationConstants.DESCRIPTION_MAX_LENGTH).isEqualTo(2000);
      assertThat(ValidationConstants.DESCRIPTION_SIZE_MESSAGE)
          .contains("20")
          .contains("2000")
          .contains("description");
    }

    @Test
    @DisplayName("Test constantes description courte")
    void testConstantesDescriptionCourte() {
      assertThat(ValidationConstants.DESCRIPTION_COURTE_MAX_LENGTH).isEqualTo(1000);
      assertThat(ValidationConstants.DESCRIPTION_COURTE_SIZE_MESSAGE)
          .contains("1000")
          .contains("description");
    }

    @Test
    @DisplayName("Test constantes justification")
    void testConstantesJustification() {
      assertThat(ValidationConstants.JUSTIFICATION_MAX_LENGTH).isEqualTo(1000);
      assertThat(ValidationConstants.JUSTIFICATION_SIZE_MESSAGE)
          .contains("1000")
          .contains("justification");
    }

    @Test
    @DisplayName("Test constantes commentaires")
    void testConstantesCommentaires() {
      assertThat(ValidationConstants.COMMENTAIRES_MAX_LENGTH).isEqualTo(1000);
      assertThat(ValidationConstants.COMMENTAIRES_SIZE_MESSAGE)
          .contains("1000")
          .contains("commentaires");
    }

    @Test
    @DisplayName("Test constantes raison rejet")
    void testConstantesRaisonRejet() {
      assertThat(ValidationConstants.RAISON_REJET_MAX_LENGTH).isEqualTo(500);
      assertThat(ValidationConstants.RAISON_REJET_SIZE_MESSAGE).contains("500").contains("rejet");
    }

    @Test
    @DisplayName("Test constantes email")
    void testConstantesEmail() {
      assertThat(ValidationConstants.EMAIL_MAX_LENGTH).isEqualTo(100);
      assertThat(ValidationConstants.EMAIL_SIZE_MESSAGE).contains("100").contains("email");
    }

    @Test
    @DisplayName("Test constantes nom et prénom")
    void testConstantesNomPrenom() {
      assertThat(ValidationConstants.NOM_PRENOM_MIN_LENGTH).isEqualTo(2);
      assertThat(ValidationConstants.NOM_PRENOM_MAX_LENGTH).isEqualTo(50);
      assertThat(ValidationConstants.NOM_SIZE_MESSAGE).contains("2").contains("50").contains("nom");
      assertThat(ValidationConstants.PRENOM_SIZE_MESSAGE).contains("2").contains("50").contains("prénom");
    }
  }

  @Nested
  @DisplayName("Tests des patterns de validation")
  class TestsPatternsValidation {

    @Test
    @DisplayName("Test patterns téléphone")
    void testPatternsTelephone() {
      assertThat(ValidationConstants.TELEPHONE_PATTERN).isNotNull();
      assertThat(ValidationConstants.TELEPHONE_MESSAGE).contains("téléphone");
    }

    @Test
    @DisplayName("Test patterns devise")
    void testPatternsDevise() {
      assertThat(ValidationConstants.DEVISE_PATTERN).isNotNull();
      assertThat(ValidationConstants.DEVISE_MESSAGE).contains("devise");
    }

    @Test
    @DisplayName("Test patterns référence aide")
    void testPatternsReferenceAide() {
      assertThat(ValidationConstants.REFERENCE_AIDE_PATTERN).isNotNull();
      assertThat(ValidationConstants.REFERENCE_AIDE_MESSAGE).contains("référence");
    }

    @Test
    @DisplayName("Test patterns numéro membre")
    void testPatternsNumeroMembre() {
      assertThat(ValidationConstants.NUMERO_MEMBRE_PATTERN).isNotNull();
      assertThat(ValidationConstants.NUMERO_MEMBRE_MESSAGE).contains("numéro");
    }

    @Test
    @DisplayName("Test patterns couleur hexadécimale")
    void testPatternsCouleurHex() {
      assertThat(ValidationConstants.COULEUR_HEX_PATTERN).isNotNull();
      assertThat(ValidationConstants.COULEUR_HEX_MESSAGE).contains("couleur");
    }
  }

  @Nested
  @DisplayName("Tests des messages obligatoires")
  class TestsMessagesObligatoires {

    @Test
    @DisplayName("Test message obligatoire")
    void testMessageObligatoire() {
      assertThat(ValidationConstants.OBLIGATOIRE_MESSAGE).contains("obligatoire");
    }

    @Test
    @DisplayName("Test message email format")
    void testMessageEmailFormat() {
      assertThat(ValidationConstants.EMAIL_FORMAT_MESSAGE).contains("email");
    }

    @Test
    @DisplayName("Test messages de date")
    void testMessagesDate() {
      assertThat(ValidationConstants.DATE_PASSEE_MESSAGE).contains("passé");
      assertThat(ValidationConstants.DATE_FUTURE_MESSAGE).contains("futur");
    }
  }

  @Nested
  @DisplayName("Tests des constantes numériques")
  class TestsConstantesNumeriques {

    @Test
    @DisplayName("Test constantes montant")
    void testConstantesMontant() {
      assertThat(ValidationConstants.MONTANT_MIN_VALUE).isEqualTo("0.0");
      assertThat(ValidationConstants.MONTANT_INTEGER_DIGITS).isEqualTo(10);
      assertThat(ValidationConstants.MONTANT_FRACTION_DIGITS).isEqualTo(2);
      assertThat(ValidationConstants.MONTANT_DIGITS_MESSAGE).contains("10").contains("2");
      assertThat(ValidationConstants.MONTANT_POSITIF_MESSAGE).contains("positif");
    }
  }

  @Test
  @DisplayName("Test toutes les constantes sont non nulles")
  void testToutesConstantesNonNulles() {
    // Vérification que toutes les constantes String sont non nulles
    assertThat(ValidationConstants.TITRE_SIZE_MESSAGE).isNotNull();
    assertThat(ValidationConstants.NOM_ORGANISATION_SIZE_MESSAGE).isNotNull();
    assertThat(ValidationConstants.DESCRIPTION_SIZE_MESSAGE).isNotNull();
    assertThat(ValidationConstants.TELEPHONE_PATTERN).isNotNull();
    assertThat(ValidationConstants.DEVISE_PATTERN).isNotNull();
    assertThat(ValidationConstants.OBLIGATOIRE_MESSAGE).isNotNull();
    assertThat(ValidationConstants.EMAIL_FORMAT_MESSAGE).isNotNull();
  }
}
