#!/usr/bin/env python3
"""
Module pour formater les rapports à partir des fichiers JSON générés par l'AgentReportGenerator.

Ce module prend en entrée un fichier JSON contenant les analyses et génère différents
formats de sortie (Markdown, HTML, etc.) sans utiliser de LLM.
"""

import os
import json
import argparse
import sys
import re
from datetime import datetime
from typing import Dict, List, Any, Optional, Tuple

def generate_markdown_report(json_path: str, output_path: Optional[str] = None) -> Tuple[bool, str]:
    """
    Génère un rapport au format Markdown à partir d'un fichier JSON.
    
    Args:
        json_path: Chemin vers le fichier JSON contenant les données du rapport
        output_path: Chemin de sortie pour le fichier Markdown (facultatif)
        
    Returns:
        Tuple (succès, chemin du fichier généré ou message d'erreur)
    """
    try:
        # Lire le fichier JSON
        with open(json_path, "r", encoding="utf-8") as f:
            rapport_data = json.load(f)
        
        # Si le chemin de sortie n'est pas spécifié, le créer à partir du chemin d'entrée
        if not output_path:
            # Remplacer l'extension JSON par MD
            output_path = os.path.splitext(json_path)[0] + ".md"
        
        # Générer le contenu Markdown
        markdown_content = _generate_markdown_content(rapport_data)
        
        # Écrire le contenu dans le fichier de sortie
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(markdown_content)
        
        print(f"Rapport Markdown généré avec succès: {output_path}")
        return True, output_path
    
    except Exception as e:
        error_message = f"Erreur lors de la génération du rapport Markdown: {str(e)}"
        print(error_message)
        return False, error_message

