package dev.lions.unionflow.server.entity;

import dev.lions.unionflow.server.api.enums.comptabilite.TypeCompteComptable;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.UUID;

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

@DisplayName("CompteComptable")
class CompteComptableTest {

    @Test
    @DisplayName("getters/setters et valeurs par défaut")
    void gettersSetters() {
        CompteComptable c = new CompteComptable();
        c.setNumeroCompte("411000");
        c.setLibelle("Clients");
        c.setTypeCompte(TypeCompteComptable.CHARGES);
        c.setClasseComptable(4);
        c.setSoldeInitial(new BigDecimal("1000.00"));
        c.setSoldeActuel(new BigDecimal("1500.00"));
        c.setCompteCollectif(true);
        c.setCompteAnalytique(true);
        c.setDescription("Compte clients");

        assertThat(c.getNumeroCompte()).isEqualTo("411000");
        assertThat(c.getLibelle()).isEqualTo("Clients");
        assertThat(c.getTypeCompte()).isEqualTo(TypeCompteComptable.CHARGES);
        assertThat(c.getClasseComptable()).isEqualTo(4);
        assertThat(c.getSoldeInitial()).isEqualByComparingTo("1000.00");
        assertThat(c.getSoldeActuel()).isEqualByComparingTo("1500.00");
        assertThat(c.getCompteCollectif()).isTrue();
        assertThat(c.getCompteAnalytique()).isTrue();
        assertThat(c.getDescription()).isEqualTo("Compte clients");
    }

    @Test
    @DisplayName("getNumeroFormate")
    void getNumeroFormate() {
        CompteComptable c = new CompteComptable();
        c.setNumeroCompte("512");
        assertThat(c.getNumeroFormate()).hasSize(10).startsWith("512");
    }

    @Test
    @DisplayName("isTresorerie true quand type TRESORERIE")
    void isTresorerie_true() {
        CompteComptable c = new CompteComptable();
        c.setTypeCompte(TypeCompteComptable.TRESORERIE);
        assertThat(c.isTresorerie()).isTrue();
    }

    @Test
    @DisplayName("isTresorerie false pour autre type")
    void isTresorerie_false() {
        CompteComptable c = new CompteComptable();
        c.setTypeCompte(TypeCompteComptable.CHARGES);
        assertThat(c.isTresorerie()).isFalse();
    }

    @Test
    @DisplayName("onCreate initialise soldeInitial, soldeActuel, compteCollectif, compteAnalytique")
    void onCreate_initialiseChamps() throws Exception {
        CompteComptable c = new CompteComptable();
        c.setNumeroCompte("411000");
        c.setLibelle("X");
        c.setTypeCompte(TypeCompteComptable.CHARGES);
        c.setClasseComptable(1);
        c.setSoldeInitial(null);
        c.setSoldeActuel(null);
        c.setCompteCollectif(null);
        c.setCompteAnalytique(null);
        Method onCreate = CompteComptable.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(c);
        assertThat(c.getSoldeInitial()).isEqualByComparingTo(BigDecimal.ZERO);
        assertThat(c.getSoldeActuel()).isEqualByComparingTo(BigDecimal.ZERO);
        assertThat(c.getCompteCollectif()).isFalse();
        assertThat(c.getCompteAnalytique()).isFalse();
    }

    @Test
    @DisplayName("equals et hashCode")
    void equalsHashCode() {
        UUID id = UUID.randomUUID();
        CompteComptable a = new CompteComptable();
        a.setId(id);
        a.setNumeroCompte("411000");
        a.setLibelle("C");
        a.setTypeCompte(TypeCompteComptable.CHARGES);
        a.setClasseComptable(4);
        CompteComptable b = new CompteComptable();
        b.setId(id);
        b.setNumeroCompte("411000");
        b.setLibelle("C");
        b.setTypeCompte(TypeCompteComptable.CHARGES);
        b.setClasseComptable(4);
        assertThat(a).isEqualTo(b);
        assertThat(a.hashCode()).isEqualTo(b.hashCode());
    }

    @Test
    @DisplayName("toString non null")
    void toString_nonNull() {
        CompteComptable c = new CompteComptable();
        c.setNumeroCompte("411000");
        c.setLibelle("Clients");
        c.setTypeCompte(TypeCompteComptable.CHARGES);
        c.setClasseComptable(4);
        assertThat(c.toString()).isNotNull().isNotEmpty();
    }
}
