"""
Sélecteur de thème avec prévisualisation pour Web Sentinel
Permet à l'utilisateur de choisir et prévisualiser différents thèmes
"""

import tkinter as tk
from tkinter import ttk
from typing import Optional, Callable
from .themes import ThemeManager, Theme


class ThemeSelectorDialog:
    """Dialogue de sélection de thème avec prévisualisation."""
    
    def __init__(self, parent: tk.Tk, current_theme: str = "default", 
                 on_theme_change: Optional[Callable[[str], None]] = None):
        self.parent = parent
        self.current_theme = current_theme
        self.on_theme_change = on_theme_change
        self.selected_theme = current_theme
        
        # Création de la fenêtre
        self.dialog = tk.Toplevel(parent)
        self.dialog.title("🎨 Sélection du thème")
        self.dialog.geometry("900x600")
        self.dialog.resizable(True, True)
        self.dialog.transient(parent)
        self.dialog.grab_set()
        
        # Centrer la fenêtre
        self.dialog.update_idletasks()
        x = (self.dialog.winfo_screenwidth() // 2) - (900 // 2)
        y = (self.dialog.winfo_screenheight() // 2) - (600 // 2)
        self.dialog.geometry(f"900x600+{x}+{y}")
        
        self.setup_ui()
    
    def setup_ui(self):
        """Création de l'interface du sélecteur."""
        # Frame principal
        main_frame = ttk.Frame(self.dialog, padding="20")
        main_frame.pack(fill=tk.BOTH, expand=True)
        
        # Titre
        title_label = ttk.Label(main_frame, 
                               text="🎨 Choisissez votre thème",
                               font=("Arial", 16, "bold"))
        title_label.pack(pady=(0, 20))
        
        # Container pour la liste et la prévisualisation
        content_frame = ttk.Frame(main_frame)
        content_frame.pack(fill=tk.BOTH, expand=True)
        content_frame.columnconfigure(0, weight=1)
        content_frame.columnconfigure(1, weight=2)
        content_frame.rowconfigure(0, weight=1)
        
        # ===== LISTE DES THÈMES (gauche) =====
        list_frame = ttk.LabelFrame(content_frame, text="📋 Thèmes disponibles", padding="10")
        list_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 10))
        list_frame.columnconfigure(0, weight=1)
        list_frame.rowconfigure(0, weight=1)
        
        # Listbox avec scrollbar
        list_container = ttk.Frame(list_frame)
        list_container.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        list_container.columnconfigure(0, weight=1)
        list_container.rowconfigure(0, weight=1)
        
        scrollbar = ttk.Scrollbar(list_container)
        scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
        
        self.theme_listbox = tk.Listbox(list_container,
                                        yscrollcommand=scrollbar.set,
                                        font=("Arial", 11),
                                        height=15,
                                        activestyle='dotbox')
        self.theme_listbox.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        scrollbar.config(command=self.theme_listbox.yview)
        
        # Descriptions des thèmes
        theme_descriptions = {
            "default": "🏢 Classique - Thème clair et professionnel",
            "dark": "🌙 Sombre - Mode nuit élégant",
            "cyberpunk": "⚡ Cyberpunk - Néon futuriste",
            "nord": "❄️ Nord - Palette scandinave",
            "ocean": "🌊 Ocean - Bleu apaisant",
            "forest": "🌲 Forest - Vert nature",
        }
        
        # Remplir la liste
        for theme_name in ThemeManager.get_theme_names():
            display_name = theme_descriptions.get(theme_name, theme_name.capitalize())
            self.theme_listbox.insert(tk.END, display_name)
            
            # Sélectionner le thème actuel
            if theme_name == self.current_theme:
                self.theme_listbox.selection_set(self.theme_listbox.size() - 1)
        
        # Bind selection
        self.theme_listbox.bind('<<ListboxSelect>>', self.on_theme_selected)
        
        # ===== PRÉVISUALISATION (droite) =====
        preview_frame = ttk.LabelFrame(content_frame, text="👁️ Prévisualisation", padding="10")
        preview_frame.grid(row=0, column=1, sticky=(tk.W, tk.E, tk.N, tk.S))
        preview_frame.columnconfigure(0, weight=1)
        preview_frame.rowconfigure(0, weight=1)
        
        # Canvas de prévisualisation
        self.preview_canvas = tk.Canvas(preview_frame, 
                                        highlightthickness=1,
                                        highlightbackground="#d1d5db")
        self.preview_canvas.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # ===== BOUTONS (bas) =====
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=(20, 0))
        
        # Bouton Appliquer
        apply_btn = ttk.Button(button_frame,
                              text="✅ Appliquer",
                              command=self.apply_theme,
                              style="Accent.TButton")
        apply_btn.pack(side=tk.RIGHT, padx=(10, 0))
        
        # Bouton Annuler
        cancel_btn = ttk.Button(button_frame,
                               text="❌ Annuler",
                               command=self.dialog.destroy)
        cancel_btn.pack(side=tk.RIGHT)
        
        # Prévisualisation initiale
        self.update_preview()
    
    def on_theme_selected(self, event):
        """Appelé quand un thème est sélectionné."""
        self.update_preview()
    
    def get_selected_theme_name(self) -> str:
        """Récupère le nom du thème sélectionné."""
        selection = self.theme_listbox.curselection()
        if selection:
            index = selection[0]
            theme_names = ThemeManager.get_theme_names()
            return theme_names[index]
        return self.current_theme
    
    def update_preview(self):
        """Met à jour la prévisualisation du thème."""
        theme_name = self.get_selected_theme_name()
        theme = ThemeManager.get_theme(theme_name)
        
        if not theme:
            return
        
        # Nettoyer le canvas
        self.preview_canvas.delete("all")
        
        # Dimensions du canvas
        width = self.preview_canvas.winfo_width() or 500
        height = self.preview_canvas.winfo_height() or 400
        
        if width < 100:  # Canvas pas encore rendu
            self.dialog.after(100, self.update_preview)
            return
        
        colors = theme.colors
        
        # Fond principal
        self.preview_canvas.configure(bg=colors.bg_primary)
        
        # Marges
        margin = 20
        y_offset = margin
        
        # === En-tête ===
        # Titre
        self.preview_canvas.create_text(
            width // 2, y_offset + 15,
            text="Web Sentinel",
            font=("Arial", 16, "bold"),
            fill=colors.fg_accent
        )
        y_offset += 50
        
        # === Card exemple ===
        card_height = 120
        self.preview_canvas.create_rectangle(
            margin, y_offset,
            width - margin, y_offset + card_height,
            fill=colors.bg_secondary,
            outline=colors.border,
            width=1
        )
        
        # Texte dans la card
        self.preview_canvas.create_text(
            margin + 10, y_offset + 15,
            text="🔍 Configuration du scan",
            font=("Arial", 12, "bold"),
            fill=colors.fg_primary,
            anchor="w"
        )
        
        # Checkbox simulé
        checkbox_y = y_offset + 45
        self.preview_canvas.create_rectangle(
            margin + 10, checkbox_y,
            margin + 25, checkbox_y + 15,
            fill=colors.entry_bg,
            outline=colors.border
        )
        self.preview_canvas.create_text(
            margin + 35, checkbox_y + 7,
            text="✓ Analyser les en-têtes HTTP",
            font=("Arial", 10),
            fill=colors.fg_primary,
            anchor="w"
        )
        
        # Entry simulé
        entry_y = checkbox_y + 30
        self.preview_canvas.create_rectangle(
            margin + 10, entry_y,
            width - margin - 10, entry_y + 25,
            fill=colors.entry_bg,
            outline=colors.entry_border,
            width=2
        )
        self.preview_canvas.create_text(
            margin + 15, entry_y + 12,
            text="example.com",
            font=("Arial", 10),
            fill=colors.entry_fg,
            anchor="w"
        )
        
        y_offset += card_height + 20
        
        # === Boutons ===
        button_width = 100
        button_height = 30
        button_x = margin + 10
        
        # Bouton principal
        self.preview_canvas.create_rectangle(
            button_x, y_offset,
            button_x + button_width, y_offset + button_height,
            fill=colors.button_bg,
            outline="",
            width=0
        )
        self.preview_canvas.create_text(
            button_x + button_width // 2, y_offset + button_height // 2,
            text="🚀 Scanner",
            font=("Arial", 10, "bold"),
            fill=colors.button_fg
        )
        
        # Bouton succès
        success_btn_x = button_x + button_width + 10
        self.preview_canvas.create_rectangle(
            success_btn_x, y_offset,
            success_btn_x + button_width, y_offset + button_height,
            fill=colors.success,
            outline="",
            width=0
        )
        self.preview_canvas.create_text(
            success_btn_x + button_width // 2, y_offset + button_height // 2,
            text="✅ Valider",
            font=("Arial", 10, "bold"),
            fill="white"
        )
        
        # Bouton erreur
        error_btn_x = success_btn_x + button_width + 10
        self.preview_canvas.create_rectangle(
            error_btn_x, y_offset,
            error_btn_x + button_width, y_offset + button_height,
            fill=colors.error,
            outline="",
            width=0
        )
        self.preview_canvas.create_text(
            error_btn_x + button_width // 2, y_offset + button_height // 2,
            text="❌ Annuler",
            font=("Arial", 10, "bold"),
            fill="white"
        )
        
        y_offset += button_height + 30
        
        # === Résultats (tableau simulé) ===
        results_label_y = y_offset
        self.preview_canvas.create_text(
            margin + 10, results_label_y,
            text="📊 Résultats du scan",
            font=("Arial", 12, "bold"),
            fill=colors.fg_primary,
            anchor="w"
        )
        
        y_offset += 30
        
        # En-têtes de tableau
        table_header_height = 30
        self.preview_canvas.create_rectangle(
            margin, y_offset,
            width - margin, y_offset + table_header_height,
            fill=colors.bg_accent,
            outline=colors.border,
            width=1
        )
        self.preview_canvas.create_text(
            margin + 10, y_offset + table_header_height // 2,
            text="Sévérité",
            font=("Arial", 10, "bold"),
            fill=colors.fg_accent,
            anchor="w"
        )
        self.preview_canvas.create_text(
            width // 2, y_offset + table_header_height // 2,
            text="Vulnérabilité détectée",
            font=("Arial", 10, "bold"),
            fill=colors.fg_accent,
            anchor="w"
        )
        
        y_offset += table_header_height
        
        # Lignes de résultats (exemples de sévérité)
        severities = [
            ("CRITICAL", colors.critical_bg, colors.critical_fg),
            ("HIGH", colors.high_bg, colors.high_fg),
            ("MEDIUM", colors.medium_bg, colors.medium_fg),
            ("LOW", colors.low_bg, colors.low_fg),
        ]
        
        row_height = 30
        for sev_text, bg_color, fg_color in severities:
            self.preview_canvas.create_rectangle(
                margin, y_offset,
                width - margin, y_offset + row_height,
                fill=bg_color,
                outline=colors.border,
                width=1
            )
            self.preview_canvas.create_text(
                margin + 10, y_offset + row_height // 2,
                text=sev_text,
                font=("Arial", 9, "bold"),
                fill=fg_color,
                anchor="w"
            )
            
            # Description (aléatoire)
            descriptions = {
                "CRITICAL": "Certificat TLS expiré",
                "HIGH": "En-tête HSTS manquant",
                "MEDIUM": "Version serveur exposée",
                "LOW": "Cookie sans flag Secure",
            }
            self.preview_canvas.create_text(
                width // 2, y_offset + row_height // 2,
                text=descriptions.get(sev_text, "Problème détecté"),
                font=("Arial", 9),
                fill=fg_color,
                anchor="w"
            )
            
            y_offset += row_height
    
    def apply_theme(self):
        """Applique le thème sélectionné."""
        theme_name = self.get_selected_theme_name()
        self.selected_theme = theme_name
        
        if self.on_theme_change:
            self.on_theme_change(theme_name)
        
        self.dialog.destroy()
    
    def show(self) -> str:
        """Affiche le dialogue et retourne le thème sélectionné."""
        self.dialog.wait_window()
        return self.selected_theme


def show_theme_selector(parent: tk.Tk, 
                        current_theme: str = "default",
                        on_theme_change: Optional[Callable[[str], None]] = None) -> str:
    """
    Affiche le sélecteur de thème.
    
    Args:
        parent: Fenêtre parente
        current_theme: Nom du thème actuel
        on_theme_change: Callback appelé quand le thème change
    
    Returns:
        Nom du thème sélectionné
    """
    dialog = ThemeSelectorDialog(parent, current_theme, on_theme_change)
    return dialog.show()
