"""
Intégration Orchestrator ↔ GUI
Module pour connecter l'Orchestrator à l'interface graphique
"""

import logging
from typing import Optional
from .human_logger import HumanLogger
from .signals import GUISignals
from .improved_gui import ImprovedGUI


class OrchestratorGUIBridge:
    """
    Pont entre l'Orchestrator et la GUI.
    
    Facilite la communication bidirectionnelle:
    - Orchestrator → GUI : Logs, stats, changements de mode
    - GUI → Orchestrator : Commandes (start, stop, pause)
    
    Attributes:
        orchestrator: Instance de l'Orchestrator
        gui: Instance de l'ImprovedGUI
        human_logger: Instance du HumanLogger
        signals: Signaux Qt pour communication
    """
    
    def __init__(self, orchestrator, gui: Optional[ImprovedGUI] = None):
        """
        Initialise le pont Orchestrator-GUI.
        
        Args:
            orchestrator: Instance de l'Orchestrator
            gui: Instance de l'ImprovedGUI (optionnel, sera créée si None)
        """
        self.logger = logging.getLogger(__name__)
        self.orchestrator = orchestrator
        
        # Créer ou utiliser la GUI fournie
        if gui is None:
            self.gui = ImprovedGUI(orchestrator)
        else:
            self.gui = gui
        
        # Créer le HumanLogger
        self.human_logger = HumanLogger()
        
        # Utiliser les signaux de la GUI
        self.signals = self.gui.signals
        
        # Connecter les signaux
        self._connect_gui_to_orchestrator()
        self._inject_logging_into_orchestrator()
        
        self.logger.info("OrchestratorGUIBridge initialisé")
    
    def _connect_gui_to_orchestrator(self):
        """Connecte les signaux de la GUI à l'Orchestrator."""
        # Boutons de contrôle
        self.gui.start_requested.connect(self._on_start_requested)
        self.gui.stop_requested.connect(self._on_stop_requested)
        self.gui.pause_requested.connect(self._on_pause_requested)
        
        self.logger.info("Signaux GUI → Orchestrator connectés")
    
    def _inject_logging_into_orchestrator(self):
        """Injecte le système de logging dans l'Orchestrator."""
        # Ajouter les attributs nécessaires à l'Orchestrator
        self.orchestrator.human_logger = self.human_logger
        self.orchestrator.gui_signals = self.signals
        
        # Ajouter des méthodes helper à l'Orchestrator
        self.orchestrator.log_to_gui = self.log_to_gui
        self.orchestrator.update_gui_stats = self.update_gui_stats
        self.orchestrator.change_mode_gui = self.change_mode_gui
        
        self.logger.info("Logging injecté dans l'Orchestrator")
    
    def _on_start_requested(self):
        """Gestionnaire de demande de démarrage."""
        self.logger.info("Démarrage demandé depuis la GUI")
        if hasattr(self.orchestrator, 'start'):
            try:
                self.orchestrator.start()
                self.signals.emit_status_change(True)
                self.log_to_gui("👀", "Système démarré en mode Observation", "success")
            except Exception as e:
                self.logger.error(f"Erreur au démarrage: {e}")
                self.log_to_gui("❌", f"Erreur au démarrage: {str(e)}", "error")
    
    def _on_stop_requested(self):
        """Gestionnaire de demande d'arrêt."""
        self.logger.info("Arrêt demandé depuis la GUI")
        if hasattr(self.orchestrator, 'stop'):
            try:
                self.orchestrator.stop()
                self.signals.emit_status_change(False)
                self.log_to_gui("⏹", "Système arrêté", "info")
            except Exception as e:
                self.logger.error(f"Erreur à l'arrêt: {e}")
                self.log_to_gui("❌", f"Erreur à l'arrêt: {str(e)}", "error")
    
    def _on_pause_requested(self):
        """Gestionnaire de demande de pause."""
        self.logger.info("Pause demandée depuis la GUI")
        if hasattr(self.orchestrator, 'pause'):
            try:
                self.orchestrator.pause()
                is_paused = getattr(self.orchestrator, 'is_paused', False)
                if is_paused:
                    self.log_to_gui("⏸", "Système en pause", "warning")
                else:
                    self.log_to_gui("▶", "Système repris", "success")
            except Exception as e:
                self.logger.error(f"Erreur à la pause: {e}")
                self.log_to_gui("❌", f"Erreur à la pause: {str(e)}", "error")
    
    def log_to_gui(self, emoji: str, message: str, level: str = "info"):
        """
        Envoie un log à la GUI.
        
        Args:
            emoji: Emoji à afficher
            message: Message de log
            level: Niveau du log ('info', 'success', 'warning', 'error')
            
        Examples:
            >>> bridge.log_to_gui("👀", "Action observée", "info")
        """
        self.signals.emit_log(emoji, message, level)
    
    def update_gui_stats(self, **stats):
        """
        Met à jour les statistiques de la GUI.
        
        Args:
            **stats: Statistiques à mettre à jour
                    (actions_count, patterns_count, workflows_count, etc.)
                    
        Examples:
            >>> bridge.update_gui_stats(
            ...     actions_count=12,
            ...     patterns_count=2,
            ...     workflows_count=1
            ... )
        """
        self.signals.emit_stats_update(stats)
    
    def change_mode_gui(self, mode: str):
        """
        Change le mode affiché dans la GUI.
        
        Args:
            mode: Nouveau mode ('shadow', 'assist', 'copilot', 'auto')
            
        Examples:
            >>> bridge.change_mode_gui("assist")
        """
        self.signals.emit_mode_change(mode)
    
    def show(self):
        """Affiche la GUI."""
        self.gui.show()
    
    def hide(self):
        """Masque la GUI."""
        self.gui.hide()


