"""
Tests unitaires pour HumanLogger
Teste le formatage des messages, les emojis et les messages contextuels.
"""

import sys
from pathlib import Path

# Ajouter le répertoire parent au path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))

from geniusia2.gui.human_logger import HumanLogger


def test_initialization():
    """Test l'initialisation de HumanLogger"""
    print("Test 1: Initialisation...")
    logger = HumanLogger()
    
    # Vérifier que les événements "première fois" sont initialisés
    assert "workflow_detected" in logger.first_time_events
    assert "mode_change" in logger.first_time_events
    assert "pattern_detected" in logger.first_time_events
    assert "finetuning_started" in logger.first_time_events
    
    # Tous doivent être False au départ
    assert logger.first_time_events["workflow_detected"] is False
    assert logger.first_time_events["mode_change"] is False
    assert logger.first_time_events["pattern_detected"] is False
    assert logger.first_time_events["finetuning_started"] is False
    
    print("✓ Initialisation OK")


def test_log_observation_format():
    """Test le formatage des messages d'observation"""
    print("\nTest 2: Formatage log_observation...")
    logger = HumanLogger()
    
    # Test avec différentes fenêtres
    msg1 = logger.log_observation("click", "Calculator")
    assert "👀" in msg1, "L'emoji d'observation doit être présent"
    assert "Calculator" in msg1, "Le nom de la fenêtre doit être présent"
    assert "J'observe" in msg1, "Le message doit contenir 'J'observe'"
    
    msg2 = logger.log_observation("type", "Firefox")
    assert "👀" in msg2
    assert "Firefox" in msg2
    
    msg3 = logger.log_observation("scroll", "LibreOffice Writer")
    assert "👀" in msg3
    assert "LibreOffice Writer" in msg3
    
    print("✓ Formatage log_observation OK")


def test_log_pattern_detected_emoji():
    """Test l'emoji correct pour pattern détecté"""
    print("\nTest 3: Emoji log_pattern_detected...")
    logger = HumanLogger()
    
    msg = logger.log_pattern_detected(3, "Calculer 9/9")
    assert "🎯" in msg, "L'emoji de pattern doit être présent"
    assert "3 fois" in msg, "Le nombre de répétitions doit être présent"
    
    print("✓ Emoji log_pattern_detected OK")


def test_log_pattern_detected_contextual():
    """Test les messages contextuels pour pattern détecté"""
    print("\nTest 4: Messages contextuels log_pattern_detected...")
    logger = HumanLogger()
    
    # Première fois - doit inclure le contexte
    msg1 = logger.log_pattern_detected(3, "Calculer 9/9")
    assert "Je commence à apprendre" in msg1, "Le message contextuel doit être présent la première fois"
    assert logger.first_time_events["pattern_detected"] is True, "Le flag doit être mis à True"
    
    # Deuxième fois - ne doit pas inclure le contexte
    msg2 = logger.log_pattern_detected(4, "Ouvrir fichier")
    assert "Je commence à apprendre" not in msg2, "Le message contextuel ne doit pas être répété"
    
    print("✓ Messages contextuels log_pattern_detected OK")


def test_log_workflow_learned_format():
    """Test le formatage des messages de workflow appris"""
    print("\nTest 5: Formatage log_workflow_learned...")
    logger = HumanLogger()
    
    msg = logger.log_workflow_learned("Ouvrir facture", 5)
    assert "📚" in msg, "L'emoji de workflow doit être présent"
    assert "Ouvrir facture" in msg, "Le nom du workflow doit être présent"
    assert "5 observations" in msg, "Le nombre d'observations doit être présent"
    assert "J'apprends" in msg, "Le message doit contenir 'J'apprends'"
    
    print("✓ Formatage log_workflow_learned OK")