def _generate_markdown_content(rapport_data: Dict) -> str:
    """
    Génère le contenu Markdown à partir des données du rapport.
    
    Args:
        rapport_data: Dictionnaire contenant les données du rapport
        
    Returns:
        Contenu Markdown
    """
    ticket_id = rapport_data.get("ticket_id", "")
    timestamp = rapport_data.get("metadata", {}).get("timestamp", "")
    generation_date = rapport_data.get("metadata", {}).get("generation_date", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    
    # Entête du document
    markdown = f"# Rapport d'analyse du ticket #{ticket_id}\n\n"
    markdown += f"*Généré le: {generation_date}*\n\n"
    
    # 1. Résumé exécutif
    if "resume" in rapport_data and rapport_data["resume"]:
        markdown += rapport_data["resume"] + "\n\n"
    
    # 2. Chronologie des échanges (tableau)
    markdown += "## Chronologie des échanges\n\n"
    
    if "chronologie_echanges" in rapport_data and rapport_data["chronologie_echanges"]:
        # Créer un tableau pour les échanges
        markdown += "| Date | Émetteur | Type | Contenu | Statut |\n"
        markdown += "|------|---------|------|---------|--------|\n"
        
        # Prétraitement pour détecter les questions sans réponse
        questions_sans_reponse = {}
        echanges = rapport_data["chronologie_echanges"]
        
        for i, echange in enumerate(echanges):
            if echange.get("type", "").lower() == "question" and echange.get("emetteur", "").lower() == "client":
                has_response = False
                # Vérifier si la question a une réponse
                for j in range(i+1, len(echanges)):
                    next_echange = echanges[j]
                    if next_echange.get("type", "").lower() == "réponse" and next_echange.get("emetteur", "").lower() == "support":
                        has_response = True
                        break
                questions_sans_reponse[i] = not has_response
        
        # Générer les lignes du tableau
        for i, echange in enumerate(echanges):
            date = echange.get("date", "-")
            emetteur = echange.get("emetteur", "-")
            type_msg = echange.get("type", "-")
            contenu = echange.get("contenu", "-")
            
            # Ajouter un statut pour les questions sans réponse
            statut = ""
            if emetteur.lower() == "client" and type_msg.lower() == "question" and questions_sans_reponse.get(i, False):
                statut = "**Sans réponse**"
            
            markdown += f"| {date} | {emetteur} | {type_msg} | {contenu} | {statut} |\n"
        
        # Ajouter une note si aucune réponse du support n'a été trouvée
        if not any(echange.get("emetteur", "").lower() == "support" for echange in echanges):
            markdown += "\n**Note: Aucune réponse du support n'a été trouvée dans ce ticket.**\n\n"
    else:
        markdown += "*Aucun échange détecté dans le ticket.*\n\n"
    
    # 3. Analyse des images
    markdown += "## Analyse des images\n\n"
    
    if "images_analyses" in rapport_data and rapport_data["images_analyses"]:
        images_list = rapport_data["images_analyses"]
        
        if not images_list:
            markdown += "*Aucune image pertinente n'a été identifiée.*\n\n"
        else:
            for i, img_data in enumerate(images_list, 1):
                image_name = img_data.get("image_name", f"Image {i}")
                sorting_info = img_data.get("sorting_info", {})
                reason = sorting_info.get("reason", "Non spécifiée")
                
                markdown += f"### Image {i}: {image_name}\n\n"
                
                # Raison de la pertinence
                if reason:
                    markdown += f"**Raison de la pertinence**: {reason}\n\n"
                
                # Ajouter l'analyse détaillée dans une section dépliable
                analyse_detail = img_data.get("analyse", "Aucune analyse disponible")
                if analyse_detail:
                    markdown += "<details>\n<summary>Analyse détaillée de l'image</summary>\n\n"
                    markdown += "```\n" + analyse_detail + "\n```\n\n"
                    markdown += "</details>\n\n"
    else:
        markdown += "*Aucune image pertinente n'a été analysée.*\n\n"
    
    # 4. Diagnostic technique
    if "diagnostic" in rapport_data and rapport_data["diagnostic"]:
        markdown += "## Diagnostic technique\n\n"
        markdown += rapport_data["diagnostic"] + "\n\n"
    
    # Tableau récapitulatif des échanges (nouveau)
    if "tableau_questions_reponses" in rapport_data and rapport_data["tableau_questions_reponses"]:
        markdown += rapport_data["tableau_questions_reponses"] + "\n\n"
    
    # Section séparatrice
    markdown += "---\n\n"
    
    # Détails des analyses effectuées
    markdown += "# Détails des analyses effectuées\n\n"
    markdown += "## Processus d'analyse\n\n"
    
    # 1. Analyse de ticket
    ticket_analyse = rapport_data.get("ticket_analyse", "")
    if ticket_analyse:
        markdown += "### Étape 1: Analyse du ticket\n\n"
        markdown += "L'agent d'analyse de ticket a extrait les informations suivantes du ticket d'origine:\n\n"
        markdown += "<details>\n<summary>Cliquez pour voir l'analyse complète du ticket</summary>\n\n"
        markdown += "```\n" + str(ticket_analyse) + "\n```\n\n"
        markdown += "</details>\n\n"
    else:
        markdown += "### Étape 1: Analyse du ticket\n\n"
        markdown += "*Aucune analyse de ticket disponible*\n\n"
    
    # 2. Tri des images
    markdown += "### Étape 2: Tri des images\n\n"
    markdown += "L'agent de tri d'images a évalué chaque image pour déterminer sa pertinence par rapport au problème client:\n\n"
    
    # Création d'un tableau récapitulatif
    images_list = rapport_data.get("images_analyses", [])
    if images_list:
        markdown += "| Image | Pertinence | Raison |\n"
        markdown += "|-------|------------|--------|\n"
        
        for img_data in images_list:
            image_name = img_data.get("image_name", "Image inconnue")
            sorting_info = img_data.get("sorting_info", {})
            is_relevant = "Oui" if sorting_info else "Oui"  # Par défaut, si présent dans la liste c'est pertinent
            reason = sorting_info.get("reason", "Non spécifiée")
            
            markdown += f"| {image_name} | {is_relevant} | {reason} |\n"
        
        markdown += "\n"
    else:
        markdown += "*Aucune image n'a été triée pour ce ticket.*\n\n"
    
    # 3. Analyse des images
    markdown += "### Étape 3: Analyse détaillée des images pertinentes\n\n"
    
    if images_list:
        for i, img_data in enumerate(images_list, 1):
            image_name = img_data.get("image_name", f"Image {i}")
            analyse_detail = img_data.get("analyse", "Analyse non disponible")
            
            markdown += f"#### Image pertinente {i}: {image_name}\n\n"
            markdown += "<details>\n<summary>Cliquez pour voir l'analyse complète de l'image</summary>\n\n"
            markdown += "```\n" + str(analyse_detail) + "\n```\n\n"
            markdown += "</details>\n\n"
    else:
        markdown += "*Aucune image pertinente n'a été identifiée pour ce ticket.*\n\n"
    
    # 4. Génération du rapport
    markdown += "### Étape 4: Génération du rapport de synthèse\n\n"
    markdown += "L'agent de génération de rapport a synthétisé toutes les analyses précédentes pour produire le rapport ci-dessus.\n\n"
    
    # Informations techniques et métadonnées
    markdown += "## Informations techniques\n\n"
    
    # Statistiques
    statistiques = rapport_data.get("statistiques", {})
    metadata = rapport_data.get("metadata", {})
    
    markdown += "### Statistiques\n\n"
    markdown += f"- **Images analysées**: {statistiques.get('total_images', 0)}\n"
    markdown += f"- **Images pertinentes**: {statistiques.get('images_pertinentes', 0)}\n"
    
    if "generation_time" in statistiques:
        markdown += f"- **Temps de génération**: {statistiques['generation_time']:.2f} secondes\n"
    
    # Modèle utilisé
    markdown += "\n### Modèle LLM utilisé\n\n"
    markdown += f"- **Modèle**: {metadata.get('model', 'Non spécifié')}\n"
    
    if "model_version" in metadata:
        markdown += f"- **Version**: {metadata.get('model_version', 'Non spécifiée')}\n"
    
    markdown += f"- **Température**: {metadata.get('temperature', 'Non spécifiée')}\n"
    markdown += f"- **Top_p**: {metadata.get('top_p', 'Non spécifié')}\n"
    
    # Section sur les agents utilisés
    if "agents" in metadata:
        markdown += "\n### Agents impliqués\n\n"
        
        agents = metadata["agents"]
        
        # Agent d'analyse de ticket
        if "json_analyser" in agents:
            markdown += "#### Agent d'analyse du ticket\n"
            json_analyser = agents["json_analyser"]
            if "model_info" in json_analyser:
                markdown += f"- **Modèle**: {json_analyser['model_info'].get('name', 'Non spécifié')}\n"
        
        # Agent de tri d'images
        if "image_sorter" in agents:
            markdown += "\n#### Agent de tri d'images\n"
            sorter = agents["image_sorter"]
            # Récupérer directement le modèle ou via model_info selon la structure
            if "model" in sorter:
                markdown += f"- **Modèle**: {sorter.get('model', 'Non spécifié')}\n"
                markdown += f"- **Température**: {sorter.get('temperature', 'Non spécifiée')}\n"
                markdown += f"- **Top_p**: {sorter.get('top_p', 'Non spécifié')}\n"
            elif "model_info" in sorter:
                markdown += f"- **Modèle**: {sorter['model_info'].get('name', 'Non spécifié')}\n"
            else:
                markdown += f"- **Modèle**: Non spécifié\n"
        
        # Agent d'analyse d'images
        if "image_analyser" in agents:
            markdown += "\n#### Agent d'analyse d'images\n"
            analyser = agents["image_analyser"]
            # Récupérer directement le modèle ou via model_info selon la structure
            if "model" in analyser:
                markdown += f"- **Modèle**: {analyser.get('model', 'Non spécifié')}\n"
                markdown += f"- **Température**: {analyser.get('temperature', 'Non spécifiée')}\n"
                markdown += f"- **Top_p**: {analyser.get('top_p', 'Non spécifié')}\n"
            elif "model_info" in analyser:
                markdown += f"- **Modèle**: {analyser['model_info'].get('name', 'Non spécifié')}\n"
            else:
                markdown += f"- **Modèle**: Non spécifié\n"
        
        # Ajouter une section pour les prompts s'ils sont présents
        if "prompts_utilisés" in rapport_data and rapport_data["prompts_utilisés"]:
            markdown += "\n## Prompts utilisés\n\n"
            prompts = rapport_data["prompts_utilisés"]
            
            for agent, prompt in prompts.items():
                # Si le prompt est trop long, le tronquer pour éviter des rapports trop volumineux
                if len(prompt) > 2000:
                    debut = prompt[:1000].strip()
                    fin = prompt[-1000:].strip()
                    prompt_tronque = f"{debut}\n\n[...]\n\n{fin}"
                    markdown += f"### Agent: {agent}\n\n```\n{prompt_tronque}\n```\n\n"
                else:
                    markdown += f"### Agent: {agent}\n\n```\n{prompt}\n```\n\n"
    
    return markdown

def generate_html_report(json_path: str, output_path: Optional[str] = None) -> Tuple[bool, str]:
    """
    Génère un rapport au format HTML à partir d'un fichier JSON.
    
    Args:
        json_path: Chemin vers le fichier JSON contenant les données du rapport
        output_path: Chemin de sortie pour le fichier HTML (facultatif)
        
    Returns:
        Tuple (succès, chemin du fichier généré ou message d'erreur)
    """
    try:
        # Générer d'abord le Markdown
        success, md_path_or_error = generate_markdown_report(json_path, None)
        
        if not success:
            return False, md_path_or_error
        
        # Lire le contenu Markdown
        with open(md_path_or_error, "r", encoding="utf-8") as f:
            markdown_content = f.read()
        
        # Si le chemin de sortie n'est pas spécifié, le créer à partir du chemin d'entrée
        if not output_path:
            # Remplacer l'extension JSON par HTML
            output_path = os.path.splitext(json_path)[0] + ".html"
        
        # Conversion Markdown → HTML (avec gestion de l'absence de mistune)
        html_content = _simple_markdown_to_html(markdown_content)
        
        # Essayer d'utiliser mistune pour une meilleure conversion si disponible
        try:
            import mistune
            markdown = mistune.create_markdown(escape=False)
            html_content = markdown(markdown_content)
            print("Conversion HTML effectuée avec mistune")
        except ImportError:
            print("Module mistune non disponible, utilisation de la conversion HTML simplifiée")
        
        # Créer un HTML complet avec un peu de style
        html_page = f"""<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rapport d'analyse de ticket</title>
    <style>
        body {{ font-family: Arial, sans-serif; line-height: 1.6; margin: 0; padding: 20px; color: #333; max-width: 1200px; margin: 0 auto; }}
        h1 {{ color: #2c3e50; border-bottom: 2px solid #eee; padding-bottom: 10px; }}
        h2 {{ color: #3498db; margin-top: 30px; }}
        h3 {{ color: #2980b9; }}
        h4 {{ color: #16a085; }}
        table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }}
        th, td {{ padding: 12px 15px; text-align: left; border-bottom: 1px solid #ddd; }}
        th {{ background-color: #f2f2f2; }}
        tr:hover {{ background-color: #f5f5f5; }}
        code, pre {{ background: #f8f8f8; border: 1px solid #ddd; border-radius: 3px; padding: 10px; overflow-x: auto; }}
        details {{ margin: 15px 0; }}
        summary {{ cursor: pointer; font-weight: bold; color: #2980b9; }}
        .status {{ color: #e74c3c; font-weight: bold; }}
        hr {{ border: 0; height: 1px; background: #eee; margin: 30px 0; }}
    </style>
</head>
<body>
    {html_content}
</body>
</html>"""
        
        # Écrire le contenu dans le fichier de sortie
        with open(output_path, "w", encoding="utf-8") as f:
            f.write(html_page)
        
        print(f"Rapport HTML généré avec succès: {output_path}")
        return True, output_path
    
    except Exception as e:
        error_message = f"Erreur lors de la génération du rapport HTML: {str(e)}"
        print(error_message)
        return False, error_message

def _simple_markdown_to_html(markdown_content: str) -> str:
    """
    Convertit un contenu Markdown en HTML de façon simplifiée.
    
    Args:
        markdown_content: Contenu Markdown à convertir
        
    Returns:
        Contenu HTML
    """
    html = markdown_content
    
    # Titres
    html = re.sub(r'^# (.*?)$', r'<h1>\1</h1>', html, flags=re.MULTILINE)
    html = re.sub(r'^## (.*?)$', r'<h2>\1</h2>', html, flags=re.MULTILINE)
    html = re.sub(r'^### (.*?)$', r'<h3>\1</h3>', html, flags=re.MULTILINE)
    html = re.sub(r'^#### (.*?)$', r'<h4>\1</h4>', html, flags=re.MULTILINE)
    
    # Emphase
    html = re.sub(r'\*\*(.*?)\*\*', r'<strong>\1</strong>', html)
    html = re.sub(r'\*(.*?)\*', r'<em>\1</em>', html)
    
    # Lists
    html = re.sub(r'^- (.*?)$', r'<li>\1</li>', html, flags=re.MULTILINE)
    
    # Paragraphes
    html = re.sub(r'([^\n])\n([^\n])', r'\1<br>\2', html)
    html = re.sub(r'\n\n', r'</p><p>', html)
    
    # Tables simplifiées (sans analyser la structure)
    html = re.sub(r'\| (.*?) \|', r'<td>\1</td>', html)
    
    # Code blocks
    html = re.sub(r'```(.*?)```', r'<pre><code>\1</code></pre>', html, flags=re.DOTALL)
    
    # Envelopper dans des balises paragraphe
    html = f"<p>{html}</p>"
    
    return html

def process_report(json_path: str, output_format: str = "markdown") -> None:
    """
    Traite un rapport dans le format spécifié.
    
    Args:
        json_path: Chemin vers le fichier JSON contenant les données du rapport
        output_format: Format de sortie (markdown ou html)
    """
    if output_format.lower() == "markdown":
        generate_markdown_report(json_path)
    elif output_format.lower() == "html":
        generate_html_report(json_path)
    else:
        print(f"Format non supporté: {output_format}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Formateur de rapports à partir de fichiers JSON")
    parser.add_argument("json_path", help="Chemin vers le fichier JSON contenant les données du rapport")
    parser.add_argument("--format", "-f", choices=["markdown", "html"], default="markdown", 
                        help="Format de sortie (markdown par défaut)")
    parser.add_argument("--output", "-o", help="Chemin de sortie pour le rapport (facultatif)")
    
    args = parser.parse_args()
    
    if args.format == "markdown":
        generate_markdown_report(args.json_path, args.output)
    elif args.format == "html":
        generate_html_report(args.json_path, args.output)
    else:
        print(f"Format non supporté: {args.format}") 