package dev.lions.unionflow.server.entity;

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

import java.lang.reflect.Method;
import java.time.LocalDate;

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

/**
 * Tests pour {@link JournalComptable} — méthodes estDansPeriode() et onCreate().
 */
@DisplayName("JournalComptable — estDansPeriode et onCreate")
class JournalComptableBranchTest {

    private JournalComptable newJournal() {
        JournalComptable j = new JournalComptable();
        j.setCode("AC");
        j.setLibelle("Achat");
        j.setTypeJournal(TypeJournalComptable.ACHATS);
        return j;
    }

    // ── estDansPeriode() ──────────────────────────────────────────────────────

    @Test
    @DisplayName("estDansPeriode: dateDebut non null mais dateFin null → true (période illimitée)")
    void estDansPeriode_dateFinNull_returnsTrue() {
        JournalComptable j = newJournal();
        j.setDateDebut(LocalDate.of(2025, 1, 1));
        j.setDateFin(null);

        assertThat(j.estDansPeriode(LocalDate.of(2025, 6, 15))).isTrue();
    }

    @Test
    @DisplayName("estDansPeriode: dateDebut null mais dateFin non null → true (période illimitée)")
    void estDansPeriode_dateDebutNull_returnsTrue() {
        JournalComptable j = newJournal();
        j.setDateDebut(null);
        j.setDateFin(LocalDate.of(2025, 12, 31));

        assertThat(j.estDansPeriode(LocalDate.of(2025, 6, 15))).isTrue();
    }

    @Test
    @DisplayName("estDansPeriode: date dans la période → true")
    void estDansPeriode_dateInPeriode_returnsTrue() {
        JournalComptable j = newJournal();
        j.setDateDebut(LocalDate.of(2025, 1, 1));
        j.setDateFin(LocalDate.of(2025, 12, 31));

        assertThat(j.estDansPeriode(LocalDate.of(2025, 6, 15))).isTrue();
    }

    @Test
    @DisplayName("estDansPeriode: date hors période → false")
    void estDansPeriode_dateOutsidePeriode_returnsFalse() {
        JournalComptable j = newJournal();
        j.setDateDebut(LocalDate.of(2025, 1, 1));
        j.setDateFin(LocalDate.of(2025, 6, 30));

        assertThat(j.estDansPeriode(LocalDate.of(2025, 7, 1))).isFalse();
    }

    // ── onCreate() ────────────────────────────────────────────────────────────

    @Test
    @DisplayName("onCreate: statut null → OUVERT")
    void onCreate_statutNull_setsOuvert() throws Exception {
        JournalComptable j = newJournal();
        j.setStatut(null);

        Method onCreate = JournalComptable.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(j);

        assertThat(j.getStatut()).isEqualTo("OUVERT");
    }

    @Test
    @DisplayName("onCreate: statut vide → OUVERT")
    void onCreate_statutEmpty_setsOuvert() throws Exception {
        JournalComptable j = newJournal();
        j.setStatut("");

        Method onCreate = JournalComptable.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(j);

        assertThat(j.getStatut()).isEqualTo("OUVERT");
    }

    @Test
    @DisplayName("onCreate: statut déjà défini → conservé")
    void onCreate_statutDejaDefini_conserve() throws Exception {
        JournalComptable j = newJournal();
        j.setStatut("FERME");

        Method onCreate = JournalComptable.class.getDeclaredMethod("onCreate");
        onCreate.setAccessible(true);
        onCreate.invoke(j);

        assertThat(j.getStatut()).isEqualTo("FERME");
    }
}
