package dev.lions.unionflow.server.service;

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

import dev.lions.unionflow.server.api.dto.solidarite.request.CreateDemandeAideRequest;
import dev.lions.unionflow.server.api.enums.solidarite.TypeAide;
import dev.lions.unionflow.server.mapper.DemandeAideMapper;
import dev.lions.unionflow.server.repository.DemandeAideRepository;
import dev.lions.unionflow.server.repository.MembreRepository;
import dev.lions.unionflow.server.repository.OrganisationRepository;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

/**
 * Tests couvrant les branches false (null IDs) de DemandeAideService.creerDemande L72/L79.
 *
 * <p>Stratégie : @ExtendWith(MockitoExtension.class) + @InjectMocks pour contourner @Valid CDI
 * qui empêche d'appeler la méthode avec des IDs null via le proxy CDI Quarkus.
 */
@ExtendWith(MockitoExtension.class)
class DemandeAideServiceNullIdsBranchesTest {

    @Mock
    DemandeAideRepository demandeAideRepository;

    @Mock
    DemandeAideMapper demandeAideMapper;

    @Mock
    MembreRepository membreRepository;

    @Mock
    OrganisationRepository organisationRepository;

    @InjectMocks
    DemandeAideService demandeAideService;

    @Test
    @DisplayName("creerDemande — membreDemandeurId null → branche L72 false couverte (skip if body)")
    void creerDemande_membreDemandeurIdNull_l72FalseBranch() {
        // @Valid est contourné via @InjectMocks — membreDemandeurId=null passe directement au corps de méthode
        // L72: if (request.membreDemandeurId() != null) → false → skip le bloc if → branche false couverte
        // La méthode échoue ensuite (NPE ou IllegalArgument) car membre n'est pas résolu
        CreateDemandeAideRequest request = CreateDemandeAideRequest.builder()
                .typeAide(TypeAide.AIDE_FINANCIERE_URGENTE)
                .titre("Test L72 false branch")
                .description("Description test")
                .membreDemandeurId(null)
                .associationId(null)
                .build();

        assertThatThrownBy(() -> demandeAideService.creerDemande(request))
                .isInstanceOf(Exception.class);
    }

    @Test
    @DisplayName("creerDemande — associationId null avec membreDemandeurId valide → branche L79 false couverte")
    void creerDemande_associationIdNull_l79FalseBranch() {
        UUID membreId = UUID.randomUUID();

        // Stub findById (appel réel à L73) pour que demandeur != null → L72 true branch
        // puis continuer jusqu'à L79 avec associationId=null → L79 false branch couverte
        dev.lions.unionflow.server.entity.Membre membre = new dev.lions.unionflow.server.entity.Membre();
        membre.setId(membreId);
        org.mockito.Mockito.when(membreRepository.findById(membreId)).thenReturn(membre);

        // associationId=null → L79: if (request.associationId() != null) → false → skip → branche false couverte
        CreateDemandeAideRequest request = CreateDemandeAideRequest.builder()
                .typeAide(TypeAide.DON_MATERIEL)
                .titre("Test L79 false branch")
                .description("Description test")
                .membreDemandeurId(membreId)
                .associationId(null)
                .build();

        assertThatThrownBy(() -> demandeAideService.creerDemande(request))
                .isInstanceOf(Exception.class);
    }
}