def test_log_workflow_learned_contextual():
    """Test les messages contextuels pour workflow appris"""
    print("\nTest 6: Messages contextuels log_workflow_learned...")
    logger = HumanLogger()
    
    # Première fois - doit inclure l'explication
    msg1 = logger.log_workflow_learned("Ouvrir facture", 5)
    assert "Un workflow est une séquence" in msg1, "L'explication doit être présente la première fois"
    assert logger.first_time_events["workflow_detected"] is True
    
    # Deuxième fois - ne doit pas inclure l'explication
    msg2 = logger.log_workflow_learned("Calculer total", 3)
    assert "Un workflow est une séquence" not in msg2, "L'explication ne doit pas être répétée"
    
    print("✓ Messages contextuels log_workflow_learned OK")


def test_log_mode_change_format():
    """Test le formatage des messages de changement de mode"""
    print("\nTest 7: Formatage log_mode_change...")
    logger = HumanLogger()
    
    # Test tous les modes
    msg_shadow = logger.log_mode_change("assist", "shadow")
    assert "✅" in msg_shadow, "L'emoji de succès doit être présent"
    assert "Observation" in msg_shadow, "Le nom du mode doit être traduit"
    
    msg_assist = logger.log_mode_change("shadow", "assist")
    assert "✅" in msg_assist
    assert "Suggestions" in msg_assist
    
    msg_copilot = logger.log_mode_change("assist", "copilot")
    assert "✅" in msg_copilot
    assert "Copilote" in msg_copilot
    
    msg_auto = logger.log_mode_change("copilot", "auto")
    assert "✅" in msg_auto
    assert "Autonome" in msg_auto
    
    print("✓ Formatage log_mode_change OK")


def test_log_mode_change_contextual():
    """Test les messages contextuels pour changement de mode"""
    print("\nTest 8: Messages contextuels log_mode_change...")
    logger = HumanLogger()
    
    # Première fois vers assist - doit inclure l'explication
    msg1 = logger.log_mode_change("shadow", "assist")
    assert "Je vais maintenant vous suggérer" in msg1, "L'explication du mode assist doit être présente"
    assert logger.first_time_events["mode_change"] is True
    
    # Deuxième fois - ne doit pas inclure l'explication
    msg2 = logger.log_mode_change("assist", "auto")
    assert "Je vais maintenant vous suggérer" not in msg2, "L'explication ne doit pas être répétée"
    
    print("✓ Messages contextuels log_mode_change OK")


def test_log_mode_change_explanations():
    """Test les explications spécifiques à chaque mode"""
    print("\nTest 9: Explications spécifiques des modes...")
    
    # Test mode assist
    logger_assist = HumanLogger()
    msg_assist = logger_assist.log_mode_change("shadow", "assist")
    assert "suggérer des actions" in msg_assist
    
    # Test mode copilot
    logger_copilot = HumanLogger()
    msg_copilot = logger_copilot.log_mode_change("assist", "copilot")
    assert "exécuter avec votre validation" in msg_copilot
    
    # Test mode auto
    logger_auto = HumanLogger()
    msg_auto = logger_auto.log_mode_change("copilot", "auto")
    assert "agir de manière autonome" in msg_auto
    
    # Test mode shadow (pas d'explication spéciale)
    logger_shadow = HumanLogger()
    msg_shadow = logger_shadow.log_mode_change("assist", "shadow")
    assert "💡" not in msg_shadow or "Je vais maintenant" not in msg_shadow
    
    print("✓ Explications spécifiques des modes OK")


def test_log_finetuning_started_format():
    """Test le formatage des messages de début de fine-tuning"""
    print("\nTest 10: Formatage log_finetuning_started...")
    logger = HumanLogger()
    
    msg = logger.log_finetuning_started(10)
    assert "🧠" in msg, "L'emoji de cerveau doit être présent"
    assert "10 exemples" in msg, "Le nombre d'exemples doit être présent"
    assert "Amélioration du modèle" in msg, "Le message doit contenir 'Amélioration du modèle'"
    
    print("✓ Formatage log_finetuning_started OK")