# Fonctions helper pour faciliter l'intégration

def setup_gui_for_orchestrator(orchestrator) -> OrchestratorGUIBridge:
    """
    Configure la GUI pour un Orchestrator.
    
    Fonction helper qui crée et configure automatiquement
    le pont entre l'Orchestrator et la GUI.
    
    Args:
        orchestrator: Instance de l'Orchestrator
        
    Returns:
        Instance du OrchestratorGUIBridge configuré
        
    Examples:
        >>> from geniusia2.core import Orchestrator
        >>> from geniusia2.gui import setup_gui_for_orchestrator
        >>> 
        >>> orchestrator = Orchestrator()
        >>> bridge = setup_gui_for_orchestrator(orchestrator)
        >>> bridge.show()
        >>> 
        >>> # Dans l'Orchestrator, utiliser:
        >>> orchestrator.log_to_gui("👀", "Message", "info")
        >>> orchestrator.update_gui_stats(actions_count=12)
    """
    bridge = OrchestratorGUIBridge(orchestrator)
    return bridge


def add_gui_logging_to_orchestrator(orchestrator, signals: GUISignals):
    """
    Ajoute le logging GUI à un Orchestrator existant.
    
    Fonction helper pour ajouter uniquement le logging
    sans créer de nouvelle GUI.
    
    Args:
        orchestrator: Instance de l'Orchestrator
        signals: Signaux GUI à utiliser
        
    Examples:
        >>> orchestrator = Orchestrator()
        >>> gui = ImprovedGUI(orchestrator)
        >>> add_gui_logging_to_orchestrator(orchestrator, gui.signals)
        >>> 
        >>> # Maintenant l'orchestrator peut logger:
        >>> orchestrator.log_to_gui("👀", "Message", "info")
    """
    human_logger = HumanLogger()
    
    orchestrator.human_logger = human_logger
    orchestrator.gui_signals = signals
    
    # Méthodes helper
    def log_to_gui(emoji: str, message: str, level: str = "info"):
        signals.emit_log(emoji, message, level)
    
    def update_gui_stats(**stats):
        signals.emit_stats_update(stats)
    
    def change_mode_gui(mode: str):
        signals.emit_mode_change(mode)
    
    orchestrator.log_to_gui = log_to_gui
    orchestrator.update_gui_stats = update_gui_stats
    orchestrator.change_mode_gui = change_mode_gui


if __name__ == "__main__":
    """Test de l'intégration Orchestrator-GUI"""
    import sys
    from PyQt5.QtWidgets import QApplication
    from PyQt5.QtCore import QTimer
    
    # Mock Orchestrator pour les tests
    class MockOrchestrator:
        def __init__(self):
            self.is_running = False
            self.is_paused = False
            self.actions_count = 0
            self.patterns_count = 0
            self.workflows_count = 0
        
        def start(self):
            print("MockOrchestrator: start()")
            self.is_running = True
        
        def stop(self):
            print("MockOrchestrator: stop()")
            self.is_running = False
        
        def pause(self):
            print("MockOrchestrator: pause()")
            self.is_paused = not self.is_paused
        
        def simulate_action(self):
            """Simule une action observée"""
            self.actions_count += 1
            self.log_to_gui("👀", f"Action #{self.actions_count} observée", "info")
            self.update_gui_stats(
                actions_count=self.actions_count,
                patterns_count=self.patterns_count,
                workflows_count=self.workflows_count
            )
    
    app = QApplication(sys.argv)
    
    print("=" * 60)
    print("Test de l'intégration Orchestrator-GUI")
    print("=" * 60)
    
    # Créer un mock orchestrator
    orchestrator = MockOrchestrator()
    
    # Configurer la GUI
    bridge = setup_gui_for_orchestrator(orchestrator)
    bridge.show()
    
    print("\n✓ GUI créée et affichée")
    print("✓ Orchestrator connecté")
    
    # Simuler des événements
    def simulate_workflow():
        print("\n📝 Simulation d'événements...")
        
        # Démarrer
        QTimer.singleShot(1000, lambda: [
            print("  1. Démarrage"),
            orchestrator.start(),
            bridge.signals.emit_status_change(True),
            bridge.log_to_gui("✅", "Système démarré", "success")
        ])
        
        # Actions
        QTimer.singleShot(2000, lambda: [
            print("  2. Action 1"),
            orchestrator.simulate_action()
        ])
        
        QTimer.singleShot(3000, lambda: [
            print("  3. Action 2"),
            orchestrator.simulate_action()
        ])
        
        QTimer.singleShot(4000, lambda: [
            print("  4. Action 3"),
            orchestrator.simulate_action()
        ])
        
        # Pattern détecté
        QTimer.singleShot(5000, lambda: [
            print("  5. Pattern détecté"),
            setattr(orchestrator, 'patterns_count', 1),
            bridge.log_to_gui("🎯", "Pattern détecté !", "success"),
            bridge.update_gui_stats(
                actions_count=orchestrator.actions_count,
                patterns_count=1,
                workflows_count=0
            )
        ])
        
        # Changement de mode
        QTimer.singleShot(6000, lambda: [
            print("  6. Changement de mode"),
            bridge.change_mode_gui("assist"),
            bridge.log_to_gui("✅", "Mode Suggestions activé", "success")
        ])
    
    QTimer.singleShot(500, simulate_workflow)
    
    print("\nTestez les boutons de la GUI:")
    print("  - Pause")
    print("  - Arrêter")
    print("  - System tray")
    
    sys.exit(app.exec_())
