package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.ConversationService;
import dev.lions.unionflow.client.service.MessageService;
import dev.lions.unionflow.server.api.dto.communication.request.CreateConversationRequest;
import dev.lions.unionflow.server.api.dto.communication.request.SendMessageRequest;
import dev.lions.unionflow.server.api.dto.communication.response.ConversationResponse;
import dev.lions.unionflow.server.api.dto.communication.response.MessageResponse;
import dev.lions.unionflow.server.api.enums.communication.ConversationType;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.SessionScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Inject;
import jakarta.inject.Named;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.eclipse.microprofile.rest.client.inject.RestClient;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.logging.Logger;

@Named("messagingBean")
@SessionScoped
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class MessagingBean implements Serializable {

    private static final Logger LOGGER = Logger.getLogger(MessagingBean.class.getName());

    @Inject
    @RestClient
    private ConversationService conversationService;

    @Inject
    @RestClient
    private MessageService messageService;

    @Inject
    private UserSession userSession;

    private List<ConversationResponse> conversations = new ArrayList<>();
    private List<MessageResponse> messagesConversationActive = new ArrayList<>();
    private ConversationResponse conversationActive;
    private NouvelleConversation nouvelleConversation = new NouvelleConversation();
    private String contenuMessage;
    private int pageConversations = 0;
    private int taille = 20;

    @PostConstruct
    public void init() {
        chargerConversations();
    }

    public void chargerConversations() {
        try {
            conversations = conversationService.listerConversations(pageConversations, taille);
        } catch (Exception e) {
            LOGGER.severe("Erreur chargement conversations: " + e.getMessage());
            conversations = new ArrayList<>();
            ajouterMessageErreur("Impossible de charger les conversations.");
        }
    }

    public void ouvrirConversation(ConversationResponse conversation) {
        this.conversationActive = conversation;
        chargerMessages(conversation.getId());
        try {
            conversationService.marquerCommeLue(conversation.getId());
        } catch (Exception e) {
            LOGGER.warning("Impossible de marquer comme lue: " + e.getMessage());
        }
    }

    public void chargerMessages(UUID conversationId) {
        try {
            messagesConversationActive = messageService.listerMessages(conversationId, 50);
        } catch (Exception e) {
            LOGGER.severe("Erreur chargement messages: " + e.getMessage());
            messagesConversationActive = new ArrayList<>();
            ajouterMessageErreur("Impossible de charger les messages.");
        }
    }

    public void envoyerMessage() {
        if (conversationActive == null || contenuMessage == null || contenuMessage.isBlank()) {
            return;
        }
        try {
            SendMessageRequest request = SendMessageRequest.builder()
                .conversationId(conversationActive.getId())
                .content(contenuMessage.trim())
                .build();
            MessageResponse envoye = messageService.envoyer(request);
            messagesConversationActive.add(envoye);
            contenuMessage = null;
        } catch (Exception e) {
            LOGGER.severe("Erreur envoi message: " + e.getMessage());
            ajouterMessageErreur("Impossible d'envoyer le message.");
        }
    }

    public void creerConversation() {
        try {
            List<UUID> participantIds = new ArrayList<>();
            if (nouvelleConversation.participantsIds != null) {
                for (String id : nouvelleConversation.participantsIds.split(",")) {
                    String trimmed = id.trim();
                    if (!trimmed.isEmpty()) {
                        participantIds.add(UUID.fromString(trimmed));
                    }
                }
            }
            CreateConversationRequest request = CreateConversationRequest.builder()
                .name(nouvelleConversation.nom)
                .description(nouvelleConversation.description)
                .type(ConversationType.valueOf(nouvelleConversation.type))
                .participantIds(participantIds)
                .build();
            ConversationResponse creee = conversationService.creer(request);
            conversations.add(0, creee);
            nouvelleConversation = new NouvelleConversation();
            ajouterMessageSucces("Conversation créée.");
        } catch (Exception e) {
            LOGGER.severe("Erreur création conversation: " + e.getMessage());
            ajouterMessageErreur("Impossible de créer la conversation.");
        }
    }

    public void archiverConversation(ConversationResponse conversation) {
        try {
            conversationService.archiver(conversation.getId(), !conversation.isArchived());
            chargerConversations();
        } catch (Exception e) {
            ajouterMessageErreur("Impossible de modifier la conversation.");
        }
    }

    public void basculerSilence(ConversationResponse conversation) {
        try {
            conversationService.basculerSilence(conversation.getId());
            chargerConversations();
        } catch (Exception e) {
            ajouterMessageErreur("Impossible de modifier le silence.");
        }
    }

    public void basculerEpinglage(ConversationResponse conversation) {
        try {
            conversationService.basculerEpinglage(conversation.getId());
            chargerConversations();
        } catch (Exception e) {
            ajouterMessageErreur("Impossible de modifier l'épinglage.");
        }
    }

    public void supprimerMessage(MessageResponse message) {
        try {
            messageService.supprimer(message.getId());
            messagesConversationActive.remove(message);
            ajouterMessageSucces("Message supprimé.");
        } catch (Exception e) {
            ajouterMessageErreur("Impossible de supprimer le message.");
        }
    }

    public void actualiser() {
        chargerConversations();
        if (conversationActive != null) {
            chargerMessages(conversationActive.getId());
        }
    }

    public String getStatusSeverity(String status) {
        if (status == null) return "info";
        return switch (status) {
            case "READ" -> "success";
            case "FAILED" -> "danger";
            default -> "info";
        };
    }

    private void ajouterMessageSucces(String detail) {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_INFO, "Succès", detail));
    }

    private void ajouterMessageErreur(String detail) {
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", detail));
    }

    @Data
    public static class NouvelleConversation {
        private String nom;
        private String description;
        private String type = "GROUP";
        private String participantsIds;
    }
}