def test_log_finetuning_started_contextual():
    """Test les messages contextuels pour début de fine-tuning"""
    print("\nTest 11: Messages contextuels log_finetuning_started...")
    logger = HumanLogger()
    
    # Première fois - doit inclure l'explication
    msg1 = logger.log_finetuning_started(10)
    assert "J'améliore ma compréhension" in msg1, "L'explication doit être présente la première fois"
    assert logger.first_time_events["finetuning_started"] is True
    
    # Deuxième fois - ne doit pas inclure l'explication
    msg2 = logger.log_finetuning_started(15)
    assert "J'améliore ma compréhension" not in msg2, "L'explication ne doit pas être répétée"
    
    print("✓ Messages contextuels log_finetuning_started OK")


def test_log_finetuning_completed_format():
    """Test le formatage des messages de fin de fine-tuning"""
    print("\nTest 12: Formatage log_finetuning_completed...")
    logger = HumanLogger()
    
    msg1 = logger.log_finetuning_completed(2.5)
    assert "✅" in msg1, "L'emoji de succès doit être présent"
    assert "2.5s" in msg1, "La durée doit être présente avec 1 décimale"
    assert "Modèle amélioré" in msg1
    
    msg2 = logger.log_finetuning_completed(10.123)
    assert "10.1s" in msg2, "La durée doit être arrondie à 1 décimale"
    
    print("✓ Formatage log_finetuning_completed OK")


def test_log_error_types():
    """Test les différents types d'erreurs"""
    print("\nTest 13: Types d'erreurs...")
    logger = HumanLogger()
    
    # Test tous les types d'erreurs
    error_types = ["connection", "permission", "not_found", "timeout", "whitelist", "unknown"]
    
    for error_type in error_types:
        msg = logger.log_error(error_type)
        assert "⚠️" in msg, f"L'emoji d'avertissement doit être présent pour {error_type}"
    
    # Vérifier les messages spécifiques
    msg_connection = logger.log_error("connection")
    assert "Impossible de se connecter" in msg_connection
    
    msg_permission = logger.log_error("permission")
    assert "Permission refusée" in msg_permission
    
    msg_not_found = logger.log_error("not_found")
    assert "Élément introuvable" in msg_not_found
    
    msg_timeout = logger.log_error("timeout")
    assert "Délai d'attente dépassé" in msg_timeout
    
    msg_whitelist = logger.log_error("whitelist")
    assert "Application non autorisée" in msg_whitelist
    
    msg_unknown = logger.log_error("unknown_type")
    assert "Une erreur est survenue" in msg_unknown
    
    print("✓ Types d'erreurs OK")


def test_log_error_with_context():
    """Test les erreurs avec contexte"""
    print("\nTest 14: Erreurs avec contexte...")
    logger = HumanLogger()
    
    msg = logger.log_error("connection", "Calculator")
    assert "Calculator" in msg, "Le contexte doit être présent"
    
    msg2 = logger.log_error("permission", "Firefox")
    assert "Firefox" in msg2
    
    print("✓ Erreurs avec contexte OK")


def test_log_error_suggestions():
    """Test les suggestions correctives pour les erreurs"""
    print("\nTest 15: Suggestions correctives...")
    logger = HumanLogger()
    
    # Vérifier que chaque type d'erreur a une suggestion
    msg_connection = logger.log_error("connection")
    assert "💡" in msg_connection, "Une suggestion doit être présente"
    assert "Vérifiez que l'application est ouverte" in msg_connection
    
    msg_permission = logger.log_error("permission")
    assert "💡" in msg_permission
    assert "Vérifiez les permissions" in msg_permission
    
    msg_not_found = logger.log_error("not_found")
    assert "💡" in msg_not_found
    assert "interface a peut-être changé" in msg_not_found
    
    msg_timeout = logger.log_error("timeout")
    assert "💡" in msg_timeout
    assert "application est peut-être trop lente" in msg_timeout
    
    msg_whitelist = logger.log_error("whitelist")
    assert "💡" in msg_whitelist
    assert "Ajoutez l'application à la liste autorisée" in msg_whitelist
    
    print("✓ Suggestions correctives OK")


