package dev.lions.unionflow.server.mapper.ong;

import dev.lions.unionflow.server.api.dto.ong.ProjetOngDTO;
import dev.lions.unionflow.server.api.enums.ong.StatutProjetOng;
import dev.lions.unionflow.server.entity.Organisation;
import dev.lions.unionflow.server.entity.ong.ProjetOng;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.util.UUID;

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

@QuarkusTest
class ProjetOngMapperTest {

    @Inject
    ProjetOngMapper mapper;

    @Test
    @DisplayName("toDto avec null retourne null")
    void toDto_null_returnsNull() {
        assertThat(mapper.toDto(null)).isNull();
    }

    @Test
    @DisplayName("toEntity avec null retourne null")
    void toEntity_null_returnsNull() {
        assertThat(mapper.toEntity(null)).isNull();
    }

    @Test
    @DisplayName("toDto mappe entity vers DTO")
    void toDto_mapsEntityToDto() {
        UUID orgId = UUID.randomUUID();
        Organisation org = new Organisation();
        org.setId(orgId);
        ProjetOng entity = ProjetOng.builder()
                .organisation(org)
                .nomProjet("Projet santé")
                .statut(StatutProjetOng.EN_ETUDE)
                .build();
        entity.setId(UUID.randomUUID());

        ProjetOngDTO dto = mapper.toDto(entity);

        assertThat(dto).isNotNull();
        assertThat(dto.getOrganisationId()).isEqualTo(orgId.toString());
        assertThat(dto.getNomProjet()).isEqualTo("Projet santé");
        assertThat(dto.getStatut()).isEqualTo(StatutProjetOng.EN_ETUDE);
    }

    @Test
    @DisplayName("toEntity mappe DTO vers entity (champs non ignorés)")
    void toEntity_mapsDtoToEntity() {
        ProjetOngDTO dto = new ProjetOngDTO();
        dto.setNomProjet("Projet test");
        dto.setDescriptionMandat("Description");
        dto.setZoneGeographiqueIntervention("Afrique");

        ProjetOng entity = mapper.toEntity(dto);

        assertThat(entity).isNotNull();
        assertThat(entity.getNomProjet()).isEqualTo("Projet test");
        assertThat(entity.getDescriptionMandat()).isEqualTo("Description");
        assertThat(entity.getZoneGeographiqueIntervention()).isEqualTo("Afrique");
    }

    @Test
    @DisplayName("toDto avec organisation null produit organisationId null (branche entityOrganisationId — objet null)")
    void toDto_organisationNull_organisationIdIsNull() {
        ProjetOng entity = ProjetOng.builder()
                .organisation(null)
                .nomProjet("Projet sans org")
                .statut(StatutProjetOng.EN_ETUDE)
                .build();
        entity.setId(UUID.randomUUID());

        ProjetOngDTO dto = mapper.toDto(entity);

        assertThat(dto).isNotNull();
        assertThat(dto.getOrganisationId()).isNull();
        assertThat(dto.getNomProjet()).isEqualTo("Projet sans org");
    }

    @Test
    @DisplayName("updateEntityFromDto met à jour les champs de l'entité")
    void updateEntityFromDto_updatesEntity() {
        ProjetOng entity = ProjetOng.builder()
                .nomProjet("Ancien nom")
                .descriptionMandat("Ancienne description")
                .build();

        ProjetOngDTO dto = new ProjetOngDTO();
        dto.setNomProjet("Nouveau nom");
        dto.setDescriptionMandat("Nouvelle description");
        dto.setZoneGeographiqueIntervention("Amérique");

        mapper.updateEntityFromDto(dto, entity);

        assertThat(entity.getNomProjet()).isEqualTo("Nouveau nom");
        assertThat(entity.getDescriptionMandat()).isEqualTo("Nouvelle description");
        assertThat(entity.getZoneGeographiqueIntervention()).isEqualTo("Amérique");
    }

    @Test
    @DisplayName("updateEntityFromDto avec dto null ne modifie pas l'entité (branche updateEntityFromDto — dto null)")
    void updateEntityFromDto_dtoNull_entityUnchanged() {
        ProjetOng entity = ProjetOng.builder()
                .nomProjet("Nom inchangé")
                .descriptionMandat("Description initiale")
                .build();

        mapper.updateEntityFromDto(null, entity);

        assertThat(entity.getNomProjet()).isEqualTo("Nom inchangé");
        assertThat(entity.getDescriptionMandat()).isEqualTo("Description initiale");
    }
}
