"""
Interface GUI améliorée avec onglets pour Web Sentinel
Séparation des différents types d'analyse en onglets distincts
"""

import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
import threading
import json
import webbrowser
import os
from pathlib import Path
from typing import List, Dict, Any, Optional
import datetime

from ..model import ScanRequest
from ..scanner import SentinelScanner
from ..reporting import HistoryStore, ReportEngine
from ..subscription import SubscriptionManager, SubscriptionTier
from ..subscription.validator import LicenseError as SubscriptionLicenseError, LicenseValidator
from ..payment.payment_modal import PaymentModalController
from ..payment.stripe_client import StripeClient
from ..auth import AuthManager, LoginDialog
from ..license.license_manager import LicenceError as EmbeddedLicenceError
from ..license.runtime_bridge import get_license_bridge, initialize_license_system
from .i18n import localization
from .invasive_warning import show_invasive_warning
from .license_dialog import LicenceOperationError, show_license_status_dialog


class TabWebSentinelGUI:
    """Interface Web Sentinel avec onglets séparés pour chaque type d'analyse."""
    
    def __init__(self, subscription_tier: str | SubscriptionTier | None = None):
        self.root = tk.Tk()
        self.root.title(localization.t("app_title"))
        self.root.geometry("1400x900")
        self.root.minsize(1200, 700)
        
        # Configuration du redimensionnement automatique
        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_columnconfigure(0, weight=1)
        
        # Variables communes
        self.current_scan_thread = None
        self.scan_results = []
        self.is_scanning = False
        
        # Système d'authentification et de licence
        self.auth_manager = AuthManager()
        self.license_bridge = get_license_bridge()
        self.license_initialized = initialize_license_system()
        self._synchronize_license_with_auth()
        self.subscription_manager = self.license_bridge.get_runtime_manager()
        self.license_validator = self.license_bridge.get_runtime_validator()
        self.license_status = self.license_bridge.get_license_status()
        
        # Configuration
        self.config_file = Path.home() / ".web-sentinel" / "gui-config.json"
        self.load_config()
        
        # Créer l'interface avec onglets
        self.setup_tabbed_ui()
        self.load_domains_from_config()
        self.refresh_subscription_ui(self.license_status)
        
        # Gestion du redimensionnement
        self.root.bind('<Configure>', self.on_window_configure)
    
    def _synchronize_license_with_auth(self):
        """Synchroniser le système de licence avec l'authentification."""
        # Cette méthode synchronise les systèmes
        pass
    
    def setup_tabbed_ui(self):
        """Créer l'interface utilisateur avec onglets."""
        
        # Frame principal
        main_frame = ttk.Frame(self.root)
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=10, pady=10)
        main_frame.grid_rowconfigure(1, weight=1)
        main_frame.grid_columnconfigure(0, weight=1)
        
        # En-tête avec informations utilisateur
        self.create_header(main_frame)
        
        # Notebook (système d'onglets)
        self.notebook = ttk.Notebook(main_frame)
        self.notebook.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(10, 0))
        
        # Onglet 1: Scan de domaine (existant)
        self.domain_tab = ttk.Frame(self.notebook)
        self.notebook.add(self.domain_tab, text="🌐 Scan de domaine")
        self.setup_domain_tab()
        
        # Onglet 2: Analyse de code source (SAST)
        self.sast_tab = ttk.Frame(self.notebook)
        self.notebook.add(self.sast_tab, text="🔍 Code source (SAST)")
        self.setup_sast_tab()
        
        # Onglet 3: Rapports et historique
        self.reports_tab = ttk.Frame(self.notebook)
        self.notebook.add(self.reports_tab, text="📊 Rapports")
        self.setup_reports_tab()
        
        # Onglet 4: Configuration
        self.config_tab = ttk.Frame(self.notebook)
        self.notebook.add(self.config_tab, text="⚙️ Configuration")
        self.setup_config_tab()
        
        # Barre de statut commune
        self.create_status_bar(main_frame)
        
        # Vérifier les permissions et activer/désactiver les onglets
        self.update_tab_permissions()
    
    def create_header(self, parent):
        """Créer l'en-tête avec informations utilisateur et licence."""
        header_frame = ttk.Frame(parent)
        header_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
        header_frame.grid_columnconfigure(1, weight=1)
        
        # Logo et titre
        title_frame = ttk.Frame(header_frame)
        title_frame.grid(row=0, column=0, sticky=tk.W)
        
        title_label = ttk.Label(title_frame, text="🛡️ Web Sentinel", font=("Arial", 16, "bold"))
        title_label.grid(row=0, column=0)
        
        subtitle_label = ttk.Label(title_frame, text="Scanner de sécurité web", font=("Arial", 10))
        subtitle_label.grid(row=1, column=0, sticky=tk.W)
        
        # Informations utilisateur et licence
        self.user_frame = ttk.Frame(header_frame)
        self.user_frame.grid(row=0, column=2, sticky=tk.E)
        self._create_user_section()
    
    def _create_user_section(self):
        """Créer la section utilisateur dans l'en-tête."""
        for widget in self.user_frame.winfo_children():
            widget.destroy()
        
        if self.auth_manager.is_authenticated():
            user = self.auth_manager.get_current_user()
            if user:
                user_info = ttk.Label(self.user_frame, text=f"👤 {user.display_name}", font=("Arial", 10))
                user_info.grid(row=0, column=0, padx=(0, 10))
                
                tier_text = self.subscription_manager.tier.value.upper()
                tier_colors = {"FREE": "#6b7280", "PRO": "#2563eb", "ENTERPRISE": "#7c3aed", "SYSOP": "#dc2626"}
                tier_label = ttk.Label(self.user_frame, text=f"🎯 {tier_text}", font=("Arial", 9, "bold"))
                tier_label.grid(row=0, column=1, padx=(0, 10))
        else:
            guest_label = ttk.Label(self.user_frame, text="👤 Mode invité (FREE)", font=("Arial", 10))
            guest_label.grid(row=0, column=0, padx=(0, 10))
    
    def setup_domain_tab(self):
        """Configuration de l'onglet scan de domaine."""
        # Configuration similaire à l'ancienne interface mais simplifiée
        tab_frame = ttk.Frame(self.domain_tab)
        tab_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=20, pady=20)
        tab_frame.grid_rowconfigure(2, weight=1)
        tab_frame.grid_columnconfigure(0, weight=1)
        
        # Section domaines
        domains_frame = ttk.LabelFrame(tab_frame, text="🌐 Domaines à analyser", padding="15")
        domains_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        domains_frame.grid_columnconfigure(0, weight=1)
        
        self.domains_text = scrolledtext.ScrolledText(domains_frame, height=4, wrap=tk.WORD)
        self.domains_text.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # Boutons de gestion des domaines
        domain_buttons = ttk.Frame(domains_frame)
        domain_buttons.grid(row=1, column=0, sticky=tk.W)
        
        ttk.Button(domain_buttons, text="💾 Sauvegarder", command=self.save_domains).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(domain_buttons, text="🗑️ Effacer", command=self.clear_domains).pack(side=tk.LEFT)
        
        # Options de scan
        options_frame = ttk.LabelFrame(tab_frame, text="⚙️ Options de scan", padding="15")
        options_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        
        # Timeout et mode invasif
        opts_row1 = ttk.Frame(options_frame)
        opts_row1.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 10))
        
        self.timeout_var = tk.DoubleVar(value=5.0)
        ttk.Label(opts_row1, text="Timeout (s):").grid(row=0, column=0, padx=(0, 5))
        ttk.Spinbox(opts_row1, from_=1.0, to=30.0, increment=1.0, textvariable=self.timeout_var, width=10).grid(row=0, column=1, padx=(0, 20))
        
        self.allow_invasive_var = tk.BooleanVar()
        self.invasive_check = ttk.Checkbutton(opts_row1, text="Tests invasifs", variable=self.allow_invasive_var)
        self.invasive_check.grid(row=0, column=2, sticky=tk.W)
        if not self.subscription_manager.can_use_invasive_tests():
            self.invasive_check.state(["disabled"])
        
        # Modules
        opts_row2 = ttk.Frame(options_frame)
        opts_row2.grid(row=1, column=0, sticky=(tk.W, tk.E))
        
        ttk.Label(opts_row2, text="Modules:").grid(row=0, column=0, padx=(0, 10), sticky=tk.W)
        
        self.domain_module_vars = {
            'tls': tk.BooleanVar(value=True),
            'headers': tk.BooleanVar(value=True),
            'static-analysis': tk.BooleanVar(value=True),
            'injection': tk.BooleanVar(value=True),
            'third-party': tk.BooleanVar(value=False)
        }
        
        col = 1
        for module, var in self.domain_module_vars.items():
            translated_name = localization.translate_module(module)
            cb = ttk.Checkbutton(opts_row2, text=translated_name, variable=var)
            cb.grid(row=0, column=col, padx=(0, 10), sticky=tk.W)
            col += 1
        
        # Boutons d'action
        action_frame = ttk.Frame(tab_frame)
        action_frame.grid(row=2, column=0, sticky=tk.W, pady=(15, 0))
        
        self.domain_scan_btn = ttk.Button(action_frame, text="🚀 Lancer le scan", command=self.start_domain_scan, style="Accent.TButton")
        self.domain_scan_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        self.domain_stop_btn = ttk.Button(action_frame, text="⏹️ Arrêter", command=self.stop_scan, state=tk.DISABLED)
        self.domain_stop_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        self.domain_export_btn = ttk.Button(action_frame, text="📤 Exporter", command=self.export_report, state=tk.DISABLED)
        self.domain_export_btn.pack(side=tk.LEFT)
    
    def setup_sast_tab(self):
        """Configuration de l'onglet SAST (analyse de code source)."""
        tab_frame = ttk.Frame(self.sast_tab)
        tab_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=20, pady=20)
        tab_frame.grid_rowconfigure(3, weight=1)
        tab_frame.grid_columnconfigure(0, weight=1)
        
        # Vérification des permissions SAST
        if not self._can_use_sast():
            self.create_sast_upgrade_message(tab_frame)
            return
        
        # Section sélection de code source
        source_frame = ttk.LabelFrame(tab_frame, text="📁 Sélection du code source", padding="15")
        source_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        source_frame.grid_columnconfigure(1, weight=1)
        
        # Type de sélection
        selection_type_frame = ttk.Frame(source_frame)
        selection_type_frame.grid(row=0, column=0, columnspan=3, sticky=(tk.W, tk.E), pady=(0, 10))
        
        self.source_type_var = tk.StringVar(value="folder")
        ttk.Radiobutton(selection_type_frame, text="📁 Dossier complet", variable=self.source_type_var, value="folder").grid(row=0, column=0, padx=(0, 20))
        ttk.Radiobutton(selection_type_frame, text="📄 Fichiers spécifiques", variable=self.source_type_var, value="files").grid(row=0, column=1)
        
        # Sélection de dossier/fichiers
        ttk.Label(source_frame, text="Chemin:").grid(row=1, column=0, padx=(0, 10), sticky=tk.W)
        
        self.source_path_var = tk.StringVar()
        self.source_path_entry = ttk.Entry(source_frame, textvariable=self.source_path_var, width=50)
        self.source_path_entry.grid(row=1, column=1, padx=(0, 10), sticky=(tk.W, tk.E))
        
        browse_frame = ttk.Frame(source_frame)
        browse_frame.grid(row=1, column=2)
        ttk.Button(browse_frame, text="📁 Dossier", command=self.browse_source_folder).pack(side=tk.TOP)
        ttk.Button(browse_frame, text="📄 Fichiers", command=self.browse_source_files).pack(side=tk.TOP)
        
        # Configuration SAST
        sast_config_frame = ttk.LabelFrame(tab_frame, text="⚙️ Configuration SAST", padding="15")
        sast_config_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        sast_config_frame.grid_columnconfigure(1, weight=1)
        
        # Langages
        ttk.Label(sast_config_frame, text="Langages:").grid(row=0, column=0, padx=(0, 10), sticky=tk.W)
        self.source_languages_var = tk.StringVar(value="php,javascript,python,java,csharp,go")
        ttk.Entry(sast_config_frame, textvariable=self.source_languages_var, width=40).grid(row=0, column=1, sticky=(tk.W, tk.E))
        
        # Exclusions
        ttk.Label(sast_config_frame, text="Exclure:").grid(row=1, column=0, padx=(0, 10), sticky=tk.W, pady=(10, 0))
        self.source_exclude_var = tk.StringVar(value="node_modules/*,vendor/*,.git/*,*.min.js,*.min.css")
        ttk.Entry(sast_config_frame, textvariable=self.source_exclude_var, width=40).grid(row=1, column=1, sticky=(tk.W, tk.E), pady=(10, 0))
        
        # Niveau de sévérité
        ttk.Label(sast_config_frame, text="Sévérité min:").grid(row=2, column=0, padx=(0, 10), sticky=tk.W, pady=(10, 0))
        self.sast_severity_var = tk.StringVar(value="medium")
        severity_combo = ttk.Combobox(sast_config_frame, textvariable=self.sast_severity_var, values=["info", "low", "medium", "high", "critical"], state="readonly", width=15)
        severity_combo.grid(row=2, column=1, sticky=tk.W, pady=(10, 0))
        
        # Informations de licence
        license_info_frame = ttk.LabelFrame(tab_frame, text="ℹ️ Informations de licence", padding="10")
        license_info_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        
        features = self.subscription_manager.get_features()
        tier_name = self.subscription_manager.tier.value.upper()
        
        try:
            from ..subscription.models import get_features_for_tier
            direct_features = get_features_for_tier(self.subscription_manager.tier)
            max_files = direct_features.max_source_files if direct_features.max_source_files != -1 else "Illimité"
            max_size = f"{direct_features.max_source_size_mb} MB" if direct_features.max_source_size_mb != -1 else "Illimitée"
        except:
            max_files = "Non disponible"
            max_size = "Non disponible"
        
        license_text = f"Licence {tier_name} - Limite: {max_files} fichiers/mois - Taille max: {max_size}"
        ttk.Label(license_info_frame, text=license_text).grid(row=0, column=0)
        
        # Boutons d'action SAST
        sast_action_frame = ttk.Frame(tab_frame)
        sast_action_frame.grid(row=3, column=0, sticky=tk.W, pady=(15, 0))
        
        self.sast_scan_btn = ttk.Button(sast_action_frame, text="🔍 Analyser le code", command=self.start_sast_scan, style="Accent.TButton")
        self.sast_scan_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        self.sast_stop_btn = ttk.Button(sast_action_frame, text="⏹️ Arrêter", command=self.stop_scan, state=tk.DISABLED)
        self.sast_stop_btn.pack(side=tk.LEFT, padx=(0, 10))
        
        self.sast_export_btn = ttk.Button(sast_action_frame, text="📤 Exporter", command=self.export_sast_report, state=tk.DISABLED)
        self.sast_export_btn.pack(side=tk.LEFT)
    
    def create_sast_upgrade_message(self, parent):
        """Créer le message d'upgrade pour l'onglet SAST."""
        upgrade_frame = ttk.Frame(parent)
        upgrade_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        upgrade_frame.grid_rowconfigure(0, weight=1)
        upgrade_frame.grid_columnconfigure(0, weight=1)
        
        message_frame = ttk.Frame(upgrade_frame)
        message_frame.place(relx=0.5, rely=0.5, anchor=tk.CENTER)
        
        icon_label = ttk.Label(message_frame, text="🔒", font=("Arial", 48))
        icon_label.grid(row=0, column=0, pady=(0, 20))
        
        title_label = ttk.Label(message_frame, text="Analyse de code source (SAST)", font=("Arial", 16, "bold"))
        title_label.grid(row=1, column=0, pady=(0, 10))
        
        desc_label = ttk.Label(message_frame, text="Fonctionnalité disponible avec les licences PRO, ENTERPRISE et SYSOP", font=("Arial", 12))
        desc_label.grid(row=2, column=0, pady=(0, 20))
        
        features_text = """✨ Fonctionnalités SAST:
• Analyse statique de code multi-langages
• Détection de vulnérabilités OWASP Top 10
• Support PHP, JavaScript, Python, Java, C#, Go
• Rapports détaillés avec recommandations"""
        
        features_label = ttk.Label(message_frame, text=features_text, font=("Arial", 10), justify=tk.LEFT)
        features_label.grid(row=3, column=0, pady=(0, 20))
        
        ttk.Button(message_frame, text="⬆️ Mettre à niveau", command=self.show_upgrade_dialog, style="Accent.TButton").grid(row=4, column=0)
    
    def setup_reports_tab(self):
        """Configuration de l'onglet rapports."""
        tab_frame = ttk.Frame(self.reports_tab)
        tab_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=20, pady=20)
        
        # Zone de résultats commune avec TreeView
        results_frame = ttk.LabelFrame(tab_frame, text="📊 Résultats des analyses", padding="10")
        results_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        results_frame.grid_rowconfigure(0, weight=1)
        results_frame.grid_columnconfigure(0, weight=1)
        
        # TreeView pour afficher les résultats
        columns = ("Type", "Domaine/Source", "Sévérité", "Titre", "Description")
        self.results_tree = ttk.Treeview(results_frame, columns=columns, show="headings", height=20)
        
        # Configuration des colonnes
        self.results_tree.heading("Type", text="Type")
        self.results_tree.heading("Domaine/Source", text="Domaine/Source")
        self.results_tree.heading("Sévérité", text="Sévérité")
        self.results_tree.heading("Titre", text="Titre")
        self.results_tree.heading("Description", text="Description")
        
        self.results_tree.column("Type", width=100)
        self.results_tree.column("Domaine/Source", width=200)
        self.results_tree.column("Sévérité", width=80)
        self.results_tree.column("Titre", width=250)
        self.results_tree.column("Description", width=300)
        
        # Scrollbars
        v_scrollbar = ttk.Scrollbar(results_frame, orient=tk.VERTICAL, command=self.results_tree.yview)
        h_scrollbar = ttk.Scrollbar(results_frame, orient=tk.HORIZONTAL, command=self.results_tree.xview)
        self.results_tree.configure(yscrollcommand=v_scrollbar.set, xscrollcommand=h_scrollbar.set)
        
        self.results_tree.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        v_scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
        h_scrollbar.grid(row=1, column=0, sticky=(tk.W, tk.E))
    
    def setup_config_tab(self):
        """Configuration de l'onglet configuration."""
        tab_frame = ttk.Frame(self.config_tab)
        tab_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=20, pady=20)
        
        ttk.Label(tab_frame, text="⚙️ Configuration", font=("Arial", 16, "bold")).grid(row=0, column=0, sticky=tk.W, pady=(0, 20))
        
        # Section utilisateur
        user_frame = ttk.LabelFrame(tab_frame, text="👤 Compte utilisateur", padding="15")
        user_frame.grid(row=1, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        
        if self.auth_manager.is_authenticated():
            user = self.auth_manager.get_current_user()
            if user:
                ttk.Label(user_frame, text=f"Connecté: {user.display_name}").grid(row=0, column=0, sticky=tk.W)
                ttk.Button(user_frame, text="Déconnexion", command=self._on_logout).grid(row=1, column=0, sticky=tk.W, pady=(10, 0))
        else:
            ttk.Label(user_frame, text="Mode invité").grid(row=0, column=0, sticky=tk.W)
            ttk.Button(user_frame, text="Se connecter", command=self._on_login).grid(row=1, column=0, sticky=tk.W, pady=(10, 0))
        
        # Section licence
        license_frame = ttk.LabelFrame(tab_frame, text="🎫 Licence", padding="15")
        license_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=(0, 15))
        
        tier_text = self.subscription_manager.tier.value.upper()
        ttk.Label(license_frame, text=f"Licence actuelle: {tier_text}").grid(row=0, column=0, sticky=tk.W)
        ttk.Button(license_frame, text="Gérer la licence", command=self._show_license_status).grid(row=1, column=0, sticky=tk.W, pady=(10, 0))
    
    def create_status_bar(self, parent):
        """Créer la barre de statut commune."""
        status_frame = ttk.Frame(parent)
        status_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=(10, 0))
        status_frame.grid_columnconfigure(0, weight=1)
        
        self.status_label = ttk.Label(status_frame, text="Prêt")
        self.status_label.grid(row=0, column=0, sticky=tk.W)
        
        self.progress_bar = ttk.Progressbar(status_frame, mode='indeterminate')
        self.progress_bar.grid(row=0, column=1, sticky=tk.E, padx=(10, 0))
    
    def _can_use_sast(self) -> bool:
        """Vérifier si l'utilisateur peut utiliser le SAST selon sa licence."""
        try:
            # Vérification directe via le tier
            tier = self.subscription_manager.tier
            from ..subscription.models import get_features_for_tier
            direct_features = get_features_for_tier(tier)
            return direct_features.allow_source_scan
        except Exception as e:
            print(f"[DEBUG] _can_use_sast error: {e}")
            # Par défaut, autoriser pour les tiers payants
            try:
                tier = self.subscription_manager.tier
                return tier.value.upper() in ['PRO', 'ENTERPRISE', 'SYSOP']
            except:
                return False
    
    def update_tab_permissions(self):
        """Mettre à jour les permissions des onglets selon la licence."""
        # L'onglet SAST est toujours visible mais le contenu change selon les permissions
        pass
    
    # Méthodes de navigation et sélection de fichiers
    def browse_source_folder(self):
        """Ouvrir un dialogue de sélection de dossier."""
        folder = filedialog.askdirectory(
            title="Sélectionner le dossier contenant le code source",
            initialdir=self.source_path_var.get() or os.getcwd()
        )
        if folder:
            self.source_path_var.set(folder)
    
    def browse_source_files(self):
        """Ouvrir un dialogue de sélection de fichiers multiples."""
        files = filedialog.askopenfilenames(
            title="Sélectionner les fichiers de code source",
            initialdir=os.path.dirname(self.source_path_var.get()) if self.source_path_var.get() else os.getcwd(),
            filetypes=[
                ("Tous les fichiers de code", "*.php;*.js;*.py;*.java;*.cs;*.go"),
                ("PHP", "*.php"),
                ("JavaScript", "*.js"),
                ("Python", "*.py"),
                ("Java", "*.java"),
                ("C#", "*.cs"),
                ("Go", "*.go"),
                ("Tous", "*.*")
            ]
        )
        if files:
            # Joindre les fichiers avec des virgules
            self.source_path_var.set(";".join(files))
    
    # Méthodes de scan (à implémenter)
    def start_domain_scan(self):
        """Lancer le scan de domaine."""
        messagebox.showinfo("Scan de domaine", "Fonctionnalité en cours d'implémentation")
    
    def start_sast_scan(self):
        """Lancer l'analyse SAST."""
        if not self.source_path_var.get():
            messagebox.showerror("Erreur", "Veuillez sélectionner un dossier ou des fichiers source")
            return
        
        messagebox.showinfo("Analyse SAST", f"Analyse en cours de {self.source_path_var.get()}")
    
    def stop_scan(self):
        """Arrêter le scan en cours."""
        pass
    
    def export_report(self):
        """Exporter le rapport de scan de domaine."""
        pass
    
    def export_sast_report(self):
        """Exporter le rapport SAST."""
        pass
    
    # Méthodes de configuration
    def load_config(self):
        """Charger la configuration."""
        try:
            if self.config_file.exists():
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    self.config = json.load(f)
            else:
                self.config = {"domains": [], "last_settings": {}}
        except Exception:
            self.config = {"domains": [], "last_settings": {}}
    
    def save_config(self):
        """Sauvegarder la configuration."""
        try:
            self.config_file.parent.mkdir(parents=True, exist_ok=True)
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, indent=2, ensure_ascii=False)
        except Exception as e:
            messagebox.showerror("Erreur", f"Erreur de sauvegarde: {e}")
    
    def load_domains_from_config(self):
        """Charger les domaines depuis la configuration."""
        domains = self.config.get("domains", [])
        if domains and hasattr(self, 'domains_text'):
            self.domains_text.delete(1.0, tk.END)
            self.domains_text.insert(1.0, "\\n".join(domains))
    
    def save_domains(self):
        """Sauvegarder les domaines."""
        if hasattr(self, 'domains_text'):
            domains = self.domains_text.get(1.0, tk.END).strip().split('\\n')
            self.config["domains"] = [d.strip() for d in domains if d.strip()]
            self.save_config()
            messagebox.showinfo("Succès", "Domaines sauvegardés")
    
    def clear_domains(self):
        """Effacer les domaines."""
        if hasattr(self, 'domains_text'):
            self.domains_text.delete(1.0, tk.END)
    
    # Méthodes d'authentification et licence
    def _on_login(self):
        """Gérer la connexion."""
        pass
    
    def _on_logout(self):
        """Gérer la déconnexion."""
        pass
    
    def _show_license_status(self):
        """Afficher le statut de la licence."""
        pass
    
    def show_upgrade_dialog(self):
        """Afficher le dialogue d'upgrade."""
        messagebox.showinfo("Upgrade", "Contactez-nous pour mettre à niveau votre licence")
    
    def refresh_subscription_ui(self, license_status):
        """Rafraîchir l'interface selon le statut de la licence."""
        pass
    
    def on_window_configure(self, event):
        """Gérer le redimensionnement de la fenêtre."""
        pass
    
    def run(self):
        """Lancer l'application."""
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
        self.root.mainloop()
    
    def on_closing(self):
        """Gestionnaire de fermeture de l'application."""
        self.save_config()
        self.root.destroy()


def main():
    """Point d'entrée de l'interface avec onglets."""
    app = TabWebSentinelGUI()
    app.run()


if __name__ == "__main__":
    main()