from PySide6.QtCore import QRect, Qt
from PySide6.QtWidgets import QWidget, QApplication
from typing import Dict
import sys
from qt_material import apply_stylesheet
from acycle.plot.plotConfig import plotConfig
from acycle.plot.TxtEditor import TxtEditor
from acycle.plot.MplWidget import MplWidget
from acycle.window.WindowDivider import WindowDivider

class PlotPro(QWidget):
    def __init__(self, parent=None, spacing: int = 10, theme: str = 'default.xml', file_path: str = None):
        super().__init__(parent)
        self.spacing = spacing
        self.theme = theme
        self.files = file_path if isinstance(file_path, list) else [file_path] if file_path else []
        self.current_file_path = self.files[0] if self.files else ""
        self.windows: Dict[str, QWidget] = {}
        
    def setup_3_pane_layout(self):
        screen_geometry = self.screen().availableGeometry()
        
        # Use WindowDivider to calculate layout
        divider = WindowDivider(screen_geometry, spacing=self.spacing)
        
        # Left panel (50%)
        left_rect = divider.get_subrect(1, 2, 1)  # 1 row, 2 columns, 1st area
        
        # Right panel (50%), divided into top and bottom
        right_top_rect = divider.get_subrect(2, 2, 2)  # 2 rows, 1 column, 1st area
        right_bottom_rect = divider.get_subrect(2, 2, 4)  # 2 rows, 1 column, 2nd area
        
        window_rects = {
            "left": left_rect,
            "right_top": right_top_rect,
            "right_bottom": right_bottom_rect
        }
        
        # Clear existing windows
        self._close_all_windows()
        
        # Create new windows
        self._create_windows(window_rects)
    
    def _create_windows(self, window_rects: Dict[str, QRect]):
        # Window creation configuration
        window_configs = {
            "left": {
                "title": "Plot Configuration",
                "creator": self._create_left_panel,
                "args": {"parent_win": self, "files": self.files}
            },
            "right_top": {
                "title": self.current_file_path,
                "creator": self._create_right_top_panel,
                "args": {"file_path": self.current_file_path}
            },
            "right_bottom": {
                "title": self.current_file_path,
                "creator": self._create_right_bottom_panel,
                "args": {"file_path": self.current_file_path}
            }
        }
        
        for pos, geom in window_rects.items():
            config = window_configs[pos]
            self.windows[pos] = config["creator"](**config["args"])
            self._configure_window(self.windows[pos], geom, config["title"])
            self.windows[pos].destroyed.connect(lambda _, p=pos: self._on_window_closed(p))
        
        # Connect configuration change signal
        if "left" in self.windows and "right_bottom" in self.windows:
            self.windows["left"].plot_config_changed.connect(
                self.windows["right_bottom"].update_plot_config
            )
    
    def _create_left_panel(self, **kwargs) -> QWidget:
        """Create left panel"""
        self.pltCfg = plotConfig(**kwargs)  # Use the new PlotConfig class
        return self.pltCfg  # Use the new PlotConfig class
    
    def _create_right_top_panel(self, **kwargs) -> QWidget:
        """Create right top panel"""
        return TxtEditor(file_path=kwargs.get("file_path", ""))
    
    def _create_right_bottom_panel(self, **kwargs) -> QWidget:
        """Create right bottom panel"""
        mlp = MplWidget(**kwargs)
        mlp.update_plot_config(config = self.pltCfg.plot_config)
        return mlp
    
    def _configure_window(self, window: QWidget, geometry: QRect, title: str = ""):
        """Configure common window properties"""
        if hasattr(window, 'setGeometry'):
            window.setGeometry(geometry)
        if title and hasattr(window, 'setWindowTitle'):
            window.setWindowTitle(title)
        
        apply_stylesheet(window, theme=self.theme)
        
        if hasattr(window, 'show'):
            window.show()
        if hasattr(window, 'raise_'):
            window.raise_()
    
    def _on_window_closed(self, position: str):
        """Window close event handler"""
        if position in self.windows:
            del self.windows[position]
    
    def _close_all_windows(self):
        """Close all managed windows"""
        for window in self.windows.values():
            if hasattr(window, 'close'):
                window.close()
        self.windows.clear()
    
    def set_file_path(self, file_path: str):
        """Set current file path"""
        self.current_file_path = file_path
        if "right_top" in self.windows and hasattr(self.windows["right_top"], 'set_file_path'):
            self.windows["right_top"].set_file_path(file_path)
        if "right_bottom" in self.windows and hasattr(self.windows["right_bottom"],'set_file_path'):
            self.windows["right_bottom"].set_file_path(file_path)
    
    def set_theme(self, theme: str):
        """Set theme and apply to all windows"""
        self.theme = theme
        for window in self.windows.values():
            apply_stylesheet(window, theme=theme)
            
if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # Create window manager
    manager = PlotPro(
        spacing=30, 
        theme='default.xml',
        file_path=''
    )
    
    # Set up 3-pane layout (right side split 60/40)
    manager.setup_3_pane_layout()
    
    sys.exit(app.exec())