package dev.lions.unionflow.server.mapper.mutuelle.credit;

import dev.lions.unionflow.server.api.dto.mutuelle.credit.GarantieDemandeDTO;
import dev.lions.unionflow.server.api.enums.mutuelle.credit.TypeGarantie;
import dev.lions.unionflow.server.entity.mutuelle.credit.DemandeCredit;
import dev.lions.unionflow.server.entity.mutuelle.credit.GarantieDemande;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.util.UUID;

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

@QuarkusTest
class GarantieDemandeMapperTest {

    @Inject
    GarantieDemandeMapper 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() {
        GarantieDemande entity = GarantieDemande.builder()
                .typeGarantie(TypeGarantie.CAUTION_SOLIDAIRE)
                .valeurEstimee(new BigDecimal("500000"))
                .referenceOuDescription("Membre X - Caution")
                .documentPreuveId("doc-uuid")
                .build();
        entity.setId(UUID.randomUUID());

        GarantieDemandeDTO dto = mapper.toDto(entity);

        assertThat(dto).isNotNull();
        assertThat(dto.getTypeGarantie()).isEqualTo(TypeGarantie.CAUTION_SOLIDAIRE);
        assertThat(dto.getValeurEstimee()).isEqualByComparingTo("500000");
        assertThat(dto.getReferenceOuDescription()).isEqualTo("Membre X - Caution");
        assertThat(dto.getDocumentPreuveId()).isEqualTo("doc-uuid");
    }

    @Test
    @DisplayName("toEntity mappe DTO vers entity")
    void toEntity_mapsDtoToEntity() {
        GarantieDemandeDTO dto = new GarantieDemandeDTO();
        dto.setTypeGarantie(TypeGarantie.EPARGNE_BLOQUEE);
        dto.setValeurEstimee(new BigDecimal("1000000"));
        dto.setReferenceOuDescription("Titre foncier SN 123");
        dto.setDocumentPreuveId("doc-id");

        GarantieDemande entity = mapper.toEntity(dto);

        assertThat(entity).isNotNull();
        assertThat(entity.getTypeGarantie()).isEqualTo(TypeGarantie.EPARGNE_BLOQUEE);
        assertThat(entity.getReferenceOuDescription()).isEqualTo("Titre foncier SN 123");
        assertThat(entity.getDemandeCredit()).isNull();
    }

    @Test
    @DisplayName("updateEntityFromDto met à jour l'entité cible")
    void updateEntityFromDto_updatesTarget() {
        GarantieDemande entity = GarantieDemande.builder()
                .typeGarantie(TypeGarantie.CAUTION_SOLIDAIRE)
                .referenceOuDescription("Ancienne")
                .build();
        GarantieDemandeDTO dto = new GarantieDemandeDTO();
        dto.setTypeGarantie(TypeGarantie.EPARGNE_BLOQUEE);
        dto.setReferenceOuDescription("Nouvelle référence");

        mapper.updateEntityFromDto(dto, entity);

        assertThat(entity.getTypeGarantie()).isEqualTo(TypeGarantie.EPARGNE_BLOQUEE);
        assertThat(entity.getReferenceOuDescription()).isEqualTo("Nouvelle référence");
    }

    @Test
    @DisplayName("updateEntityFromDto avec dto null ne modifie pas l'entité")
    void updateEntityFromDto_nullDto_noOp() {
        GarantieDemande entity = GarantieDemande.builder()
                .typeGarantie(TypeGarantie.CAUTION_SOLIDAIRE)
                .referenceOuDescription("Inchangée")
                .build();

        mapper.updateEntityFromDto(null, entity);

        assertThat(entity.getTypeGarantie()).isEqualTo(TypeGarantie.CAUTION_SOLIDAIRE);
        assertThat(entity.getReferenceOuDescription()).isEqualTo("Inchangée");
    }
}
