package dev.lions.unionflow.client.view;

import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@Named("auditBean")
@SessionScoped
public class AuditBean implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    // Filtres
    private Date dateDebut;
    private Date dateFin;
    private String typeAction = "";
    private String severite = "";
    private String utilisateur = "";
    private String module = "";
    private String ipAddress = "";
    
    // Données
    private List<EvenementAudit> evenements;
    private EvenementAudit evenementSelectionne;
    
    // Export
    private String formatExport = "EXCEL";
    private boolean inclureFiltresExport = true;
    
    public AuditBean() {
        initialiserEvenements();
        // Initialiser les dates à aujourd'hui - 7 jours
        Calendar cal = Calendar.getInstance();
        dateFin = cal.getTime();
        cal.add(Calendar.DAY_OF_MONTH, -7);
        dateDebut = cal.getTime();
    }
    
    private void initialiserEvenements() {
        evenements = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        
        // Événements de connexion
        evenements.add(new EvenementAudit(
            now.minusMinutes(15), "CONNEXION", "SUCCESS", "Marie Dupont", "ADMIN_ORG", "AUTH",
            "Connexion réussie", "Connexion via interface web", "192.168.1.105",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "SESSION_123456"));
            
        evenements.add(new EvenementAudit(
            now.minusMinutes(32), "CONNEXION", "ERROR", "Jean Martin", "MEMBRE", "AUTH",
            "Tentative de connexion échouée", "Mot de passe incorrect (3e tentative)", "192.168.1.87",
            "Mozilla/5.0 (Macintosh; Intel Mac OS X)", "SESSION_789012"));
            
        // Événements de gestion des membres
        evenements.add(new EvenementAudit(
            now.minusHours(1), "CREATION", "SUCCESS", "Marie Dupont", "ADMIN_ORG", "MEMBRES",
            "Création d'un nouveau membre", "Membre: Paul Durand (ID: MBR_2024_001)", "192.168.1.105",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "SESSION_123456"));
            
        evenements.add(new EvenementAudit(
            now.minusHours(2), "MODIFICATION", "SUCCESS", "Sophie Bernard", "SECRETAIRE", "MEMBRES",
            "Modification profil membre", "Mise à jour adresse email: paul.durand@email.com", "192.168.1.92",
            "Mozilla/5.0 (iPhone; CPU iPhone OS)", "SESSION_345678"));
            
        // Événements de cotisations
        evenements.add(new EvenementAudit(
            now.minusHours(3), "CREATION", "SUCCESS", "Pierre Legrand", "COMPTABLE", "COTISATIONS",
            "Enregistrement paiement cotisation", "Cotisation 2024 - Membre: Marie Petit - 50€", "192.168.1.78",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "SESSION_901234"));
            
        // Événements d'export
        evenements.add(new EvenementAudit(
            now.minusHours(4), "EXPORT", "SUCCESS", "Marie Dupont", "ADMIN_ORG", "RAPPORTS",
            "Export liste des membres", "Format Excel - 156 membres exportés", "192.168.1.105",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "SESSION_123456"));
            
        // Événements de configuration
        evenements.add(new EvenementAudit(
            now.minusHours(6), "CONFIGURATION", "WARNING", "Admin Système", "SUPER_ADMIN", "CONFIG",
            "Modification paramètres sécurité", "Durée de session modifiée: 30min → 60min", "192.168.1.1",
            "Mozilla/5.0 (Linux; Ubuntu)", "SESSION_ADMIN001"));
            
        // Événements suspects
        evenements.add(new EvenementAudit(
            now.minusHours(8), "CONNEXION", "CRITICAL", "Utilisateur Inconnu", "N/A", "AUTH",
            "Tentative de connexion suspecte", "Multiples tentatives depuis IP externe", "203.45.67.89",
            "Bot/1.0", "SESSION_UNKNOWN"));
            
        evenements.add(new EvenementAudit(
            now.minusHours(12), "CONSULTATION", "ERROR", "Test User", "MEMBRE", "DOCUMENTS",
            "Accès non autorisé", "Tentative d'accès au document confidentiel DOC_2024_005", "192.168.1.199",
            "Mozilla/5.0 (Android)", "SESSION_567890"));
            
        // Événements de suppression
        evenements.add(new EvenementAudit(
            now.minusHours(24), "SUPPRESSION", "WARNING", "Marie Dupont", "ADMIN_ORG", "EVENTS",
            "Suppression événement", "Événement: Assemblée Générale 2023 supprimé", "192.168.1.105",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "SESSION_123456"));
            
        // Plus d'événements pour la pagination
        for (int i = 0; i < 50; i++) {
            LocalDateTime date = now.minusHours(i + 1).minusMinutes(new Random().nextInt(60));
            String[] users = {"Marie Dupont", "Jean Martin", "Pierre Legrand", "Sophie Bernard", "Paul Durand"};
            String[] actions = {"CONSULTATION", "MODIFICATION", "CONNEXION", "DECONNEXION"};
            String[] modules = {"MEMBRES", "COTISATIONS", "EVENTS", "DOCUMENTS"};
            String[] ips = {"192.168.1.105", "192.168.1.87", "192.168.1.92", "192.168.1.78"};
            
            String user = users[i % users.length];
            String action = actions[i % actions.length];
            String module = modules[i % modules.length];
            String ip = ips[i % ips.length];
            String severite = i % 10 == 0 ? "WARNING" : "SUCCESS";
            
            evenements.add(new EvenementAudit(
                date, action, severite, user, "MEMBRE", module,
                "Action automatique " + (i + 1), "Détails de l'action " + (i + 1), ip,
                "Mozilla/5.0 (Auto)", "SESSION_AUTO_" + i));
        }
        
        // Trier par date décroissante
        evenements.sort((e1, e2) -> e2.getDateHeure().compareTo(e1.getDateHeure()));
    }
    
    // Getters pour KPIs
    public int getTotalEvenements() {
        return evenements.size();
    }
    
    public long getConnexionsReussies() {
        return evenements.stream()
                        .filter(e -> "CONNEXION".equals(e.getTypeAction()) && "SUCCESS".equals(e.getSeverite()))
                        .filter(e -> e.getDateHeure().isAfter(LocalDateTime.now().toLocalDate().atStartOfDay()))
                        .count();
    }
    
    public long getTentativesEchouees() {
        return evenements.stream()
                        .filter(e -> "CONNEXION".equals(e.getTypeAction()) && !"SUCCESS".equals(e.getSeverite()))
                        .filter(e -> e.getDateHeure().isAfter(LocalDateTime.now().minusWeeks(1)))
                        .count();
    }
    
    public long getAlertesSecurite() {
        return evenements.stream()
                        .filter(e -> "CRITICAL".equals(e.getSeverite()) || "ERROR".equals(e.getSeverite()))
                        .count();
    }
    
    // Filtrage
    public List<EvenementAudit> getEvenementsFiltres() {
        return evenements.stream()
                        .filter(this::correspondAuxFiltres)
                        .collect(Collectors.toList());
    }
    
    private boolean correspondAuxFiltres(EvenementAudit event) {
        // Filtre par dates
        if (dateDebut != null && event.getDateHeure().isBefore(convertToLocalDateTime(dateDebut))) {
            return false;
        }
        if (dateFin != null && event.getDateHeure().isAfter(convertToLocalDateTime(dateFin).plusDays(1))) {
            return false;
        }
        
        // Filtre par type d'action
        if (!typeAction.isEmpty() && !typeAction.equals(event.getTypeAction())) {
            return false;
        }
        
        // Filtre par sévérité
        if (!severite.isEmpty() && !severite.equals(event.getSeverite())) {
            return false;
        }
        
        // Filtre par utilisateur
        if (!utilisateur.isEmpty() && !event.getUtilisateur().toLowerCase().contains(utilisateur.toLowerCase())) {
            return false;
        }
        
        // Filtre par module
        if (!module.isEmpty() && !module.equals(event.getModule())) {
            return false;
        }
        
        // Filtre par IP
        if (!ipAddress.isEmpty() && !event.getIpAddress().contains(ipAddress)) {
            return false;
        }
        
        return true;
    }
    
    private LocalDateTime convertToLocalDateTime(Date date) {
        return LocalDateTime.ofInstant(date.toInstant(), java.time.ZoneId.systemDefault());
    }
    
    // Actions
    public void rechercher() {
        // La recherche se fait automatiquement via le filtrage
    }
    
    public void reinitialiserFiltres() {
        Calendar cal = Calendar.getInstance();
        dateFin = cal.getTime();
        cal.add(Calendar.DAY_OF_MONTH, -7);
        dateDebut = cal.getTime();
        
        typeAction = "";
        severite = "";
        utilisateur = "";
        module = "";
        ipAddress = "";
    }
    
    public void voirDetails(EvenementAudit event) {
        this.evenementSelectionne = event;
    }
    
    public void signalerEvenement(EvenementAudit event) {
        // Logique pour signaler un événement comme suspect
    }
    
    public void exporter() {
        // Logique d'export selon le format sélectionné
    }
    
    // Getters et Setters
    public Date getDateDebut() { return dateDebut; }
    public void setDateDebut(Date dateDebut) { this.dateDebut = dateDebut; }
    
    public Date getDateFin() { return dateFin; }
    public void setDateFin(Date dateFin) { this.dateFin = dateFin; }
    
    public String getTypeAction() { return typeAction; }
    public void setTypeAction(String typeAction) { this.typeAction = typeAction; }
    
    public String getSeverite() { return severite; }
    public void setSeverite(String severite) { this.severite = severite; }
    
    public String getUtilisateur() { return utilisateur; }
    public void setUtilisateur(String utilisateur) { this.utilisateur = utilisateur; }
    
    public String getModule() { return module; }
    public void setModule(String module) { this.module = module; }
    
    public String getIpAddress() { return ipAddress; }
    public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; }
    
    public EvenementAudit getEvenementSelectionne() { return evenementSelectionne; }
    public void setEvenementSelectionne(EvenementAudit evenementSelectionne) { this.evenementSelectionne = evenementSelectionne; }
    
    public String getFormatExport() { return formatExport; }
    public void setFormatExport(String formatExport) { this.formatExport = formatExport; }
    
    public boolean isInclurefiltresExport() { return inclureFiltresExport; }
    public void setInclurefiltresExport(boolean inclureFiltresExport) { this.inclureFiltresExport = inclureFiltresExport; }
    
    // Classe interne EvenementAudit
    public static class EvenementAudit implements Serializable {
        private LocalDateTime dateHeure;
        private String typeAction;
        private String severite;
        private String utilisateur;
        private String role;
        private String module;
        private String description;
        private String details;
        private String ipAddress;
        private String userAgent;
        private String sessionId;
        
        public EvenementAudit(LocalDateTime dateHeure, String typeAction, String severite, 
                            String utilisateur, String role, String module, String description, 
                            String details, String ipAddress, String userAgent, String sessionId) {
            this.dateHeure = dateHeure;
            this.typeAction = typeAction;
            this.severite = severite;
            this.utilisateur = utilisateur;
            this.role = role;
            this.module = module;
            this.description = description;
            this.details = details;
            this.ipAddress = ipAddress;
            this.userAgent = userAgent;
            this.sessionId = sessionId;
        }
        
        // Propriétés calculées pour l'affichage
        public String getDateFormatee() {
            return dateHeure.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
        }
        
        public String getHeureFormatee() {
            return dateHeure.format(DateTimeFormatter.ofPattern("HH:mm:ss"));
        }
        
        public String getDateHeureComplete() {
            return dateHeure.format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"));
        }
        
        public String getSeveriteLibelle() {
            switch (severite) {
                case "SUCCESS": return "Succès";
                case "INFO": return "Info";
                case "WARNING": return "Attention";
                case "ERROR": return "Erreur";
                case "CRITICAL": return "Critique";
                default: return severite;
            }
        }
        
        public String getSeveriteSeverity() {
            switch (severite) {
                case "SUCCESS": return "success";
                case "INFO": return "info";
                case "WARNING": return "warning";
                case "ERROR": return "danger";
                case "CRITICAL": return "danger";
                default: return "secondary";
            }
        }
        
        public String getSeveriteIcon() {
            switch (severite) {
                case "SUCCESS": return "pi pi-check";
                case "INFO": return "pi pi-info";
                case "WARNING": return "pi pi-exclamation-triangle";
                case "ERROR": return "pi pi-times";
                case "CRITICAL": return "pi pi-ban";
                default: return "pi pi-circle";
            }
        }
        
        public String getActionIcon() {
            switch (typeAction) {
                case "CONNEXION": return "pi pi-sign-in";
                case "DECONNEXION": return "pi pi-sign-out";
                case "CREATION": return "pi pi-plus";
                case "MODIFICATION": return "pi pi-pencil";
                case "SUPPRESSION": return "pi pi-trash";
                case "CONSULTATION": return "pi pi-eye";
                case "EXPORT": return "pi pi-download";
                case "CONFIGURATION": return "pi pi-cog";
                default: return "pi pi-circle";
            }
        }
        
        public String getActionColor() {
            switch (typeAction) {
                case "CONNEXION": return "#28a745";
                case "DECONNEXION": return "#6c757d";
                case "CREATION": return "#007bff";
                case "MODIFICATION": return "#ffc107";
                case "SUPPRESSION": return "#dc3545";
                case "CONSULTATION": return "#17a2b8";
                case "EXPORT": return "#6f42c1";
                case "CONFIGURATION": return "#fd7e14";
                default: return "#6c757d";
            }
        }
        
        public String getModuleLibelle() {
            switch (module) {
                case "AUTH": return "Authentification";
                case "MEMBRES": return "Membres";
                case "COTISATIONS": return "Cotisations";
                case "EVENTS": return "Événements";
                case "DOCUMENTS": return "Documents";
                case "CONFIG": return "Configuration";
                case "RAPPORTS": return "Rapports";
                default: return module;
            }
        }
        
        public String getAction() {
            switch (typeAction) {
                case "CONNEXION": return "Connexion";
                case "DECONNEXION": return "Déconnexion";
                case "CREATION": return "Création";
                case "MODIFICATION": return "Modification";
                case "SUPPRESSION": return "Suppression";
                case "CONSULTATION": return "Consultation";
                case "EXPORT": return "Export";
                case "CONFIGURATION": return "Configuration";
                default: return typeAction;
            }
        }
        
        public String getDescriptionComplete() {
            return description + (details != null && !details.isEmpty() ? "\n\nDétails: " + details : "");
        }
        
        public String getUserAgentComplet() {
            return userAgent;
        }
        
        public String getDonneesAvant() {
            // Simulation de données avant modification
            if ("MODIFICATION".equals(typeAction)) {
                return "{\n  \"nom\": \"Ancien Nom\",\n  \"email\": \"ancien@email.com\",\n  \"statut\": \"INACTIF\"\n}";
            }
            return null;
        }
        
        public String getDonneesApres() {
            // Simulation de données après modification
            if ("MODIFICATION".equals(typeAction)) {
                return "{\n  \"nom\": \"Nouveau Nom\",\n  \"email\": \"nouveau@email.com\",\n  \"statut\": \"ACTIF\"\n}";
            }
            return null;
        }
        
        // Getters et Setters
        public LocalDateTime getDateHeure() { return dateHeure; }
        public void setDateHeure(LocalDateTime dateHeure) { this.dateHeure = dateHeure; }
        
        public String getTypeAction() { return typeAction; }
        public void setTypeAction(String typeAction) { this.typeAction = typeAction; }
        
        public String getSeverite() { return severite; }
        public void setSeverite(String severite) { this.severite = severite; }
        
        public String getUtilisateur() { return utilisateur; }
        public void setUtilisateur(String utilisateur) { this.utilisateur = utilisateur; }
        
        public String getRole() { return role; }
        public void setRole(String role) { this.role = role; }
        
        public String getModule() { return module; }
        public void setModule(String module) { this.module = module; }
        
        public String getDescription() { return description; }
        public void setDescription(String description) { this.description = description; }
        
        public String getDetails() { return details; }
        public void setDetails(String details) { this.details = details; }
        
        public String getIpAddress() { return ipAddress; }
        public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; }
        
        public String getUserAgent() { 
            return userAgent != null && userAgent.length() > 20 ? 
                   userAgent.substring(0, 20) + "..." : userAgent; 
        }
        public void setUserAgent(String userAgent) { this.userAgent = userAgent; }
        
        public String getSessionId() { return sessionId; }
        public void setSessionId(String sessionId) { this.sessionId = sessionId; }
    }
}