#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Fonctions utilitaires pour nettoyer le HTML et formater les dates.
Version simplifiée et robuste: ignore les lignes problématiques.
"""

import re
from datetime import datetime

def clean_html(html_content, is_description=False):
    """
    Nettoie le contenu HTML pour le Markdown en identifiant et ignorant les parties problématiques.
    
    Args:
        html_content (str): Contenu HTML à nettoyer
        is_description (bool): Indique si le contenu est une description de ticket
    
    Returns:
        str: Texte nettoyé
    """
    if not html_content:
        return "*Contenu vide*"
    
    # 0. PRÉVENIR LES DOUBLONS - Détecter et supprimer les messages dupliqués
    # Cette étape permet d'éliminer les messages qui apparaissent en double
    
    # D'abord, nettoyer le HTML pour comparer les sections de texte réel
    cleaned_for_comparison = pre_clean_html(html_content)
    
    # Détection des doublons basée sur les premières lignes
    # Si le même début apparaît deux fois, ne garder que jusqu'à la première occurrence
    first_paragraph = ""
    for line in cleaned_for_comparison.split('\n'):
        if len(line.strip()) > 10:  # Ignorer les lignes vides ou trop courtes
            first_paragraph = line.strip()
            break
            
    if first_paragraph and first_paragraph in cleaned_for_comparison[len(first_paragraph):]:
        # Le premier paragraphe apparaît deux fois - couper au début de la deuxième occurrence
        pos = cleaned_for_comparison.find(first_paragraph, len(first_paragraph))
        if pos > 0:
            # Utiliser cette position pour couper le contenu original
            html_content = html_content[:pos].strip()
    
    # Diviser le contenu en sections potentielles (souvent séparées par des lignes vides doubles)
    sections = re.split(r'\n\s*\n\s*\n', html_content)
    
    # Si le contenu a plusieurs sections, ne garder que la première section significative
    if len(sections) > 1:
        # Rechercher la première section qui contient du texte significatif (non des en-têtes/métadonnées)
        significant_content = ""
        for section in sections:
            # Ignorer les sections très courtes ou qui ressemblent à des en-têtes
            if len(section.strip()) > 50 and not re.search(r'^(?:Subject|Date|From|To|Cc|Objet|De|À|Copie à):', section, re.IGNORECASE):
                significant_content = section
                break
        
        # Si on a trouvé une section significative, l'utiliser comme contenu
        if significant_content:
            html_content = significant_content
    
    # 1. CAS SPÉCIAUX - Traités en premier avec leurs propres règles
    
    # 1.1. Traitement spécifique pour les descriptions
    if is_description:
        # Suppression complète des balises HTML de base
        content = pre_clean_html(html_content)
        content = re.sub(r'\n\s*\n', '\n\n', content)
        return content.strip()
    
    # 1.2. Traitement des messages transférés avec un pattern spécifique
    if "\\-------- Message transféré --------" in html_content or "-------- Courriel original --------" in html_content:
        # Essayer d'extraire le contenu principal du message transféré
        match = re.search(r'(?:De|From|Copie à|Cc)\s*:.*?\n\s*\n(.*?)(?=\n\s*(?:__+|--+|==+|\\\\|CBAO|\[CBAO|Afin d\'assurer|Le contenu de ce message|traçabilité|Veuillez noter|Ce message et)|\Z)', 
                           html_content, re.DOTALL | re.IGNORECASE)
        if match:
            return match.group(1).strip()
        else:
            # Essayer une autre approche si la première échoue
            match = re.search(r'Bonjour.*?(?=\n\s*(?:__+|--+|==+|\\\\|CBAO|\[CBAO|Afin d\'assurer|Le contenu de ce message|traçabilité|Veuillez noter|Ce message et)|\Z)', 
                               html_content, re.DOTALL)
            if match:
                return match.group(0).strip()
    
    # 1.3. Traitement des notifications d'appel
    if "Notification d'appel" in html_content:
        match = re.search(r'(?:Sujet d\'appel:[^\n]*\n[^\n]*\n[^\n]*\n[^\n]*\n)[^\n]*\n[^\n]*([^|]+)', html_content, re.DOTALL)
        if match:
            message_content = match.group(1).strip()
            # Construire un message formaté avec les informations essentielles
            infos = {}
            date_match = re.search(r'Date:.*?\|(.*?)(?:\n|$)', html_content)
            appelant_match = re.search(r'\*\*Appel de:\*\*.*?\|(.*?)(?:\n|$)', html_content)
            telephone_match = re.search(r'Téléphone principal:.*?\|(.*?)(?:\n|$)', html_content)
            mobile_match = re.search(r'Mobile:.*?\|(.*?)(?:\n|$)', html_content)
            sujet_match = re.search(r'Sujet d\'appel:.*?\|(.*?)(?:\n|$)', html_content)
            
            if date_match:
                infos["date"] = date_match.group(1).strip()
            if appelant_match:
                infos["appelant"] = appelant_match.group(1).strip()
            if telephone_match:
                infos["telephone"] = telephone_match.group(1).strip()
            if mobile_match:
                infos["mobile"] = mobile_match.group(1).strip()
            if sujet_match:
                infos["sujet"] = sujet_match.group(1).strip()
            
            # Construire le message formaté
            formatted_message = f"**Notification d'appel**\n\n"
            if "appelant" in infos:
                formatted_message += f"De: {infos['appelant']}\n"
            if "date" in infos:
                formatted_message += f"Date: {infos['date']}\n"
            if "telephone" in infos:
                formatted_message += f"Téléphone: {infos['telephone']}\n"
            if "mobile" in infos:
                formatted_message += f"Mobile: {infos['mobile']}\n"
            if "sujet" in infos:
                formatted_message += f"Sujet: {infos['sujet']}\n\n"
                
            formatted_message += f"Message: {message_content}"
            
            return formatted_message
    
    # 2. NOUVELLE APPROCHE SIMPLE - Filtrer les lignes problématiques
    
    # 2.1. D'abord nettoyer le HTML
    cleaned_content = pre_clean_html(html_content)
    
    # 2.2. Diviser en lignes et filtrer les lignes problématiques
    filtered_lines = []
    
    # Liste des indicateurs de lignes problématiques
    problematic_indicators = [
        "CBAO", "développeur de rentabilité", "traçabilité", 
        "http://", "https://", ".fr", ".com", "@", 
        "Envoyé par", "Afin d'assurer", "Affin d'assurer",
        "[", "]", "!/web/image/"
    ]
    
    # Mémoriser l'indice de la ligne contenant "Cordialement" ou équivalent
    signature_line_idx = -1
    
    lines = cleaned_content.split('\n')
    for i, line in enumerate(lines):
        # Détecter la signature
        if any(sig in line.lower() for sig in ["cordialement", "cdlt", "bien à vous", "salutation"]):
            signature_line_idx = i
        
        # Vérifier si la ligne contient un indicateur problématique
        is_problematic = any(indicator in line for indicator in problematic_indicators)
        
        # Si la ligne est très longue (plus de 200 caractères), la considérer comme problématique
        if len(line) > 200:
            is_problematic = True
        
        # Ajouter la ligne seulement si elle n'est pas problématique
        if not is_problematic:
            filtered_lines.append(line)
    
    # 2.3. Si on a trouvé une signature, ne garder que 2 lignes après maximum
    if signature_line_idx >= 0:
        filtered_lines = filtered_lines[:min(signature_line_idx + 3, len(filtered_lines))]
    
    # 2.4. Recombiner les lignes filtrées
    content = '\n'.join(filtered_lines)
    
    # 2.5. Nettoyer les espaces et lignes vides
    content = re.sub(r'\n{3,}', '\n\n', content)
    content = content.strip()
    
    # 2.6. VÉRIFICATION FINALE: S'assurer qu'il n'y a pas de duplication dans le contenu final
    # Si le même paragraphe apparaît deux fois, ne garder que jusqu'à la première occurrence
    lines = content.split('\n')
    unique_lines = []
    seen_paragraphs = set()
    
    for line in lines:
        clean_line = line.strip()
        # Ne traiter que les lignes non vides et assez longues pour être significatives
        if clean_line and len(clean_line) > 10:
            if clean_line in seen_paragraphs:
                # On a déjà vu cette ligne, c'est probablement une duplication
                # Arrêter le traitement ici
                break
            seen_paragraphs.add(clean_line)
        unique_lines.append(line)
    
    content = '\n'.join(unique_lines)
    
    # Résultat final
    if not content or len(content.strip()) < 10:
        return "*Contenu non extractible*"
    
    return content

def pre_clean_html(html_content):
    """
    Effectue un nettoyage préliminaire du HTML.
    """
    # Transformer les balises h1 en titres Markdown
    content = re.sub(r'<h1>(.*?)</h1>', r'### \1', html_content)
    
    # Transformer les listes à puces
    content = re.sub(r'<ul>(.*?)</ul>', r'\1', content, flags=re.DOTALL)
    content = re.sub(r'<li><b>(.*?)</b></li>', r'- **\1**\n', content)
    content = re.sub(r'<li>(.*?)</li>', r'- \1\n', content)
    
    # Supprimer les balises simples
    content = re.sub(r'<br\s*/?>|<p>|</p>|<div>|</div>', '\n', content)
    
    # Préserver le texte en gras
    content = re.sub(r'<(?:b|strong)>(.*?)</(?:b|strong)>', r'**\1**', content)
    
    # Supprimer les balises HTML restantes
    content = re.sub(r'<.*?>', '', content)
    
    # Remplacer les entités HTML courantes
    content = content.replace('&nbsp;', ' ')
    content = content.replace('&lt;', '<')
    content = content.replace('&gt;', '>')
    content = content.replace('&amp;', '&')
    content = content.replace('&quot;', '"')
    
    # Supprimer les lignes avec uniquement des **
    content = re.sub(r'^\s*\*\*\s*\*\*\s*$', '', content, flags=re.MULTILINE)
    content = re.sub(r'^\s*\*\*\s*$', '', content, flags=re.MULTILINE)
    
    # Nettoyer les espaces et sauts de ligne
    content = re.sub(r'\n\s*\n', '\n\n', content)
    
    return content

def format_date(date_str):
    """
    Formate une date ISO en format lisible.
    """
    if not date_str:
        return ""
    
    try:
        dt = datetime.fromisoformat(date_str.replace('Z', '+00:00'))
        return dt.strftime("%d/%m/%Y %H:%M:%S")
    except (ValueError, TypeError):
        return date_str

if __name__ == "__main__":
    # Tests
    html = """<p>Bonjour,</p>
