package dev.lions.unionflow.server.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;

import dev.lions.unionflow.server.api.dto.solidarite.request.CreateDemandeAideRequest;
import dev.lions.unionflow.server.api.dto.solidarite.response.DemandeAideResponse;
import dev.lions.unionflow.server.api.enums.solidarite.PrioriteAide;
import dev.lions.unionflow.server.api.enums.solidarite.StatutAide;
import dev.lions.unionflow.server.api.enums.solidarite.TypeAide;
import dev.lions.unionflow.server.entity.DemandeAide;
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 io.quarkus.test.InjectMock;
import io.quarkus.test.junit.QuarkusTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

/**
 * Tests avec mocks pour couvrir la lambda lambda$obtenirDemandesEnRetard$2
 * (demande -> !demande.estTerminee()) qui nécessite que dateLimiteTraitement
 * soit dans le passé (estDelaiDepasse() == true) pour être atteinte.
 */
@QuarkusTest
class DemandeAideServiceMockTest {

    @Inject
    DemandeAideService demandeAideService;

    @InjectMock
    DemandeAideRepository demandeAideRepository;

    @InjectMock
    DemandeAideMapper demandeAideMapper;

    @InjectMock
    MembreRepository membreRepository;

    @InjectMock
    OrganisationRepository organisationRepository;

    @Test
    @DisplayName("obtenirDemandesEnRetard: lambda$2 !estTerminee() = true — demande en retard non terminée retournée")
    void obtenirDemandesEnRetard_lambdaEstTerminee_false_retourneDemande() {
        UUID orgId = UUID.randomUUID();

        // Demande avec dateLimiteTraitement dans le passé → estDelaiDepasse() = true
        // et statut non-final → !estTerminee() = true → passe le filtre
        DemandeAideResponse response = new DemandeAideResponse();
        response.setAssociationId(orgId);
        response.setStatut(StatutAide.EN_ATTENTE);
        response.setDateLimiteTraitement(LocalDateTime.now().minusDays(2)); // passé → estDelaiDepasse true

        DemandeAide entity = new DemandeAide();
        when(demandeAideRepository.listAll()).thenReturn(List.of(entity));
        when(demandeAideMapper.toDTO(any(DemandeAide.class))).thenReturn(response);

        List<DemandeAideResponse> result = demandeAideService.obtenirDemandesEnRetard(orgId);

        assertThat(result).hasSize(1);
        assertThat(result.get(0).getAssociationId()).isEqualTo(orgId);
    }

    @Test
    @DisplayName("obtenirDemandesEnRetard: lambda$2 !estTerminee() = false — demande terminée filtrée")
    void obtenirDemandesEnRetard_lambdaEstTerminee_true_filtreeLaDemande() {
        UUID orgId = UUID.randomUUID();

        // Demande avec dateLimiteTraitement dans le passé → estDelaiDepasse() = true
        // mais statut final → !estTerminee() = false → filtrée
        DemandeAideResponse response = new DemandeAideResponse();
        response.setAssociationId(orgId);
        response.setStatut(StatutAide.VERSEE); // statut final → estTerminee() = true
        response.setDateLimiteTraitement(LocalDateTime.now().minusDays(1)); // passé → estDelaiDepasse true

        DemandeAide entity = new DemandeAide();
        when(demandeAideRepository.listAll()).thenReturn(List.of(entity));
        when(demandeAideMapper.toDTO(any(DemandeAide.class))).thenReturn(response);

        List<DemandeAideResponse> result = demandeAideService.obtenirDemandesEnRetard(orgId);

        assertThat(result).isEmpty();
    }


}
