package dev.lions.unionflow.server.service;

import dev.lions.unionflow.server.api.dto.ticket.request.CreateTicketRequest;
import dev.lions.unionflow.server.api.dto.ticket.response.TicketResponse;
import dev.lions.unionflow.server.entity.Ticket;
import dev.lions.unionflow.server.repository.TicketRepository;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.transaction.Transactional;
import org.jboss.logging.Logger;

import jakarta.ws.rs.NotFoundException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Service métier pour la gestion des tickets support
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@ApplicationScoped
public class TicketService {

    private static final Logger LOG = Logger.getLogger(TicketService.class);

    @Inject
    TicketRepository ticketRepository;

    public List<TicketResponse> listerTickets(UUID utilisateurId) {
        LOG.infof("Récupération des tickets pour l'utilisateur %s", utilisateurId);
        List<Ticket> tickets = ticketRepository.findByUtilisateurId(utilisateurId);
        return tickets.stream()
                .map(this::toResponse)
                .collect(Collectors.toList());
    }

    public TicketResponse obtenirTicket(UUID id) {
        LOG.infof("Récupération du ticket %s", id);
        Ticket ticket = ticketRepository.findById(id);
        if (ticket == null || !ticket.getActif()) {
            throw new NotFoundException("Ticket non trouvé avec l'ID: " + id);
        }
        return toResponse(ticket);
    }

    @Transactional
    public TicketResponse creerTicket(CreateTicketRequest request) {
        LOG.infof("Création d'un ticket pour l'utilisateur %s", request.utilisateurId());

        Ticket ticket = toEntity(request);
        ticket.setNumeroTicket(ticketRepository.genererNumeroTicket());
        ticket.setDateCreation(LocalDateTime.now());
        ticket.setStatut("OUVERT");
        ticket.setNbMessages(0);
        ticket.setNbFichiers(0);

        ticketRepository.persist(ticket);
        LOG.infof("Ticket créé avec succès: %s", ticket.getNumeroTicket());

        return toResponse(ticket);
    }

    public Map<String, Object> obtenirStatistiques(UUID utilisateurId) {
        LOG.infof("Récupération des statistiques des tickets pour l'utilisateur %s", utilisateurId);
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalTickets", ticketRepository.countByStatutAndUtilisateurId(null, utilisateurId));
        stats.put("ticketsEnAttente", ticketRepository.countByStatutAndUtilisateurId("EN_ATTENTE", utilisateurId));
        stats.put("ticketsResolus", ticketRepository.countByStatutAndUtilisateurId("RESOLU", utilisateurId));
        stats.put("ticketsFermes", ticketRepository.countByStatutAndUtilisateurId("FERME", utilisateurId));
        return stats;
    }

    // Mappers Entity <-> DTO (DRY/WOU)
    private TicketResponse toResponse(Ticket ticket) {
        if (ticket == null)
            return null;
        TicketResponse response = TicketResponse.builder()
                .numeroTicket(ticket.getNumeroTicket())
                .utilisateurId(ticket.getUtilisateurId())
                .sujet(ticket.getSujet())
                .description(ticket.getDescription())
                .categorie(ticket.getCategorie())
                .priorite(ticket.getPriorite())
                .statut(ticket.getStatut())
                .agentId(ticket.getAgentId())
                .agentNom(ticket.getAgentNom())
                .dateDerniereReponse(ticket.getDateDerniereReponse())
                .dateResolution(ticket.getDateResolution())
                .dateFermeture(ticket.getDateFermeture())
                .nbMessages(ticket.getNbMessages())
                .nbFichiers(ticket.getNbFichiers())
                .noteSatisfaction(ticket.getNoteSatisfaction())
                .resolution(ticket.getResolution())
                .build();
        response.setId(ticket.getId());
        response.setDateCreation(ticket.getDateCreation());
        response.setDateModification(ticket.getDateModification());
        response.setActif(ticket.getActif());
        response.setVersion(ticket.getVersion());
        return response;
    }

    private Ticket toEntity(CreateTicketRequest dto) {
        if (dto == null)
            return null;
        Ticket ticket = new Ticket();
        ticket.setUtilisateurId(dto.utilisateurId());
        ticket.setSujet(dto.sujet());
        ticket.setDescription(dto.description());
        ticket.setCategorie(dto.categorie());
        ticket.setPriorite(dto.priorite());
        return ticket;
    }
}
