package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.service.DocumentService;
import dev.lions.unionflow.server.api.dto.document.request.*;
import dev.lions.unionflow.server.api.dto.document.response.*;
import dev.lions.unionflow.server.api.dto.document.request.*;
import dev.lions.unionflow.server.api.dto.document.response.*;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;
import jakarta.inject.Inject;
import jakarta.annotation.PostConstruct;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import org.jboss.logging.Logger;
import org.primefaces.model.file.UploadedFile;
import dev.lions.unionflow.client.service.ErrorHandlerService;
import dev.lions.unionflow.client.service.RetryService;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * Bean JSF pour la gestion documentaire personnelle
 * 
 * @author UnionFlow Team
 * @version 1.0
 */
@Named("documentBean")
@ViewScoped
public class DocumentBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    private static final Logger LOG = Logger.getLogger(DocumentBean.class);
    
    @Inject
    @RestClient
    private DocumentService documentService;
    
    @Inject
    private UserSession userSession;
    
    @Inject
    ErrorHandlerService errorHandler;
    
    @Inject
    RetryService retryService;
    
    // Données
    private List<DocumentResponse> documents = new ArrayList<>();
    private DocumentResponse documentSelectionne;
    private List<PieceJointeResponse> piecesJointes = new ArrayList<>();
    
    // Filtres
    private String rechercheTexte = "";
    
    // Upload
    private UploadedFile fichierUpload;
    private DocumentResponse nouveauDocument = new DocumentResponse();
    
    @PostConstruct
    public void init() {
        chargerDocuments();
    }
    
    public void chargerDocuments() {
        try {
            documents = retryService.executeWithRetrySupplier(
                () -> documentService.mesDocuments(),
                "chargement des documents"
            );
            if (documents == null) {
                documents = new ArrayList<>();
            }
            LOG.infof("Documents chargés: %d", documents.size());
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors du chargement des documents");
            errorHandler.handleException(e, "lors du chargement des documents", null);
            documents = new ArrayList<>();
        }
    }
    
    public void chargerPiecesJointes() {
        if (documentSelectionne != null) {
            try {
                piecesJointes = retryService.executeWithRetrySupplier(
                    () -> documentService.listerPiecesJointes(documentSelectionne.getId()),
                    "chargement des pièces jointes"
                );
            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors du chargement des pièces jointes");
                piecesJointes = new ArrayList<>();
            }
        }
    }
    
    public void voirDetailsDocument() {
        if (documentSelectionne != null) {
            try {
                documentSelectionne = retryService.executeWithRetrySupplier(
                    () -> documentService.obtenirDocument(documentSelectionne.getId()),
                    "récupération des détails d'un document"
                );
                chargerPiecesJointes();
            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors de la récupération du document");
                errorHandler.handleException(e, "lors de la récupération d'un document", null);
            }
        }
    }
    
    public void telechargerDocument() {
        if (documentSelectionne != null) {
            try {
                retryService.executeWithRetrySupplier(
                    () -> {
                        documentService.enregistrerTelechargement(documentSelectionne.getId());
                        return null;
                    },
                    "enregistrement d'un téléchargement"
                );
                errorHandler.showSuccess("Succès", "Téléchargement enregistré");
            } catch (Exception e) {
                LOG.errorf(e, "Erreur lors de l'enregistrement du téléchargement");
                errorHandler.handleException(e, "lors du téléchargement d'un document", null);
            }
        }
    }
    
    public void creerDocument() {
        try {
            CreateDocumentRequest.CreateDocumentRequestBuilder builder = CreateDocumentRequest.builder()
                    .cheminStockage("/uploads"); // Chemin par défaut

            if (fichierUpload != null) {
                builder.nomFichier(fichierUpload.getFileName())
                        .nomOriginal(fichierUpload.getFileName())
                        .tailleOctets(fichierUpload.getSize())
                        .typeMime(fichierUpload.getContentType());
            }

            CreateDocumentRequest request = builder.build();

            DocumentResponse documentCree = retryService.executeWithRetrySupplier(
                () -> documentService.creerDocument(request),
                "création d'un document"
            );
            documents.add(0, documentCree);
            fichierUpload = null;
            errorHandler.showSuccess("Succès", "Document créé avec succès");
        } catch (Exception e) {
            LOG.errorf(e, "Erreur lors de la création du document");
            errorHandler.handleException(e, "lors de la création d'un document", null);
        }
    }
    
    public List<DocumentResponse> getDocumentsFiltres() {
        if (rechercheTexte == null || rechercheTexte.trim().isEmpty()) {
            return documents;
        }
        String recherche = rechercheTexte.toLowerCase();
        return documents.stream()
            .filter(d -> (d.getNomFichier() != null && d.getNomFichier().toLowerCase().contains(recherche)) ||
                        (d.getDescription() != null && d.getDescription().toLowerCase().contains(recherche)))
            .collect(java.util.stream.Collectors.toList());
    }
    
    // Getters et Setters
    public List<DocumentResponse> getDocuments() { return documents; }
    public void setDocuments(List<DocumentResponse> documents) { this.documents = documents; }
    
    public DocumentResponse getDocumentSelectionne() { return documentSelectionne; }
    public void setDocumentSelectionne(DocumentResponse documentSelectionne) { 
        this.documentSelectionne = documentSelectionne;
        if (documentSelectionne != null) {
            chargerPiecesJointes();
        }
    }
    
    public List<PieceJointeResponse> getPiecesJointes() { return piecesJointes; }
    public void setPiecesJointes(List<PieceJointeResponse> piecesJointes) { this.piecesJointes = piecesJointes; }
    
    public String getRechercheTexte() { return rechercheTexte; }
    public void setRechercheTexte(String rechercheTexte) { this.rechercheTexte = rechercheTexte; }
    
    public UploadedFile getFichierUpload() { return fichierUpload; }
    public void setFichierUpload(UploadedFile fichierUpload) { this.fichierUpload = fichierUpload; }
    
    public DocumentResponse getNouveauDocument() { return nouveauDocument; }
    public void setNouveauDocument(DocumentResponse nouveauDocument) { this.nouveauDocument = nouveauDocument; }
    
}

