# -*- coding: utf-8 -*-
"""
ARTOS Main Docking Window
Modular GUI with dockable panels for different system modules.
"""
import tkinter as tk
from tkinter import ttk, messagebox
import logging

from pymsc.core.bus_1553_module import Bus1553Module
from pymsc.gui.docking.workspace_manager import WorkspaceManager
from pymsc.gui.docking.mcs_dock import MCSDock
from pymsc.gui.docking.placeholder_dock import PlaceholderDock
from pymsc.gui.docking.logger_dock import LoggerDock, TextWidgetHandler
from pymsc.gui.components.command_widgets import (
    CommandFrameCheckBox, CommandFrameComboBox, 
    CommandFrameSpinBox, CommandFrameLabels, 
    CommandFrameControls
)


class MainDockingWindow:
    """
    ARTOS main window with modular docking system.
    
    Architecture:
    - Left panel: MCS (Mission Control System)
    - Right top: Navigation, IRST, Algorithms (placeholders)
    - Right bottom: Logger, Status (placeholders)
    """
    
    def __init__(self, bus_module: Bus1553Module):
        """
        Args:
            bus_module: Bus1553Module instance for message access
        """
        self.bus_module = bus_module
        
        # Create main window
        self.root = tk.Tk()
        self.root.title("ARTOS - Advanced Radar Test & Orchestration System")
        self.root.geometry("1600x900")
        
        # Configure light theme
        style = ttk.Style()
        style.theme_use('clam')
        
        # Light theme configuration
        bg_light = '#f0f0f0'
        bg_lighter = '#ffffff'
        fg_dark = '#000000'
        accent = '#0078d7'
        
        self.root.configure(bg=bg_light)
        style.configure('TFrame', background=bg_light)
        style.configure('TLabel', background=bg_light, foreground=fg_dark)
        style.configure('TButton', background=accent, foreground='white')
        style.map('TButton', background=[('active', '#005a9e')])
        style.configure('TLabelframe', background=bg_light, foreground=fg_dark)
        style.configure('TLabelframe.Label', background=bg_light, foreground=fg_dark)
        
        self.root.protocol("WM_DELETE_WINDOW", self._on_close)
        
        # Create a temporary text widget for logging (will be moved to LoggerDock later)
        # This allows us to capture ALL logs from the very beginning
        import tkinter.scrolledtext as scrolledtext
        self._temp_log_widget = scrolledtext.ScrolledText(
            self.root,
            wrap=tk.WORD,
            font=('Consolas', 9),
            bg='#ffffff',
            fg='#000000',
            state='disabled'
        )
        # Configure tags for different log levels
        self._temp_log_widget.tag_config('INFO', foreground='#0066cc')
        self._temp_log_widget.tag_config('WARNING', foreground='#ff8800')
        self._temp_log_widget.tag_config('ERROR', foreground='#cc0000')
        self._temp_log_widget.tag_config('DEBUG', foreground='#666666')
        
        # Create and attach the log handler immediately
        self._log_handler = TextWidgetHandler(self._temp_log_widget)
        self._log_handler.setLevel(logging.INFO)
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        self._log_handler.setFormatter(formatter)
        logging.getLogger().addHandler(self._log_handler)
        
        # Log that GUI logger is now active
        logger = logging.getLogger('ARTOS')
        logger.info("GUI logger initialized - capturing all subsequent logs")
        
        # Create menu bar
        self._create_menu()
        
        # Create workspace manager
        self.workspace = WorkspaceManager(self.root, layouts_dir="layouts")
        
        # Create and register docks
        self._create_docks()
        
        # Load saved layout automatically after widgets are fully rendered
        self.root.after(200, lambda: self.workspace.load_layout("user_layout"))
        
        # Start refresh loops
        self._start_refresh()
    
    def _create_menu(self):
        """Create the main menu bar."""
        menubar = tk.Menu(self.root)
        self.root.config(menu=menubar)
        
        # File menu
        file_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="File", menu=file_menu)
        file_menu.add_command(label="Save Layout", command=self._save_layout)
        file_menu.add_command(label="Load Layout", command=self._load_layout)
        file_menu.add_separator()
        file_menu.add_command(label="Exit", command=self._on_close)
        
        # View menu - toggle dock visibility
        view_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="View", menu=view_menu)
        view_menu.add_command(label="Toggle MCS", 
                            command=lambda: self.workspace.toggle_dock_visibility('mcs'))
        view_menu.add_command(label="Toggle Navigation", 
                            command=lambda: self.workspace.toggle_dock_visibility('nav'))
        view_menu.add_command(label="Toggle IRST", 
                            command=lambda: self.workspace.toggle_dock_visibility('irst'))
        view_menu.add_separator()
        view_menu.add_command(label="Restore All", command=self._restore_all_docks)
        
        # System menu
        system_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="System", menu=system_menu)
        system_menu.add_command(label="Start System", command=self._start_system)
        system_menu.add_command(label="Stop System", command=self._stop_system)
        system_menu.add_separator()
        system_menu.add_command(label="System Info", command=self._show_system_info)
        
        # Help menu
        help_menu = tk.Menu(menubar, tearoff=0)
        menubar.add_cascade(label="Help", menu=help_menu)
        help_menu.add_command(label="About", command=self._show_about)
        help_menu.add_command(label="Documentation", command=self._show_docs)
    
    def _create_docks(self):
        """Create and register all dock panels."""
        # Left panel: MCS
        mcs_dock = MCSDock(
            self.workspace.left_container,
            bus_module=self.bus_module
        )
        self.workspace.add_dock('mcs', mcs_dock, position='left')
        
        # Right top: Navigation placeholder
        nav_dock = PlaceholderDock(
            self.workspace.right_top_container,
            title="Navigation System",
            description="Navigation algorithms and data processing\n\n(Coming in Phase 3)"
        )
        self.workspace.add_dock('nav', nav_dock, position='right_top')
        
        # Right bottom: IRST placeholder
        irst_dock = PlaceholderDock(
            self.workspace.right_bottom_container,
            title="IRST Module",
            description="Infrared Search & Track\n\n(Coming in Phase 4)"
        )
        self.workspace.add_dock('irst', irst_dock, position='right_bottom')
        
        # Bottom: Logger with scrollable text
        # Transfer the temporary log widget to the LoggerDock
        logger_dock = LoggerDock(
            self.workspace.bottom_container,
            existing_widget=self._temp_log_widget,
            existing_handler=self._log_handler
        )
        self.workspace.add_dock('logger', logger_dock, position='bottom')
    
    def _start_refresh(self):
        """Start the GUI refresh loop to update all widgets."""
        self.gui_refresh_loop()
    
    def _stop_refresh(self):
        """Stop refresh loops (cleanup on exit)."""
        # The refresh loop will stop automatically when window closes
        pass
    
    def gui_refresh_loop(self):
        """
        Periodically refreshes all custom widgets in all visible docks.
        This updates telemetry displays from received 1553 messages.
        """
        # First, sync all messages from the 1553 bus (read latest telemetry)
        if self.bus_module and self.bus_module.is_running:
            self.bus_module.sync_all_messages()
        
        # Then refresh widgets in all visible docks
        for dock_id, dock in self.workspace.docks.items():
            if dock.is_visible and not dock.is_minimized:
                self._refresh_widgets_recursive(dock.content_frame)
        
        # Schedule next refresh (100ms = 10 Hz update rate)
        self.root.after(100, self.gui_refresh_loop)
    
    def _refresh_widgets_recursive(self, container: tk.Widget):
        """
        Traverses the widget tree to find and update PyMsc custom components.
        Calls check_updated_value() on each command widget found.
        """
        for child in container.winfo_children():
            # Check if it's one of our custom command widgets
            is_custom = isinstance(child, (
                CommandFrameCheckBox, CommandFrameComboBox, 
                CommandFrameSpinBox, CommandFrameLabels, 
                CommandFrameControls
            ))
            
            if is_custom and hasattr(child, 'check_updated_value'):
                child.check_updated_value()
            
            # Continue searching if the child has its own children (like sub-frames)
            if child.winfo_children():
                self._refresh_widgets_recursive(child)
    
    def _save_layout(self):
        """Save current workspace layout."""
        self.workspace.save_layout("user_layout")
        messagebox.showinfo("Layout Saved", "Workspace layout saved successfully.")
    
    def _load_layout(self):
        """Load saved workspace layout."""
        self.workspace.load_layout("user_layout")
        messagebox.showinfo("Layout Loaded", "Workspace layout loaded successfully.")
    
    def _restore_all_docks(self):
        """Restore all docks to visible state."""
        for dock_id, dock in self.workspace.docks.items():
            if not dock.is_visible:
                dock.show()
            if dock.is_minimized:
                dock.restore()
    
    def _start_system(self):
        """Start the 1553 bus system."""
        if hasattr(self.bus_module, 'start'):
            self.bus_module.start()
            messagebox.showinfo("System", "Bus system started.")
    
    def _stop_system(self):
        """Stop the 1553 bus system."""
        if hasattr(self.bus_module, 'stop'):
            self.bus_module.stop()
            messagebox.showinfo("System", "Bus system stopped.")
    
    def _show_system_info(self):
        """Display system information."""
        info = f"""
ARTOS System Information

Architecture: Layered Modular Design
- L0: Hardware Abstraction (1553 Bus)
- L1: Test Orchestration (TestContext)
- L2: Algorithm Library
- L3: Test Execution

Active Modules:
- MCS: Mission Control System ✓
- Navigation: Placeholder
- IRST: Placeholder
- Logger: Placeholder

Framework: Tkinter + Custom Docking
Bus Protocol: MIL-STD-1553B over UDP
        """
        messagebox.showinfo("System Information", info.strip())
    
    def _show_about(self):
        """Show about dialog."""
        about_text = """
ARTOS v2.0
Advanced Radar Test & Orchestration System

Modular GUI with docking panels
Built with Tkinter and ttkbootstrap

© 2025
        """
        messagebox.showinfo("About ARTOS", about_text.strip())
    
    def _show_docs(self):
        """Open documentation."""
        messagebox.showinfo(
            "Documentation",
            "Documentation is available in the 'doc/' folder.\n\n"
            "Key files:\n"
            "- ARTOS_Architecture_Decisions.md\n"
            "- ARTOS_design.md\n"
            "- English-manual.md"
        )
    
    def _on_close(self):
        """Handle window close event."""
        # Save layout automatically before closing (includes window geometry)
        self.workspace.save_layout("user_layout")
        
        if messagebox.askokcancel("Quit", "Do you want to quit ARTOS?"):
            self._stop_refresh()
            self.root.quit()
            self.root.destroy()
    
    def run(self):
        """Start the main event loop."""
        self.root.mainloop()


def main():
    """Main entry point for the ARTOS GUI application."""
    # Initialize the bus module
    from pymsc.core.bus_1553_module import Bus1553Module
    
    bus_module = Bus1553Module()
    
    # Initialize with configuration
    config = {
        'udp_send_ip': '127.0.0.1',
        'udp_send_port': 51553,
        'udp_recv_ip': '0.0.0.0',
        'udp_recv_port': 61553
    }
    bus_module.initialize(config)
    
    # Create and run the main window
    app = MainDockingWindow(bus_module)
    app.run()


if __name__ == '__main__':
    main()
