package dev.lions.unionflow.server.service;

import dev.lions.unionflow.server.entity.Ticket;
import dev.lions.unionflow.server.repository.TicketRepository;
import io.quarkus.test.junit.QuarkusTest;
import io.quarkus.test.TestTransaction;
import jakarta.inject.Inject;
import jakarta.ws.rs.NotFoundException;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Method;
import java.util.UUID;

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

/**
 * Tests de couverture complémentaires pour TicketService.
 * Couvre :
 *  - la branche !ticket.getActif() dans obtenirTicket()
 *  - la branche null dans les méthodes privées toResponse() et toEntity()
 */
@QuarkusTest
class TicketServiceCoverageTest {

    @Inject
    TicketService ticketService;

    @Inject
    TicketRepository ticketRepository;

    @Test
    @TestTransaction
    @DisplayName("obtenirTicket avec ticket inactif lance NotFoundException")
    void obtenirTicket_ticketInactif_throwsNotFoundException() {
        // Créer un ticket avec actif = false
        Ticket ticket = new Ticket();
        ticket.setNumeroTicket("TKT-INACTIVE-" + UUID.randomUUID().toString().substring(0, 8));
        ticket.setUtilisateurId(UUID.randomUUID());
        ticket.setSujet("Ticket inactif");
        ticket.setStatut("FERME");
        ticket.setActif(false);
        ticket.setNbMessages(0);
        ticket.setNbFichiers(0);
        ticketRepository.persist(ticket);

        UUID ticketId = ticket.getId();

        // Même si le ticket existe en DB, il doit lancer NotFoundException car actif = false
        assertThatThrownBy(() -> ticketService.obtenirTicket(ticketId))
                .isInstanceOf(NotFoundException.class)
                .hasMessageContaining(ticketId.toString());
    }

    @Test
    @TestTransaction
    @DisplayName("obtenirTicket avec ticket actif → retourne le TicketResponse (branche return toResponse, L45)")
    void obtenirTicket_ticketActif_retourneResponse() {
        // Couvre la branche true du if : ticket != null && ticket.getActif() = true → return toResponse(ticket) (L45)
        Ticket ticket = new Ticket();
        ticket.setNumeroTicket("TKT-ACTIF-" + UUID.randomUUID().toString().substring(0, 8));
        ticket.setUtilisateurId(UUID.randomUUID());
        ticket.setSujet("Ticket actif pour couverture L45");
        ticket.setStatut("OUVERT");
        ticket.setActif(true);
        ticket.setNbMessages(0);
        ticket.setNbFichiers(0);
        ticketRepository.persist(ticket);

        UUID ticketId = ticket.getId();

        // ticket actif → passe le if → return toResponse(ticket) (L45)
        var response = ticketService.obtenirTicket(ticketId);

        assertThat(response).isNotNull();
        assertThat(response.getSujet()).isEqualTo("Ticket actif pour couverture L45");
    }

    @Test
    @DisplayName("toResponse(null) retourne null (branche défensive)")
    void toResponse_null_returnsNull() throws Exception {
        Method toResponse = TicketService.class.getDeclaredMethod("toResponse", Ticket.class);
        toResponse.setAccessible(true);
        Object result = toResponse.invoke(ticketService, (Object) null);
        assertThat(result).isNull();
    }

    @Test
    @DisplayName("toEntity(null) retourne null (branche défensive)")
    void toEntity_null_returnsNull() throws Exception {
        Method toEntity = TicketService.class.getDeclaredMethod("toEntity",
                dev.lions.unionflow.server.api.dto.ticket.request.CreateTicketRequest.class);
        toEntity.setAccessible(true);
        Object result = toEntity.invoke(ticketService, (Object) null);
        assertThat(result).isNull();
    }
}
