"""
Tests pour le ThemeApplicator - Application de thèmes de couleur au GUI.
"""

import unittest
import os
import sys
from pathlib import Path

# Ajouter le chemin racine pour les imports
sys.path.insert(0, str(Path(__file__).parent.parent))

try:
    import tkinter as tk
    from tkinter import ttk
    from web_sentinel.gui.theme_applicator import ThemeApplicator
    HAS_TKINTER = True
except ImportError:
    HAS_TKINTER = False


@unittest.skipUnless(HAS_TKINTER, "Tkinter n'est pas disponible")
class TestThemeApplicator(unittest.TestCase):
    """Tests pour l'application de thèmes de couleur."""
    
    def setUp(self):
        """Créer une fenêtre test avant chaque test."""
        self.root = tk.Tk()
        self.root.withdraw()  # Ne pas afficher la fenêtre
        
    def tearDown(self):
        """Nettoyer après chaque test."""
        try:
            self.root.destroy()
        except:
            pass
    
    def test_themes_definition(self):
        """Vérifier que tous les thèmes sont définis."""
        expected_themes = ["classic", "dark", "cyberpunk", "minimal"]
        
        for theme_name in expected_themes:
            self.assertIn(theme_name, ThemeApplicator.THEMES)
            
            # Vérifier que chaque thème a les couleurs requises
            theme = ThemeApplicator.THEMES[theme_name]
            required_keys = ["bg_primary", "bg_secondary", "text_primary", 
                           "text_secondary", "accent", "border"]
            
            for key in required_keys:
                self.assertIn(key, theme, 
                            f"Thème '{theme_name}' manque la clé '{key}'")
    
    def test_apply_classic_theme(self):
        """Tester l'application du thème classic."""
        # Créer quelques widgets
        frame = ttk.Frame(self.root)
        label = ttk.Label(frame, text="Test")
        button = ttk.Button(frame, text="Cliquer")
        
        frame.pack()
        label.pack()
        button.pack()
        
        # Appliquer le thème
        ThemeApplicator.apply_theme(self.root, "classic")
        
        # Vérifier que la méthode s'exécute sans erreur
        self.assertIsNotNone(self.root.cget("bg"))
    
    def test_apply_dark_theme(self):
        """Tester l'application du thème dark."""
        frame = tk.Frame(self.root)
        label = tk.Label(frame, text="Test")
        
        frame.pack()
        label.pack()
        
        ThemeApplicator.apply_theme(self.root, "dark")
        
        # Vérifier que le fond du root a changé
        bg_color = self.root.cget("bg")
        self.assertIsNotNone(bg_color)
    
    def test_apply_cyberpunk_theme(self):
        """Tester l'application du thème cyberpunk."""
        frame = tk.Frame(self.root)
        button = tk.Button(frame, text="Test")
        
        frame.pack()
        button.pack()
        
        ThemeApplicator.apply_theme(self.root, "cyberpunk")
        
        # Vérifier pas d'exception
        self.assertIsNotNone(self.root.cget("bg"))
    
    def test_apply_minimal_theme(self):
        """Tester l'application du thème minimal."""
        frame = tk.Frame(self.root)
        entry = tk.Entry(frame)
        
        frame.pack()
        entry.pack()
        
        ThemeApplicator.apply_theme(self.root, "minimal")
        
        # Vérifier pas d'exception
        self.assertIsNotNone(self.root.cget("bg"))
    
    def test_apply_to_complex_hierarchy(self):
        """Tester l'application sur une hiérarchie complexe de widgets."""
        # Créer une structure complexe
        main_frame = tk.Frame(self.root)
        
        top_frame = tk.Frame(main_frame)
        label1 = tk.Label(top_frame, text="Label 1")
        button1 = tk.Button(top_frame, text="Button 1")
        
        middle_frame = ttk.Frame(main_frame)
        label2 = ttk.Label(middle_frame, text="Label 2")
        entry = ttk.Entry(middle_frame)
        
        bottom_frame = tk.Frame(main_frame)
        button2 = tk.Button(bottom_frame, text="Button 2")
        text = tk.Text(bottom_frame, height=5, width=30)
        
        # Emballer
        main_frame.pack()
        top_frame.pack()
        label1.pack()
        button1.pack()
        middle_frame.pack()
        label2.pack()
        entry.pack()
        bottom_frame.pack()
        button2.pack()
        text.pack()
        
        # Appliquer le thème
        ThemeApplicator.apply_theme(self.root, "dark")
        
        # Vérifier que ça marche sans erreur
        self.assertIsNotNone(main_frame.cget("bg"))
    
    def test_apply_invalid_theme(self):
        """Tester avec un nom de thème invalide (doit utiliser classic par défaut)."""
        frame = tk.Frame(self.root)
        frame.pack()
        
        # Devrait utiliser classic si le thème n'existe pas
        ThemeApplicator.apply_theme(self.root, "theme_inexistant")
        
        # Ne devrait pas planter
        self.assertIsNotNone(self.root.cget("bg"))
    
    def test_theme_colors_validity(self):
        """Vérifier que toutes les couleurs définies sont valides."""
        for theme_name, colors in ThemeApplicator.THEMES.items():
            for color_key, color_value in colors.items():
                # Vérifier que c'est une chaîne
                self.assertIsInstance(color_value, str, 
                                    f"Couleur '{color_key}' dans '{theme_name}' n'est pas une chaîne")
                
                # Vérifier que ça commence par # (hex) ou est un nom de couleur
                self.assertTrue(
                    color_value.startswith("#") or color_value.isalpha(),
                    f"Couleur '{color_key}' = '{color_value}' dans '{theme_name}' invalide"
                )


if __name__ == '__main__':
    unittest.main()
