# -*- coding: utf-8 -*-
"""
WorkspaceManager: Manages layout and lifecycle of dockable panels.
Uses tk.PanedWindow for resizable splits.
"""
import tkinter as tk
from tkinter import ttk
import json
import os
from typing import Dict, Optional
from .dock_frame import DockFrame


class WorkspaceManager:
    """
    Manages the layout and lifecycle of dock frames.
    
    Features:
    - Dynamic layout with resizable panes (tk.PanedWindow)
    - Dock registration and retrieval
    - Save/load workspace layouts to JSON
    - Multiple dock positions (left, right, bottom, etc.)
    """
    
    def __init__(self, root: tk.Tk, layouts_dir: str = "layouts"):
        """
        Args:
            root: Root Tk window
            layouts_dir: Directory to store layout configurations
        """
        self.root = root
        self.layouts_dir = layouts_dir
        self.docks: Dict[str, DockFrame] = {}
        
        # Create layouts directory if needed
        if not os.path.exists(self.layouts_dir):
            os.makedirs(self.layouts_dir)
        
        self._create_layout()
    
    def _create_layout(self):
        """Create the main paned window layout structure."""
        # Main container
        self.main_container = ttk.Frame(self.root)
        self.main_container.pack(fill=tk.BOTH, expand=True)
        
        # Main vertical split (top | bottom logger)
        self.main_pane = tk.PanedWindow(
            self.main_container,
            orient=tk.VERTICAL,
            sashrelief=tk.RAISED,
            sashwidth=4,
            bg='#cccccc'
        )
        self.main_pane.pack(fill=tk.BOTH, expand=True)
        
        # Top horizontal split (MCS | right panels)
        self.top_pane = tk.PanedWindow(
            self.main_pane,
            orient=tk.HORIZONTAL,
            sashrelief=tk.RAISED,
            sashwidth=4,
            bg='#cccccc'
        )
        self.main_pane.add(self.top_pane, minsize=400)
        
        # Left panel container (MCS)
        self.left_container = ttk.Frame(self.top_pane)
        self.top_pane.add(self.left_container, minsize=400, width=650)
        
        # Right side vertical split (nav | irst)
        self.right_pane = tk.PanedWindow(
            self.top_pane,
            orient=tk.VERTICAL,
            sashrelief=tk.RAISED,
            sashwidth=4,
            bg='#cccccc'
        )
        self.top_pane.add(self.right_pane, minsize=300)
        
        # Right top container (Navigation)
        self.right_top_container = ttk.Frame(self.right_pane)
        self.right_pane.add(self.right_top_container, minsize=150)
        
        # Right bottom container (IRST)
        self.right_bottom_container = ttk.Frame(self.right_pane)
        self.right_pane.add(self.right_bottom_container, minsize=150)
        
        # Bottom logger container (full width)
        self.bottom_container = ttk.Frame(self.main_pane)
        self.main_pane.add(self.bottom_container, minsize=150, height=200)
    
    def add_dock(self, dock_id: str, dock: DockFrame, 
                 position: str = 'left') -> DockFrame:
        """
        Register and place a dock in the workspace.
        
        Args:
            dock_id: Unique identifier for the dock
            dock: DockFrame instance
            position: Where to place the dock ('left', 'right_top', 'right_bottom', 'bottom')
        
        Returns:
            The dock instance
        """
        self.docks[dock_id] = dock
        
        if position == 'left':
            dock.pack(in_=self.left_container, side=tk.TOP, fill=tk.BOTH, expand=True)
        elif position == 'right_top':
            dock.pack(in_=self.right_top_container, side=tk.TOP, fill=tk.BOTH, expand=True)
        elif position == 'right_bottom':
            dock.pack(in_=self.right_bottom_container, side=tk.TOP, fill=tk.BOTH, expand=True)
        elif position == 'bottom':
            dock.pack(in_=self.bottom_container, side=tk.TOP, fill=tk.BOTH, expand=True)
        else:
            raise ValueError(f"Unknown position: {position}")
        
        # Call populate_content if not done yet
        dock.populate_content()
        
        return dock
    
    def get_dock(self, dock_id: str) -> Optional[DockFrame]:
        """Retrieve a dock by its ID."""
        return self.docks.get(dock_id)
    
    def remove_dock(self, dock_id: str):
        """Remove a dock from the workspace."""
        dock = self.docks.get(dock_id)
        if dock:
            dock.close()
            del self.docks[dock_id]
    
    def toggle_dock_visibility(self, dock_id: str):
        """Toggle the visibility of a dock."""
        dock = self.docks.get(dock_id)
        if dock:
            if dock.is_visible:
                dock.close()
            else:
                dock.show()
    
    def save_layout(self, layout_name: str = "default"):
        """
        Save the current workspace layout to a JSON file.
        
        Args:
            layout_name: Name of the layout configuration
        """
        layout_file = os.path.join(self.layouts_dir, f"{layout_name}.json")
        
        # Get current window geometry
        window_geometry = self.root.geometry()
        
        # Get current sash positions
        top_sash_pos = None
        right_sash_pos = None
        main_sash_pos = None
        
        try:
            # Main vertical split (top | bottom)
            if hasattr(self, 'main_pane') and len(self.main_pane.panes()) > 0:
                main_sash_pos = self.main_pane.sash_coord(0)
            
            # Top horizontal split (MCS | right)
            if hasattr(self, 'top_pane') and len(self.top_pane.panes()) > 0:
                top_sash_pos = self.top_pane.sash_coord(0)
            
            # Right vertical split (nav | irst)
            if hasattr(self, 'right_pane') and len(self.right_pane.panes()) > 0:
                right_sash_pos = self.right_pane.sash_coord(0)
        except tk.TclError:
            pass  # Ignore errors if panes not ready
        
        layout_config = {
            'window_geometry': window_geometry,
            'main_sash_position': main_sash_pos,
            'top_sash_position': top_sash_pos,
            'right_sash_position': right_sash_pos,
            'docks': {
                dock_id: {
                    'visible': dock.is_visible,
                    'minimized': dock.is_minimized
                }
                for dock_id, dock in self.docks.items()
            }
        }
        
        try:
            with open(layout_file, 'w') as f:
                json.dump(layout_config, f, indent=2)
            print(f"Layout saved to {layout_file}")
        except Exception as e:
            print(f"Failed to save layout: {e}")
    
    def load_layout(self, layout_name: str = "default"):
        """
        Load a workspace layout from a JSON file.
        
        Args:
            layout_name: Name of the layout configuration to load
        """
        layout_file = os.path.join(self.layouts_dir, f"{layout_name}.json")
        
        if not os.path.exists(layout_file):
            print(f"Layout file not found: {layout_file} - using default layout")
            return
        
        try:
            with open(layout_file) as f:
                layout_config = json.load(f)
            
            # Restore window geometry immediately
            if layout_config.get('window_geometry'):
                try:
                    self.root.geometry(layout_config['window_geometry'])
                    print(f"Window geometry restored: {layout_config['window_geometry']}")
                except Exception as e:
                    print(f"Error restoring window geometry: {e}")
            
            # Restore sash positions after a delay to ensure widgets are rendered
            def restore_sashes():
                try:
                    # Restore main vertical split (top | bottom)
                    if layout_config.get('main_sash_position'):
                        x, y = layout_config['main_sash_position']
                        if hasattr(self, 'main_pane') and len(self.main_pane.panes()) > 0:
                            self.main_pane.sash_place(0, x, y)
                            print(f"Main sash restored: ({x}, {y})")
                    
                    # Restore top horizontal split (MCS | right)
                    if layout_config.get('top_sash_position'):
                        x, y = layout_config['top_sash_position']
                        if hasattr(self, 'top_pane') and len(self.top_pane.panes()) > 0:
                            self.top_pane.sash_place(0, x, y)
                            print(f"Top sash restored: ({x}, {y})")
                    
                    # Restore right vertical split (nav | irst)
                    if layout_config.get('right_sash_position'):
                        x, y = layout_config['right_sash_position']
                        if hasattr(self, 'right_pane') and len(self.right_pane.panes()) > 0:
                            self.right_pane.sash_place(0, x, y)
                            print(f"Right sash restored: ({x}, {y})")
                    
                    print(f"✓ Layout fully loaded from {layout_file}")
                except Exception as e:
                    print(f"Error restoring sash positions: {e}")
            
            # Schedule sash restoration after widgets are fully rendered
            self.root.after(300, restore_sashes)
            
            # Restore dock states
            for dock_id, state in layout_config.get('docks', {}).items():
                dock = self.docks.get(dock_id)
                if dock:
                    if not state['visible']:
                        dock.close()
                    elif state['minimized']:
                        dock.minimize()
        
        except Exception as e:
            print(f"Failed to load layout: {e}")