<p>Voici un message avec <b>du HTML</b> et une signature.</p>
<p>Cordialement,</p>
<p>John Doe</p>
<p>Support technique</p>
<p>Afin d'assurer une meilleure traçabilité et vous garantir une prise en charge optimale,
nous vous invitons à envoyer vos demandes d'assistance technique à support@exemple.fr</p>
<p>![CBAO - développeur de rentabilité - www.exemple.fr](data:image/png;base64,ABC123)</p>
"""
    
    cleaned = clean_html(html)
    print("HTML nettoyé :\n", cleaned)
    
    # Test avec un message transféré
    forwarded = """\\-------- Message transféré --------  Sujet :  | Test message  
---|---  
Date :  | Mon, 30 Mar 2020 11:18:20 +0200  
De :  | [test@example.com](mailto:test@example.com)  
Pour :  | John Doe [](mailto:john@example.com)  
Copie à :  | [other@example.com](mailto:other@example.com)  
  
Bonjour John,

Voici un message de test.

Cordialement,
Test User

__________________________________________________________________ Ce message et toutes les pièces jointes sont confidentiels et établis à l'intention exclusive de ses destinataires. __________________________________________________________________"""
    
    cleaned_forwarded = clean_html(forwarded)
    print("\nMessage transféré nettoyé :\n", cleaned_forwarded)
    
    # Test avec le cas problématique du ticket T0282
    test_t0282 = """Bonjour,

Je reviens vers vous pour savoir si vous souhaitez toujours renommer le numéro d'identification de certaines formules dans BCN ou si vous avez trouvé une solution alternative ?

En vous remerciant par avance, je reste à votre disposition pour tout complément d'information.

Cordialement.

**Youness BENDEQ** 

[

Affin d'assurer une meilleure traçabilité et vous garantir une prise en charge optimale, nous vous invitons à envoyer vos demandes d'assistance technique à support@cbao.fr Notre service est ouvert du lundi au vendredi de 9h à 12h et de 14h à 18h. Dès réception, un technicien prendra en charge votre demande et au besoin vous rappellera."""
    
    cleaned_t0282 = clean_html(test_t0282)
    print("\nTest ticket T0282 nettoyé :\n", cleaned_t0282)
    
    # Test avec le cas problématique de bas de page avec formatage markdown
    test_cbao_markdown = """Bonjour,

Voici un message de test pour vérifier la suppression des bas de page CBAO.

Cordialement,
Jean Dupont

[ CBAO S.A.R.L. ](https://example.com/link) .

![](/web/image/33748?access_token=13949e22-d47b-4af7-868e-e9c2575469f1) ![](/web/image/33748?access_token=13949e22-d47b-4af7-868e-e9c2575469f1)"""
    
    cleaned_markdown = clean_html(test_cbao_markdown)
    print("\nTest avec formatage Markdown CBAO nettoyé :\n", cleaned_markdown)
    
    # Test avec le cas exact du rapport
    test_rapport = """Bonjour,

Voici un message de test.

Cordialement,
Pierre Martin

Envoyé  par [ CBAO S.A.R.L. ](https://ciibcee.r.af.d.sendibt2.com/tr/cl/h2uBsi9hBosNYeSHMsPH47KAmufMTuNZjreF6M_tfRE63xzft8fwSbEQNb0aYIor74WQB5L6TF4kR9szVpQnalHFa3PUn_0jeLw42JNzIwsESwVlYad_3xCC1xi7qt3-dQ7i_Rt62MG217XgidnJxyNVcXWaWG5B75sB0GoqJq13IZc-hQ) .

![](/web/image/33748?access_token=13949e22-d47b-4af7-868e-e9c2575469f1) ![](/web/image/33748?access_token=13949e22-d47b-4af7-868e-e9c2575469f1)"""
    
    cleaned_rapport = clean_html(test_rapport)
    print("\nTest avec cas exact du rapport nettoyé :\n", cleaned_rapport)