"""
Analyseur et générateur de graphiques pour les résultats de simulation
"""

import json
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Agg')  # Backend sans affichage


class ResultsAnalyzer:
    """Analyse et visualise les résultats des simulations."""
    
    def __init__(self, results_file):
        """
        Charge les résultats depuis un fichier JSON.
        
        Args:
            results_file (str): Chemin vers le fichier JSON
        """
        with open(results_file, 'r') as f:
            self.results = json.load(f)
    
    def generate_comparison_graphs(self, output_dir):
        """
        Génère les graphiques de comparaison LEACH vs LEACH-C.
        
        Args:
            output_dir (str): Répertoire de sortie
        """
        # 1. FDN Comparison
        self._plot_fdn_comparison(output_dir)
        
        # 2. FMR Comparison
        self._plot_fmr_comparison(output_dir)
        
        # 3. DLBI Comparison
        self._plot_dlbi_comparison(output_dir)
        
        # 4. RSPI Comparison
        self._plot_rspi_comparison(output_dir)
        
        # 5. Alive Nodes Over Rounds
        self._plot_alive_nodes(output_dir)
    
    def _plot_fdn_comparison(self, output_dir):
        """Graphique : FDN pour tous les scénarios."""
        scenarios = list(self.results.keys())
        leach_fdn = []
        leachc_fdn = []
        
        for scenario in scenarios:
            leach_metrics = self.results[scenario]["LEACH"]["metrics"]
            leachc_metrics = self.results[scenario]["LEACH-C"]["metrics"]
            
            leach_fdn.append(leach_metrics.get("first_dead_node_round") or 0)
            leachc_fdn.append(leachc_metrics.get("first_dead_node_round") or 0)
        
        fig, ax = plt.subplots(figsize=(12, 6))
        x_pos = range(len(scenarios))
        width = 0.35
        
        ax.bar([i - width/2 for i in x_pos], leach_fdn, width, label='LEACH', color='#FF6B6B')
        ax.bar([i + width/2 for i in x_pos], leachc_fdn, width, label='LEACH-C', color='#4ECDC4')
        
        ax.set_xlabel('Scénario', fontsize=12)
        ax.set_ylabel('Premier Nœud Mort (Round)', fontsize=12)
        ax.set_title('Comparaison FDN (First Dead Node)', fontsize=14, fontweight='bold')
        ax.set_xticks(x_pos)
        ax.set_xticklabels(scenarios, rotation=45, ha='right')
        ax.legend()
        ax.grid(axis='y', alpha=0.3)
        
        plt.tight_layout()
        plt.savefig(f"{output_dir}/01_FDN_Comparison.png", dpi=300)
        plt.close()
    
    def _plot_fmr_comparison(self, output_dir):
        """Graphique : FMR pour tous les scénarios."""
        scenarios = list(self.results.keys())
        leach_fmr = []
        leachc_fmr = []
        
        for scenario in scenarios:
            leach_metrics = self.results[scenario]["LEACH"]["metrics"]
            leachc_metrics = self.results[scenario]["LEACH-C"]["metrics"]
            
            leach_fmr.append(leach_metrics.get("first_muted_round") or 9999)
            leachc_fmr.append(leachc_metrics.get("first_muted_round") or 9999)
        
        fig, ax = plt.subplots(figsize=(12, 6))
        x_pos = range(len(scenarios))
        width = 0.35
        
        ax.bar([i - width/2 for i in x_pos], leach_fmr, width, label='LEACH', color='#FF6B6B')
        ax.bar([i + width/2 for i in x_pos], leachc_fmr, width, label='LEACH-C', color='#4ECDC4')
        
        ax.set_xlabel('Scénario', fontsize=12)
        ax.set_ylabel('Premier Round Muet', fontsize=12)
        ax.set_title('Comparaison FMR (First Muted Round)', fontsize=14, fontweight='bold')
        ax.set_xticks(x_pos)
        ax.set_xticklabels(scenarios, rotation=45, ha='right')
        ax.legend()
        ax.grid(axis='y', alpha=0.3)
        
        plt.tight_layout()
        plt.savefig(f"{output_dir}/02_FMR_Comparison.png", dpi=300)
        plt.close()
    
    def _plot_dlbi_comparison(self, output_dir):
        """Graphique : DLBI pour tous les scénarios."""
        scenarios = list(self.results.keys())
        leach_dlbi = []
        leachc_dlbi = []
        
        for scenario in scenarios:
            leach_metrics = self.results[scenario]["LEACH"]["metrics"]
            leachc_metrics = self.results[scenario]["LEACH-C"]["metrics"]
            
            leach_dlbi.append(leach_metrics.get("dlbi", 0))
            leachc_dlbi.append(leachc_metrics.get("dlbi", 0))
        
        fig, ax = plt.subplots(figsize=(12, 6))
        x_pos = range(len(scenarios))
        width = 0.35
        
        ax.bar([i - width/2 for i in x_pos], leach_dlbi, width, label='LEACH', color='#FF6B6B')
        ax.bar([i + width/2 for i in x_pos], leachc_dlbi, width, label='LEACH-C', color='#4ECDC4')
        
        ax.set_xlabel('Scénario', fontsize=12)
        ax.set_ylabel('DLBI (0 à 1)', fontsize=12)
        ax.set_title('Comparaison DLBI (Dynamic Load Balancing Index)', fontsize=14, fontweight='bold')
        ax.set_xticks(x_pos)
        ax.set_xticklabels(scenarios, rotation=45, ha='right')
        ax.set_ylim([0, 1.1])
        ax.legend()
        ax.grid(axis='y', alpha=0.3)
        
        plt.tight_layout()
        plt.savefig(f"{output_dir}/03_DLBI_Comparison.png", dpi=300)
        plt.close()
    
    def _plot_rspi_comparison(self, output_dir):
        """Graphique : RSPI pour tous les scénarios."""
        scenarios = list(self.results.keys())
        leach_rspi = []
        leachc_rspi = []
        
        for scenario in scenarios:
            leach_metrics = self.results[scenario]["LEACH"]["metrics"]
            leachc_metrics = self.results[scenario]["LEACH-C"]["metrics"]
            
            leach_rspi.append(leach_metrics.get("rspi", 0))
            leachc_rspi.append(leachc_metrics.get("rspi", 0))
        
        fig, ax = plt.subplots(figsize=(12, 6))
        x_pos = range(len(scenarios))
        width = 0.35
        
        ax.bar([i - width/2 for i in x_pos], leach_rspi, width, label='LEACH', color='#FF6B6B')
        ax.bar([i + width/2 for i in x_pos], leachc_rspi, width, label='LEACH-C', color='#4ECDC4')
        
        ax.set_xlabel('Scénario', fontsize=12)
        ax.set_ylabel('RSPI (0 à 1)', fontsize=12)
        ax.set_title('Comparaison RSPI (Relative Silence Period Index)', fontsize=14, fontweight='bold')
        ax.set_xticks(x_pos)
        ax.set_xticklabels(scenarios, rotation=45, ha='right')
        ax.set_ylim([0, 1.1])
        ax.legend()
        ax.grid(axis='y', alpha=0.3)
        
        plt.tight_layout()
        plt.savefig(f"{output_dir}/04_RSPI_Comparison.png", dpi=300)
        plt.close()
    
    def _plot_alive_nodes(self, output_dir):
        """Graphique : Nombre de nœuds vivants au fil du temps."""
        scenarios = list(self.results.keys())[:3]  # Premiers 3 scénarios
        
        fig, axes = plt.subplots(len(scenarios), 2, figsize=(14, 4*len(scenarios)))
        
        for idx, scenario in enumerate(scenarios):
            # LEACH
            leach_detailed = self.results[scenario]["LEACH"]["detailed_rounds"]
            rounds = [r["round"] for r in leach_detailed]
            alive = [r["alive_nodes"] for r in leach_detailed]
            
            axes[idx, 0].plot(rounds, alive, marker='o', label='LEACH', color='#FF6B6B')
            axes[idx, 0].set_xlabel('Round')
            axes[idx, 0].set_ylabel('Nœuds Vivants')
            axes[idx, 0].set_title(f'LEACH - {scenario}')
            axes[idx, 0].grid(alpha=0.3)
            
            # LEACH-C
            leachc_detailed = self.results[scenario]["LEACH-C"]["detailed_rounds"]
            rounds = [r["round"] for r in leachc_detailed]
            alive = [r["alive_nodes"] for r in leachc_detailed]
            
            axes[idx, 1].plot(rounds, alive, marker='s', label='LEACH-C', color='#4ECDC4')
            axes[idx, 1].set_xlabel('Round')
            axes[idx, 1].set_ylabel('Nœuds Vivants')
            axes[idx, 1].set_title(f'LEACH-C - {scenario}')
            axes[idx, 1].grid(alpha=0.3)
        
        plt.tight_layout()
        plt.savefig(f"{output_dir}/05_Alive_Nodes_Over_Time.png", dpi=300)
        plt.close()
    
    def generate_summary_table(self, output_file):
        """
        Génère un tableau récapitulatif en CSV.
        
        Args:
            output_file (str): Chemin du fichier CSV
        """
        with open(output_file, 'w') as f:
            # En-tête
            f.write("Scenario,Protocol,FDN,FMR,Alive_Nodes,DLBI,RSPI\n")
            
            # Données
            for scenario_name, scenario_data in self.results.items():
                for protocol in ["LEACH", "LEACH-C"]:
                    metrics = scenario_data[protocol]["metrics"]
                    
                    f.write(f"{scenario_name},{protocol},")
                    f.write(f"{metrics.get('first_dead_node_round', 'N/A')},")
                    f.write(f"{metrics.get('first_muted_round', 'N/A')},")
                    f.write(f"{metrics.get('final_alive_nodes', 'N/A')},")
                    f.write(f"{metrics.get('dlbi', 'N/A'):.4f},")
                    f.write(f"{metrics.get('rspi', 'N/A'):.4f}\n")
        
        print(f"OK - Tableau récapitulatif: {output_file}")


if __name__ == "__main__":
    analyzer = ResultsAnalyzer("/home/paul/algo/results/simulation_results.json")
    analyzer.generate_comparison_graphs("/home/paul/algo/results")
    analyzer.generate_summary_table("/home/paul/algo/results/summary.csv")