def test_log_idle():
    """Test le message d'inactivité"""
    print("\nTest 16: Message d'inactivité...")
    logger = HumanLogger()
    
    msg = logger.log_idle()
    assert "💤" in msg, "L'emoji de sommeil doit être présent"
    assert "En attente" in msg, "Le message doit indiquer l'attente"
    
    print("✓ Message d'inactivité OK")


def test_log_stats_update():
    """Test le formatage des statistiques"""
    print("\nTest 17: Formatage des statistiques...")
    logger = HumanLogger()
    
    # Test avec 1 workflow (singulier)
    msg1 = logger.log_stats_update(12, 2, 1)
    assert "📊" in msg1, "L'emoji de statistiques doit être présent"
    assert "12 actions" in msg1
    assert "2 patterns" in msg1
    assert "1 workflow" in msg1
    assert "workflows" not in msg1, "Doit être au singulier pour 1 workflow"
    
    # Test avec plusieurs workflows (pluriel)
    msg2 = logger.log_stats_update(25, 5, 3)
    assert "25 actions" in msg2
    assert "5 patterns" in msg2
    assert "3 workflows" in msg2, "Doit être au pluriel pour plusieurs workflows"
    
    # Test avec 0 workflow
    msg3 = logger.log_stats_update(5, 0, 0)
    assert "0 workflow" in msg3, "Doit être au singulier pour 0 workflow"
    
    print("✓ Formatage des statistiques OK")


def test_log_suggestion_ready():
    """Test le message de suggestion prête"""
    print("\nTest 18: Message de suggestion prête...")
    logger = HumanLogger()
    
    msg = logger.log_suggestion_ready("Ouvrir facture")
    assert "💡" in msg, "L'emoji d'idée doit être présent"
    assert "Prêt à suggérer" in msg
    assert "Ouvrir facture" in msg, "Le nom de la tâche doit être présent"
    
    print("✓ Message de suggestion prête OK")


def test_log_collecting_examples():
    """Test le message de collecte d'exemples"""
    print("\nTest 19: Message de collecte d'exemples...")
    logger = HumanLogger()
    
    msg = logger.log_collecting_examples(8, 10)
    assert "🧠" in msg, "L'emoji de cerveau doit être présent"
    assert "8/10" in msg, "La progression doit être présente"
    assert "Collecte d'exemples" in msg
    
    # Test avec différentes valeurs
    msg2 = logger.log_collecting_examples(1, 5)
    assert "1/5" in msg2
    
    msg3 = logger.log_collecting_examples(10, 10)
    assert "10/10" in msg3
    
    print("✓ Message de collecte d'exemples OK")


def test_emoji_consistency():
    """Test la cohérence des emojis utilisés"""
    print("\nTest 20: Cohérence des emojis...")
    logger = HumanLogger()
    
    # Vérifier que les mêmes emojis sont utilisés de manière cohérente
    emojis = {
        "observation": "👀",
        "pattern": "🎯",
        "workflow": "📚",
        "success": "✅",
        "brain": "🧠",
        "warning": "⚠️",
        "idea": "💡",
        "stats": "📊",
        "sleep": "💤"
    }
    
    # Observation
    assert emojis["observation"] in logger.log_observation("click", "Test")
    
    # Pattern
    assert emojis["pattern"] in logger.log_pattern_detected(3, "Test")
    
    # Workflow
    assert emojis["workflow"] in logger.log_workflow_learned("Test", 5)
    
    # Success
    assert emojis["success"] in logger.log_mode_change("shadow", "assist")
    assert emojis["success"] in logger.log_finetuning_completed(2.5)
    
    # Brain
    assert emojis["brain"] in logger.log_finetuning_started(10)
    assert emojis["brain"] in logger.log_collecting_examples(8, 10)
    
    # Warning
    assert emojis["warning"] in logger.log_error("connection")
    
    # Idea
    assert emojis["idea"] in logger.log_suggestion_ready("Test")
    
    # Stats
    assert emojis["stats"] in logger.log_stats_update(12, 2, 1)
    
    # Sleep
    assert emojis["sleep"] in logger.log_idle()
    
    print("✓ Cohérence des emojis OK")


