package dev.lions.unionflow.client.view;

import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import jakarta.annotation.PostConstruct;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Named("utilisateursBean")
@SessionScoped
public class UtilisateursBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private List<Utilisateur> tousLesUtilisateurs;
    private List<Utilisateur> utilisateursFiltres;
    private List<Utilisateur> utilisateursSelectionnes;
    private List<Organisation> organisationsDisponibles;
    
    private Utilisateur utilisateurSelectionne;
    private NouvelUtilisateur nouvelUtilisateur;
    private Filtres filtres;
    private StatistiquesUtilisateurs statistiques;
    
    @PostConstruct
    public void init() {
        initializeFiltres();
        initializeStatistiques();
        initializeOrganisations();
        initializeUtilisateurs();
        initializeNouvelUtilisateur();
        appliquerFiltres();
    }
    
    private void initializeFiltres() {
        filtres = new Filtres();
        utilisateursSelectionnes = new ArrayList<>();
    }
    
    private void initializeStatistiques() {
        statistiques = new StatistiquesUtilisateurs();
        statistiques.setTotalUtilisateurs(47);
        statistiques.setUtilisateursConnectes(12);
        statistiques.setAdministrateurs(8);
        statistiques.setUtilisateursDesactives(3);
    }
    
    private void initializeOrganisations() {
        organisationsDisponibles = new ArrayList<>();
        
        Organisation org1 = new Organisation();
        org1.setId(1L);
        org1.setNom("Direction Générale");
        organisationsDisponibles.add(org1);
        
        Organisation org2 = new Organisation();
        org2.setId(2L);
        org2.setNom("Services Financiers");
        organisationsDisponibles.add(org2);
        
        Organisation org3 = new Organisation();
        org3.setId(3L);
        org3.setNom("Ressources Humaines");
        organisationsDisponibles.add(org3);
        
        Organisation org4 = new Organisation();
        org4.setId(4L);
        org4.setNom("Communication");
        organisationsDisponibles.add(org4);
    }
    
    private void initializeUtilisateurs() {
        tousLesUtilisateurs = new ArrayList<>();
        
        String[] noms = {
            "Koffi", "Asante", "Mensah", "Diallo", "Touré", "Koné", "Ouattara", "Traoré",
            "Sanogo", "Bakayoko", "Coulibaly", "Cissé", "Gyamfi", "Adjei", "Akoto",
            "Boateng", "Ofori", "Owusu", "Asamoah", "Yeboah"
        };
        
        String[] prenoms = {
            "Kwame", "Ama", "Kofi", "Akosua", "Yaw", "Adwoa", "Kweku", "Afia",
            "Kwadwo", "Akua", "Yaa", "Kwabena", "Efua", "Kojo", "Ama",
            "Kwesi", "Esi", "Kwaku", "Abena", "Fiifi"
        };
        
        String[] roles = {"USER", "GESTIONNAIRE", "ADMIN", "SUPER_ADMIN"};
        String[] statuts = {"ACTIF", "INACTIF", "SUSPENDU", "ATTENTE"};
        
        for (int i = 0; i < 30; i++) {
            Utilisateur utilisateur = new Utilisateur();
            utilisateur.setId((long) (i + 1));
            utilisateur.setNom(noms[i % noms.length]);
            utilisateur.setPrenom(prenoms[i % prenoms.length]);
            utilisateur.setEmail(prenoms[i % prenoms.length].toLowerCase() + "." + 
                               noms[i % noms.length].toLowerCase() + "@unionflow.org");
            utilisateur.setTelephone("+225 " + String.format("%02d", (i % 99) + 1) + " " + 
                                   String.format("%02d", (i % 99) + 1) + " " + 
                                   String.format("%02d", (i % 99) + 1) + " " + 
                                   String.format("%02d", (i % 99) + 1));
            utilisateur.setRole(roles[i % roles.length]);
            utilisateur.setStatut(statuts[i % statuts.length]);
            utilisateur.setOrganisationId(organisationsDisponibles.get(i % organisationsDisponibles.size()).getId());
            utilisateur.setDateCreation(LocalDateTime.now().minusDays(i + 1));
            
            // Dernière connexion variable
            if (i % 4 != 0) { // 75% des utilisateurs ont une dernière connexion
                utilisateur.setDerniereConnexion(LocalDateTime.now().minusHours(i + 1).minusMinutes(i * 5));
            }
            
            tousLesUtilisateurs.add(utilisateur);
        }
    }
    
    private void initializeNouvelUtilisateur() {
        nouvelUtilisateur = new NouvelUtilisateur();
        nouvelUtilisateur.setRole("USER");
        nouvelUtilisateur.setEnvoyerEmail(true);
    }
    
    private void appliquerFiltres() {
        utilisateursFiltres = tousLesUtilisateurs.stream()
                .filter(this::appliquerFiltre)
                .collect(Collectors.toList());
    }
    
    private boolean appliquerFiltre(Utilisateur utilisateur) {
        if (filtres.getRecherche() != null && !filtres.getRecherche().trim().isEmpty()) {
            String recherche = filtres.getRecherche().toLowerCase();
            if (!utilisateur.getNomComplet().toLowerCase().contains(recherche) &&
                !utilisateur.getEmail().toLowerCase().contains(recherche)) {
                return false;
            }
        }
        
        if (filtres.getRole() != null && !filtres.getRole().trim().isEmpty()) {
            if (!utilisateur.getRole().equals(filtres.getRole())) {
                return false;
            }
        }
        
        if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
            if (!utilisateur.getStatut().equals(filtres.getStatut())) {
                return false;
            }
        }
        
        if (filtres.getOrganisation() != null && !filtres.getOrganisation().toString().trim().isEmpty()) {
            if (!utilisateur.getOrganisationId().equals(filtres.getOrganisation())) {
                return false;
            }
        }
        
        return true;
    }
    
    // Actions
    public void rechercher() {
        appliquerFiltres();
    }
    
    public void reinitialiserFiltres() {
        filtres = new Filtres();
        appliquerFiltres();
    }
    
    public void creerUtilisateur() {
        Utilisateur nouvelUtil = new Utilisateur();
        nouvelUtil.setId((long) (tousLesUtilisateurs.size() + 1));
        nouvelUtil.setNom(nouvelUtilisateur.getNom());
        nouvelUtil.setPrenom(nouvelUtilisateur.getPrenom());
        nouvelUtil.setEmail(nouvelUtilisateur.getEmail());
        nouvelUtil.setTelephone(nouvelUtilisateur.getTelephone());
        nouvelUtil.setRole(nouvelUtilisateur.getRole());
        nouvelUtil.setOrganisationId(nouvelUtilisateur.getOrganisationId());
        nouvelUtil.setStatut("ACTIF");
        nouvelUtil.setDateCreation(LocalDateTime.now());
        
        tousLesUtilisateurs.add(nouvelUtil);
        appliquerFiltres();
        
        System.out.println("Nouvel utilisateur créé: " + nouvelUtil.getNomComplet());
        initializeNouvelUtilisateur();
    }
    
    public void activerUtilisateur(Utilisateur utilisateur) {
        utilisateur.setStatut("ACTIF");
        System.out.println("Utilisateur activé: " + utilisateur.getNomComplet());
        appliquerFiltres();
    }
    
    public void desactiverUtilisateur(Utilisateur utilisateur) {
        utilisateur.setStatut("INACTIF");
        System.out.println("Utilisateur désactivé: " + utilisateur.getNomComplet());
        appliquerFiltres();
    }
    
    public void exporterUtilisateurs() {
        System.out.println("Export de " + utilisateursFiltres.size() + " utilisateurs");
    }
    
    // Getters et Setters
    public List<Utilisateur> getTousLesUtilisateurs() { return tousLesUtilisateurs; }
    public void setTousLesUtilisateurs(List<Utilisateur> tousLesUtilisateurs) { this.tousLesUtilisateurs = tousLesUtilisateurs; }
    
    public List<Utilisateur> getUtilisateursFiltres() { return utilisateursFiltres; }
    public void setUtilisateursFiltres(List<Utilisateur> utilisateursFiltres) { this.utilisateursFiltres = utilisateursFiltres; }
    
    public List<Utilisateur> getUtilisateursSelectionnes() { return utilisateursSelectionnes; }
    public void setUtilisateursSelectionnes(List<Utilisateur> utilisateursSelectionnes) { this.utilisateursSelectionnes = utilisateursSelectionnes; }
    
    public List<Organisation> getOrganisationsDisponibles() { return organisationsDisponibles; }
    public void setOrganisationsDisponibles(List<Organisation> organisationsDisponibles) { this.organisationsDisponibles = organisationsDisponibles; }
    
    public Utilisateur getUtilisateurSelectionne() { return utilisateurSelectionne; }
    public void setUtilisateurSelectionne(Utilisateur utilisateurSelectionne) { this.utilisateurSelectionne = utilisateurSelectionne; }
    
    public NouvelUtilisateur getNouvelUtilisateur() { return nouvelUtilisateur; }
    public void setNouvelUtilisateur(NouvelUtilisateur nouvelUtilisateur) { this.nouvelUtilisateur = nouvelUtilisateur; }
    
    public Filtres getFiltres() { return filtres; }
    public void setFiltres(Filtres filtres) { this.filtres = filtres; }
    
    public StatistiquesUtilisateurs getStatistiques() { return statistiques; }
    public void setStatistiques(StatistiquesUtilisateurs statistiques) { this.statistiques = statistiques; }
    
    // Classes internes
    public static class Utilisateur {
        private Long id;
        private String nom;
        private String prenom;
        private String email;
        private String telephone;
        private String role;
        private String statut;
        private Long organisationId;
        private LocalDateTime dateCreation;
        private LocalDateTime derniereConnexion;
        
        // Getters et setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        
        public String getNom() { return nom; }
        public void setNom(String nom) { this.nom = nom; }
        
        public String getPrenom() { return prenom; }
        public void setPrenom(String prenom) { this.prenom = prenom; }
        
        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 getRole() { return role; }
        public void setRole(String role) { this.role = role; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public Long getOrganisationId() { return organisationId; }
        public void setOrganisationId(Long organisationId) { this.organisationId = organisationId; }
        
        public LocalDateTime getDateCreation() { return dateCreation; }
        public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; }
        
        public LocalDateTime getDerniereConnexion() { return derniereConnexion; }
        public void setDerniereConnexion(LocalDateTime derniereConnexion) { this.derniereConnexion = derniereConnexion; }
        
        // Propriétés dérivées
        public String getNomComplet() {
            return prenom + " " + nom;
        }
        
        public String getRoleLibelle() {
            return switch (role) {
                case "USER" -> "Utilisateur";
                case "GESTIONNAIRE" -> "Gestionnaire";
                case "ADMIN" -> "Administrateur";
                case "SUPER_ADMIN" -> "Super Admin";
                default -> role;
            };
        }
        
        public String getRoleSeverity() {
            return switch (role) {
                case "USER" -> "info";
                case "GESTIONNAIRE" -> "primary";
                case "ADMIN" -> "warning";
                case "SUPER_ADMIN" -> "danger";
                default -> "secondary";
            };
        }
        
        public String getStatutLibelle() {
            return switch (statut) {
                case "ACTIF" -> "Actif";
                case "INACTIF" -> "Inactif";
                case "SUSPENDU" -> "Suspendu";
                case "ATTENTE" -> "En attente";
                default -> statut;
            };
        }
        
        public String getStatutSeverity() {
            return switch (statut) {
                case "ACTIF" -> "success";
                case "INACTIF" -> "secondary";
                case "SUSPENDU" -> "danger";
                case "ATTENTE" -> "warning";
                default -> "secondary";
            };
        }
        
        public String getOrganisationNom() {
            // Simulation - en réalité, on ferait un lookup dans la base
            return switch (organisationId.toString()) {
                case "1" -> "Direction Générale";
                case "2" -> "Services Financiers";
                case "3" -> "Ressources Humaines";
                case "4" -> "Communication";
                default -> "Non définie";
            };
        }
        
        public String getDateCreationFormatee() {
            if (dateCreation == null) return "";
            return dateCreation.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        }
        
        public String getDerniereConnexionFormatee() {
            if (derniereConnexion == null) return "Jamais";
            return derniereConnexion.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"));
        }
        
        public String getDerniereConnexionRelative() {
            if (derniereConnexion == null) return "Jamais connecté";
            long jours = ChronoUnit.DAYS.between(derniereConnexion, LocalDateTime.now());
            if (jours == 0) return "Aujourd'hui";
            if (jours == 1) return "Hier";
            if (jours < 7) return "Il y a " + jours + " jours";
            if (jours < 30) return "Il y a " + (jours / 7) + " semaine(s)";
            return "Il y a " + (jours / 30) + " mois";
        }
    }
    
    public static class NouvelUtilisateur {
        private String nom;
        private String prenom;
        private String email;
        private String telephone;
        private String role;
        private Long organisationId;
        private String motDePasse;
        private boolean envoyerEmail;
        
        // Getters et setters
        public String getNom() { return nom; }
        public void setNom(String nom) { this.nom = nom; }
        
        public String getPrenom() { return prenom; }
        public void setPrenom(String prenom) { this.prenom = prenom; }
        
        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 getRole() { return role; }
        public void setRole(String role) { this.role = role; }
        
        public Long getOrganisationId() { return organisationId; }
        public void setOrganisationId(Long organisationId) { this.organisationId = organisationId; }
        
        public String getMotDePasse() { return motDePasse; }
        public void setMotDePasse(String motDePasse) { this.motDePasse = motDePasse; }
        
        public boolean isEnvoyerEmail() { return envoyerEmail; }
        public void setEnvoyerEmail(boolean envoyerEmail) { this.envoyerEmail = envoyerEmail; }
    }
    
    public static class Filtres {
        private String recherche;
        private String role;
        private String statut;
        private String connexion;
        private Long organisation;
        
        // Getters et setters
        public String getRecherche() { return recherche; }
        public void setRecherche(String recherche) { this.recherche = recherche; }
        
        public String getRole() { return role; }
        public void setRole(String role) { this.role = role; }
        
        public String getStatut() { return statut; }
        public void setStatut(String statut) { this.statut = statut; }
        
        public String getConnexion() { return connexion; }
        public void setConnexion(String connexion) { this.connexion = connexion; }
        
        public Long getOrganisation() { return organisation; }
        public void setOrganisation(Long organisation) { this.organisation = organisation; }
    }
    
    public static class StatistiquesUtilisateurs {
        private int totalUtilisateurs;
        private int utilisateursConnectes;
        private int administrateurs;
        private int utilisateursDesactives;
        
        // Getters et setters
        public int getTotalUtilisateurs() { return totalUtilisateurs; }
        public void setTotalUtilisateurs(int totalUtilisateurs) { this.totalUtilisateurs = totalUtilisateurs; }
        
        public int getUtilisateursConnectes() { return utilisateursConnectes; }
        public void setUtilisateursConnectes(int utilisateursConnectes) { this.utilisateursConnectes = utilisateursConnectes; }
        
        public int getAdministrateurs() { return administrateurs; }
        public void setAdministrateurs(int administrateurs) { this.administrateurs = administrateurs; }
        
        public int getUtilisateursDesactives() { return utilisateursDesactives; }
        public void setUtilisateursDesactives(int utilisateursDesactives) { this.utilisateursDesactives = utilisateursDesactives; }
    }
    
    public static class Organisation {
        private Long id;
        private String nom;
        
        // Getters et setters
        public Long getId() { return id; }
        public void setId(Long id) { this.id = id; }
        
        public String getNom() { return nom; }
        public void setNom(String nom) { this.nom = nom; }
    }
}