"""Main application window."""

from __future__ import annotations

from typing import TYPE_CHECKING

from PySide2.QtGui import QCloseEvent
from PySide2.QtWidgets import QAction, QFileDialog, QMainWindow, QMessageBox, QStackedWidget, QStatusBar

from pytola_sim.lscsim.utils.logger import get_logger

from .components import AnalysisView, DatabaseViews, FileModelView, ModelingView, SettingsView

if TYPE_CHECKING:
    from pytola_sim.lscsim.core.main_controller import MainController

logger = get_logger(__name__)


class MainWindow(QMainWindow):
    """Main application window - equivalent to C++ MainWindow."""

    def __init__(self, controller: MainController) -> None:
        super().__init__()
        self.controller = controller
        self._setup_ui()
        self._setup_connections()
        logger.info("Main window initialized")

    def _setup_connections(self) -> None:
        pass

    def _setup_ui(self) -> None:
        """Initialize user interface."""
        self.setWindowTitle("LSCSIM - Simulation System")
        self.setMinimumSize(1200, 800)
        self.resize(1400, 900)

        # Create menu bar
        self._create_menu_bar()

        # Create toolbars
        self._create_toolbars()

        # Create central widget
        self._create_central_widget()

        # Create status bar
        self._create_status_bar()

        # Apply stylesheet
        self._apply_stylesheet()

    def _create_menu_bar(self) -> None:
        """Create application menu bar."""
        menubar = self.menuBar()

        # File menu
        file_menu = menubar.addMenu("&File")

        new_action = QAction("&New Project", self)
        new_action.setShortcut("Ctrl+N")
        new_action.triggered.connect(self._new_project)
        file_menu.addAction(new_action)

        open_action = QAction("&Open Project", self)
        open_action.setShortcut("Ctrl+O")
        open_action.triggered.connect(self._open_project)
        file_menu.addAction(open_action)

        file_menu.addSeparator()

        save_action = QAction("&Save Project", self)
        save_action.setShortcut("Ctrl+S")
        save_action.triggered.connect(self._save_project)
        file_menu.addAction(save_action)

        save_as_action = QAction("Save Project &As", self)
        save_as_action.setShortcut("Ctrl+Shift+S")
        save_as_action.triggered.connect(self._save_project_as)
        file_menu.addAction(save_as_action)

        file_menu.addSeparator()

        exit_action = QAction("E&xit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)

        # View menu
        menubar.addMenu("&View")

        # Help menu
        help_menu = menubar.addMenu("&Help")
        about_action = QAction("&About", self)
        about_action.triggered.connect(self._show_about)
        help_menu.addAction(about_action)

    def _create_toolbars(self) -> None:
        """Create application toolbars."""
        # Main toolbar
        toolbar = self.addToolBar("Main")
        toolbar.setMovable(False)

        # Add actions to toolbar
        new_action = QAction("New", self)
        new_action.setToolTip("New Project")
        toolbar.addAction(new_action)

        open_action = QAction("Open", self)
        open_action.setToolTip("Open Project")
        toolbar.addAction(open_action)

        save_action = QAction("Save", self)
        save_action.setToolTip("Save Project")
        toolbar.addAction(save_action)

    def _create_central_widget(self) -> None:
        """Create central stacked widget for different views."""
        self.central_stacked = QStackedWidget()
        self.setCentralWidget(self.central_stacked)

        # Add different functional views
        try:
            self.file_view = FileModelView(self.controller)
            self.modeling_view = ModelingView(self.controller)
            self.analysis_view = AnalysisView(self.controller)
            self.database_views = DatabaseViews(self.controller)
            self.settings_view = SettingsView(self.controller)

            self.central_stacked.addWidget(self.file_view)
            self.central_stacked.addWidget(self.modeling_view)
            self.central_stacked.addWidget(self.analysis_view)
            self.central_stacked.addWidget(self.database_views)
            self.central_stacked.addWidget(self.settings_view)

            # Show file view by default
            self.central_stacked.setCurrentWidget(self.file_view)
        except Exception:
            logger.exception("Failed to create views")
            # Create placeholder if views fail
            from PySide2.QtWidgets import QLabel, QVBoxLayout, QWidget

            placeholder = QWidget()
            layout = QVBoxLayout(placeholder)
            layout.addWidget(QLabel("Loading views..."))
            self.central_stacked.addWidget(placeholder)

    def _create_status_bar(self) -> None:
        """Create status bar."""
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        self.status_bar.showMessage("Ready")

        # Connect to controller signals
        self.controller.status_message_changed.connect(self._update_status_message)

    def _apply_stylesheet(self) -> None:
        """Apply application stylesheet."""
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f0f0f0;
            }
            QMenuBar {
                background-color: #e8e8e8;
                border-bottom: 1px solid #cccccc;
            }
            QMenuBar::item {
                padding: 4px 8px;
                background: transparent;
            }
            QMenuBar::item:selected {
                background: #d0d0d0;
            }
            QToolBar {
                background-color: #f8f8f8;
                border: 1px solid #cccccc;
            }
            QStatusBar {
                background-color: #e8e8e8;
            }
        """)

    def _new_project(self) -> None:
        """Create new project."""
        logger.info("Creating new project")
        self.controller.set_status_message("Creating new project...")
        # Implementation will be added later

    def _open_project(self) -> None:
        """Open existing project."""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "Open Project",
            "",
            "LSCSIM Files (*.lscsim)",
        )
        if file_path:
            logger.info(f"Opening project: {file_path}")
            self.controller.set_status_message(f"Opening project: {file_path}")
            # Implementation will be added later

    def _save_project(self) -> None:
        """Save current project."""
        logger.info("Saving project")
        self.controller.set_status_message("Saving project...")
        # Implementation will be added later

    def _save_project_as(self) -> None:
        """Save project with new name."""
        file_path, _ = QFileDialog.getSaveFileName(
            self,
            "Save Project As",
            "",
            "LSCSIM Files (*.lscsim)",
        )
        if file_path:
            logger.info(f"Saving project as: {file_path}")
            self.controller.set_status_message(f"Saving project as: {file_path}")
            # Implementation will be added later

    def _update_status_message(self, message: str) -> None:
        """Update status bar message."""
        self.status_bar.showMessage(message)

    def _show_about(self) -> None:
        """Show about dialog."""
        QMessageBox.about(
            self,
            "About LSCSIM",
            "LSCSIM - Python-based Simulation System\nVersion 0.1.0\n\n"
            "A modern simulation system built with Python and PySide2.",
        )

    def closeEvent(self, event: QCloseEvent) -> None:
        """Handle window close event."""
        reply = QMessageBox.question(
            self,
            "Confirm Exit",
            "Are you sure you want to exit?\nAny unsaved changes will be lost.",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No,
        )

        if reply == QMessageBox.Yes:
            logger.info("Application closing")
            event.accept()
        else:
            event.ignore()