def test_message_length():
    """Test que les messages ne sont pas trop longs"""
    print("\nTest 21: Longueur des messages...")
    logger = HumanLogger()
    
    # Les messages de base (sans contexte) ne doivent pas dépasser 80 caractères
    msg1 = logger.log_observation("click", "Calculator")
    base_msg1 = msg1.split("\n")[0]  # Première ligne seulement
    assert len(base_msg1) <= 80, f"Message trop long: {len(base_msg1)} caractères"
    
    # Créer un nouveau logger pour éviter les messages contextuels
    logger2 = HumanLogger()
    logger2.first_time_events = {k: True for k in logger2.first_time_events}
    
    msg2 = logger2.log_pattern_detected(3, "Calculer 9/9")
    base_msg2 = msg2.split("\n")[0]
    assert len(base_msg2) <= 80, f"Message trop long: {len(base_msg2)} caractères"
    
    msg3 = logger2.log_workflow_learned("Ouvrir facture", 5)
    base_msg3 = msg3.split("\n")[0]
    assert len(base_msg3) <= 80, f"Message trop long: {len(base_msg3)} caractères"
    
    print("✓ Longueur des messages OK")


def test_first_time_tracking():
    """Test le tracking des événements 'première fois'"""
    print("\nTest 22: Tracking des premières fois...")
    logger = HumanLogger()
    
    # Vérifier l'état initial
    assert all(not v for v in logger.first_time_events.values()), "Tous les flags doivent être False au départ"
    
    # Déclencher chaque événement et vérifier le flag
    logger.log_pattern_detected(3, "Test")
    assert logger.first_time_events["pattern_detected"] is True
    
    logger.log_workflow_learned("Test", 5)
    assert logger.first_time_events["workflow_detected"] is True
    
    logger.log_mode_change("shadow", "assist")
    assert logger.first_time_events["mode_change"] is True
    
    logger.log_finetuning_started(10)
    assert logger.first_time_events["finetuning_started"] is True
    
    print("✓ Tracking des premières fois OK")


def run_all_tests():
    """Exécute tous les tests"""
    print("=" * 60)
    print("Tests unitaires de HumanLogger")
    print("=" * 60)
    
    try:
        test_initialization()
        test_log_observation_format()
        test_log_pattern_detected_emoji()
        test_log_pattern_detected_contextual()
        test_log_workflow_learned_format()
        test_log_workflow_learned_contextual()
        test_log_mode_change_format()
        test_log_mode_change_contextual()
        test_log_mode_change_explanations()
        test_log_finetuning_started_format()
        test_log_finetuning_started_contextual()
        test_log_finetuning_completed_format()
        test_log_error_types()
        test_log_error_with_context()
        test_log_error_suggestions()
        test_log_idle()
        test_log_stats_update()
        test_log_suggestion_ready()
        test_log_collecting_examples()
        test_emoji_consistency()
        test_message_length()
        test_first_time_tracking()
        
        print("\n" + "=" * 60)
        print("✓ TOUS LES TESTS RÉUSSIS!")
        print("=" * 60)
        return True
        
    except AssertionError as e:
        print(f"\n✗ ÉCHEC DU TEST: {e}")
        import traceback
        traceback.print_exc()
        return False
    except Exception as e:
        print(f"\n✗ ERREUR: {e}")
        import traceback
        traceback.print_exc()
        return False


if __name__ == "__main__":
    success = run_all_tests()
    sys.exit(0 if success else 1)
