package dev.lions.unionflow.client.view;

import dev.lions.unionflow.client.dto.MembreDTO;
import dev.lions.unionflow.client.dto.AssociationDTO;
import dev.lions.unionflow.client.service.MembreService;
import dev.lions.unionflow.client.service.AssociationService;
import dev.lions.unionflow.client.service.ValidationService;
import dev.lions.unionflow.client.view.SouscriptionBean;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import jakarta.inject.Inject;
import jakarta.annotation.PostConstruct;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import org.eclipse.microprofile.rest.client.inject.RestClient;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Named("membreInscriptionBean")
@RequestScoped
public class MembreInscriptionBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    @Inject
    @RestClient
    MembreService membreService;
    
    @Inject
    @RestClient
    AssociationService associationService;
    
    @Inject
    ValidationService validationService;
    
    @Inject
    SouscriptionBean souscriptionBean;
    
    // Propriétés système
    private String numeroGenere;
    
    // Informations personnelles
    private String prenom;
    private String nom;
    private String email;
    private String telephone;
    private String telephoneMobile;
    private String adresse;
    private String ville;
    private String codePostal;
    private String pays = "Sénégal";
    private LocalDate dateNaissance;
    private String lieuNaissance;
    private String nationalite = "Sénégalaise";
    private String sexe;
    private String situationMatrimoniale;
    private String profession;
    private String employeur;
    
    // Informations d'urgence
    private String contactUrgenceNom;
    private String contactUrgenceTelephone;
    private String contactUrgenceLien;
    
    // Informations bancaires
    private String numeroBanque;
    private String nomBanque;
    private String ribIban;
    
    // Informations adhésion
    private String typeAdhesion;
    private String numeroParrain;
    private String nomParrain;
    private String motifAdhesion;
    private String organisationId; // ID de l'organisation choisie
    private String organisationNom; // Nom de l'organisation affichée
    private boolean accepteReglement = false;
    private boolean acceptePrelevement = false;
    private boolean autorisationMarketing = false;
    
    // Statut de validation
    private String statutValidation = "EN_ATTENTE"; // EN_ATTENTE, VALIDE, REFUSE
    
    // Informations complémentaires
    private String competencesSpeciales;
    private String centresInteret;
    private String commentaires;
    
    // Photo et documents
    private String photoPath;
    private List<String> documentsJoints = new ArrayList<>();
    private org.primefaces.model.file.UploadedFile uploadedPhoto;
    private String photoBase64;
    
    public MembreInscriptionBean() {
        // Initialisation par défaut
    }
    
    @PostConstruct
    public void init() {
        // Générer un numéro de membre automatiquement
        this.numeroGenere = "M" + System.currentTimeMillis();
    }
    
    // Actions
    public String inscrire() {
        try {
            // Vérifier d'abord si l'organisation peut accepter de nouveaux membres
            if (!peutAccepterNouveauMembre()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                    "Quota atteint", "Cette organisation a atteint son quota maximum de membres.");
                FacesContext.getCurrentInstance().addMessage(null, message);
                return null;
            }
            
            // Créer le DTO membre
            MembreDTO nouveauMembre = new MembreDTO();
            nouveauMembre.setNumeroMembre(numeroGenere);
            nouveauMembre.setNom(nom);
            nouveauMembre.setPrenom(prenom);
            nouveauMembre.setEmail(email);
            nouveauMembre.setTelephone(telephone);
            nouveauMembre.setDateNaissance(dateNaissance);
            nouveauMembre.setAdresse(adresse);
            nouveauMembre.setProfession(profession);
            nouveauMembre.setStatutMatrimonial(situationMatrimoniale);
            nouveauMembre.setNationalite(nationalite);
            nouveauMembre.setStatut(statutValidation); // Statut d'attente par défaut
            nouveauMembre.setDateInscription(LocalDateTime.now());
            
            // Validation des données
            ValidationService.ValidationResult validationResult = validationService.validate(nouveauMembre);
            if (!validationResult.isValid()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                    "Erreurs de validation", validationResult.getFirstErrorMessage());
                FacesContext.getCurrentInstance().addMessage(null, message);
                return null;
            }
            
            // Appel du service REST pour créer le membre
            MembreDTO membreCreee = membreService.creer(nouveauMembre);
            
            // Gestion de la photo si disponible
            if (photoBase64 != null && !photoBase64.trim().isEmpty()) {
                System.out.println("Photo cadrée reçue: " + photoBase64.length() + " caractères");
                // TODO: Appeler service de sauvegarde de photo
            }
            
            System.out.println("Membre inscrit avec succès: " + membreCreee.getNomComplet());
            
            // Message de succès
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, 
                "Inscription soumise", "Votre inscription a été soumise avec succès. Elle sera validée par l'administrateur de votre organisation.");
            FacesContext.getCurrentInstance().addMessage(null, message);
            
            return "/pages/public/login?faces-redirect=true";
            
        } catch (Exception e) {
            System.err.println("Erreur lors de l'inscription: " + e.getMessage());
            e.printStackTrace();
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, 
                "Erreur", "Erreur lors de l'inscription: " + e.getMessage());
            FacesContext.getCurrentInstance().addMessage(null, message);
            return null;
        }
    }
    
    // Méthodes de validation en temps réel
    public void validateNom() {
        if (nom != null && !nom.trim().isEmpty()) {
            ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "nom", nom);
            if (!result.isValid()) {
                System.out.println("Erreur validation nom: " + result.getFirstErrorMessage());
            }
        }
    }
    
    public void validatePrenom() {
        if (prenom != null && !prenom.trim().isEmpty()) {
            ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "prenom", prenom);
            if (!result.isValid()) {
                System.out.println("Erreur validation prénom: " + result.getFirstErrorMessage());
            }
        }
    }
    
    public void validateEmail() {
        if (email != null && !email.trim().isEmpty()) {
            ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "email", email);
            if (!result.isValid()) {
                System.out.println("Erreur validation email: " + result.getFirstErrorMessage());
            }
        }
    }
    
    public void validateTelephone() {
        if (telephone != null && !telephone.trim().isEmpty()) {
            ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "telephone", telephone);
            if (!result.isValid()) {
                System.out.println("Erreur validation téléphone: " + result.getFirstErrorMessage());
            }
        }
    }
    
    public String annuler() {
        return "/pages/secure/dashboard?faces-redirect=true";
    }
    
    public void handleFileUpload(org.primefaces.event.FileUploadEvent event) {
        // Logique d'upload de documents
        org.primefaces.model.file.UploadedFile file = event.getFile();
        if (file != null) {
            documentsJoints.add(file.getFileName());
        }
    }
    
    public void ajouterDocument() {
        // Logique d'ajout de document
    }
    
    public void supprimerDocument(String document) {
        documentsJoints.remove(document);
    }
    
    public void rechercherParrain() {
        // Logique de recherche de parrain
        if (numeroParrain != null && !numeroParrain.trim().isEmpty()) {
            // Simulation de recherche
            nomParrain = "Membre trouvé - " + numeroParrain;
        }
    }
    
    public String enregistrerBrouillon() {
        // Logique d'enregistrement en brouillon
        return null; // Rester sur la même page
    }
    
    // Méthodes pour la progression
    public boolean isEtapePersonnelleComplete() {
        return prenom != null && !prenom.trim().isEmpty() &&
               nom != null && !nom.trim().isEmpty() &&
               dateNaissance != null &&
               sexe != null && !sexe.trim().isEmpty();
    }
    
    public boolean isEtapeCoordonneeComplete() {
        return adresse != null && !adresse.trim().isEmpty() &&
               ville != null && !ville.trim().isEmpty() &&
               email != null && !email.trim().isEmpty() &&
               telephoneMobile != null && !telephoneMobile.trim().isEmpty();
    }
    
    public boolean isEtapeAdhesionComplete() {
        return typeAdhesion != null && !typeAdhesion.trim().isEmpty();
    }
    
    public boolean isEtapeDocumentsComplete() {
        return !documentsJoints.isEmpty() || (photoBase64 != null && !photoBase64.trim().isEmpty());
    }
    
    public int getProgressionPourcentage() {
        int etapesCompletes = 0;
        if (isEtapePersonnelleComplete()) etapesCompletes++;
        if (isEtapeCoordonneeComplete()) etapesCompletes++;
        if (isEtapeAdhesionComplete()) etapesCompletes++;
        if (isEtapeDocumentsComplete()) etapesCompletes++;
        return (etapesCompletes * 100) / 4;
    }
    
    public boolean isFormulaireValide() {
        return isEtapePersonnelleComplete() && 
               isEtapeCoordonneeComplete() && 
               isEtapeAdhesionComplete() &&
               organisationId != null &&
               accepteReglement;
    }
    
    // Vérification du quota organisation
    public boolean peutAccepterNouveauMembre() {
        if (souscriptionBean == null || souscriptionBean.getSouscriptionActive() == null) {
            return false; // Pas de souscription active
        }
        return souscriptionBean.peutAccepterNouveauMembre();
    }
    
    public String getMessageQuotaOrganisation() {
        if (souscriptionBean != null) {
            return souscriptionBean.getMessageQuota();
        }
        return "Informations de quota non disponibles";
    }
    
    // Getters et Setters
    public String getNumeroGenere() { return numeroGenere; }
    public void setNumeroGenere(String numeroGenere) { this.numeroGenere = numeroGenere; }
    
    public String getPrenom() { return prenom; }
    public void setPrenom(String prenom) { this.prenom = prenom; }
    
    public String getNom() { return nom; }
    public void setNom(String nom) { this.nom = nom; }
    
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    public String getTelephone() { return telephone; }
    public void setTelephone(String telephone) { this.telephone = telephone; }
    
    public String getTelephoneMobile() { return telephoneMobile; }
    public void setTelephoneMobile(String telephoneMobile) { this.telephoneMobile = telephoneMobile; }
    
    public String getAdresse() { return adresse; }
    public void setAdresse(String adresse) { this.adresse = adresse; }
    
    public String getVille() { return ville; }
    public void setVille(String ville) { this.ville = ville; }
    
    public String getCodePostal() { return codePostal; }
    public void setCodePostal(String codePostal) { this.codePostal = codePostal; }
    
    public String getPays() { return pays; }
    public void setPays(String pays) { this.pays = pays; }
    
    public LocalDate getDateNaissance() { return dateNaissance; }
    public void setDateNaissance(LocalDate dateNaissance) { this.dateNaissance = dateNaissance; }
    
    public String getLieuNaissance() { return lieuNaissance; }
    public void setLieuNaissance(String lieuNaissance) { this.lieuNaissance = lieuNaissance; }
    
    public String getNationalite() { return nationalite; }
    public void setNationalite(String nationalite) { this.nationalite = nationalite; }
    
    public String getSexe() { return sexe; }
    public void setSexe(String sexe) { this.sexe = sexe; }
    
    public String getSituationMatrimoniale() { return situationMatrimoniale; }
    public void setSituationMatrimoniale(String situationMatrimoniale) { this.situationMatrimoniale = situationMatrimoniale; }
    
    public String getProfession() { return profession; }
    public void setProfession(String profession) { this.profession = profession; }
    
    public String getEmployeur() { return employeur; }
    public void setEmployeur(String employeur) { this.employeur = employeur; }
    
    public String getContactUrgenceNom() { return contactUrgenceNom; }
    public void setContactUrgenceNom(String contactUrgenceNom) { this.contactUrgenceNom = contactUrgenceNom; }
    
    public String getContactUrgenceTelephone() { return contactUrgenceTelephone; }
    public void setContactUrgenceTelephone(String contactUrgenceTelephone) { this.contactUrgenceTelephone = contactUrgenceTelephone; }
    
    public String getContactUrgenceLien() { return contactUrgenceLien; }
    public void setContactUrgenceLien(String contactUrgenceLien) { this.contactUrgenceLien = contactUrgenceLien; }
    
    public String getNumeroBanque() { return numeroBanque; }
    public void setNumeroBanque(String numeroBanque) { this.numeroBanque = numeroBanque; }
    
    public String getNomBanque() { return nomBanque; }
    public void setNomBanque(String nomBanque) { this.nomBanque = nomBanque; }
    
    public String getRibIban() { return ribIban; }
    public void setRibIban(String ribIban) { this.ribIban = ribIban; }
    
    public String getTypeAdhesion() { return typeAdhesion; }
    public void setTypeAdhesion(String typeAdhesion) { this.typeAdhesion = typeAdhesion; }
    
    public String getNumeroParrain() { return numeroParrain; }
    public void setNumeroParrain(String numeroParrain) { this.numeroParrain = numeroParrain; }
    
    public String getNomParrain() { return nomParrain; }
    public void setNomParrain(String nomParrain) { this.nomParrain = nomParrain; }
    
    public String getMotifAdhesion() { return motifAdhesion; }
    public void setMotifAdhesion(String motifAdhesion) { this.motifAdhesion = motifAdhesion; }
    
    public boolean isAccepteReglement() { return accepteReglement; }
    public void setAccepteReglement(boolean accepteReglement) { this.accepteReglement = accepteReglement; }
    
    public boolean isAcceptePrelevement() { return acceptePrelevement; }
    public void setAcceptePrelevement(boolean acceptePrelevement) { this.acceptePrelevement = acceptePrelevement; }
    
    public boolean isAutorisationMarketing() { return autorisationMarketing; }
    public void setAutorisationMarketing(boolean autorisationMarketing) { this.autorisationMarketing = autorisationMarketing; }
    
    public String getCompetencesSpeciales() { return competencesSpeciales; }
    public void setCompetencesSpeciales(String competencesSpeciales) { this.competencesSpeciales = competencesSpeciales; }
    
    public String getCentresInteret() { return centresInteret; }
    public void setCentresInteret(String centresInteret) { this.centresInteret = centresInteret; }
    
    public String getCommentaires() { return commentaires; }
    public void setCommentaires(String commentaires) { this.commentaires = commentaires; }
    
    public String getPhotoPath() { return photoPath; }
    public void setPhotoPath(String photoPath) { this.photoPath = photoPath; }
    
    public List<String> getDocumentsJoints() { return documentsJoints; }
    public void setDocumentsJoints(List<String> documentsJoints) { this.documentsJoints = documentsJoints; }
    
    public org.primefaces.model.file.UploadedFile getUploadedPhoto() { return uploadedPhoto; }
    public void setUploadedPhoto(org.primefaces.model.file.UploadedFile uploadedPhoto) { this.uploadedPhoto = uploadedPhoto; }
    
    public String getPhotoBase64() { return photoBase64; }
    public void setPhotoBase64(String photoBase64) { this.photoBase64 = photoBase64; }
    
    public String getOrganisationId() { return organisationId; }
    public void setOrganisationId(String organisationId) { this.organisationId = organisationId; }
    
    public String getOrganisationNom() { return organisationNom; }
    public void setOrganisationNom(String organisationNom) { this.organisationNom = organisationNom; }
    
    public String getStatutValidation() { return statutValidation; }
    public void setStatutValidation(String statutValidation) { this.statutValidation = statutValidation; }
    
    // Listes pour les sélections
    public List<String> getSexeOptions() {
        List<String> options = new ArrayList<>();
        options.add("Masculin");
        options.add("Féminin");
        return options;
    }
    
    public List<String> getSituationMatrimonialeOptions() {
        List<String> options = new ArrayList<>();
        options.add("Célibataire");
        options.add("Marié(e)");
        options.add("Divorcé(e)");
        options.add("Veuf(ve)");
        return options;
    }
    
    public List<String> getTypeAdhesionOptions() {
        List<String> options = new ArrayList<>();
        options.add("Membre actif");
        options.add("Membre associé");
        options.add("Membre bienfaiteur");
        options.add("Membre honoraire");
        return options;
    }
    
    public List<String> getContactUrgenceLienOptions() {
        List<String> options = new ArrayList<>();
        options.add("Conjoint(e)");
        options.add("Parent");
        options.add("Enfant");
        options.add("Frère/Sœur");
        options.add("Ami(e)");
        options.add("Autre");
        return options;
    }
}