"""Main window for Resource Hacker GUI.

This module provides the main application window with menu bar,
toolbar, and central widget layout.
"""

from __future__ import annotations

import logging
import os
from pathlib import Path

import PySide2
from PySide2.QtCore import QSize, Qt, Signal
from PySide2.QtWidgets import (
    QAction,
    QApplication,
    QFileDialog,
    QHBoxLayout,
    QLabel,
    QMainWindow,
    QMessageBox,
    QSplitter,
    QStatusBar,
    QWidget,
)

from ..models.file_utils import FileUtils
from ..models.resource_manager import ResourceManager
from .config import app_config
from .preview_widget import PreviewWidget
from .resource_view import ResourceTreeView

# Configure Qt platform plugins
qt_dir = Path(PySide2.__file__).parent
plugin_path = str(qt_dir / "plugins" / "platforms")
os.environ["QT_QPA_PLATFORM_PLUGIN_PATH"] = plugin_path

logger = logging.getLogger(__name__)

# UI constants
UI_CONSTANTS = {
    "WINDOW_WIDTH": 1200,
    "WINDOW_HEIGHT": 800,
    "STATUSBAR_HEIGHT": 24,
    "TOOLBAR_HEIGHT": 32,
    "MIN_WINDOW_WIDTH": 800,
    "MIN_WINDOW_HEIGHT": 600,
}


class MainWindow(QMainWindow):
    """Main application window for Resource Hacker."""

    # Signals
    file_loaded = Signal(str)  # Emits file path when file is loaded
    resource_selected = Signal(object)  # Emits resource info when selected

    def __init__(self):
        super().__init__()
        self.resource_manager = ResourceManager()
        self.current_file: Path | None = None
        self.config = app_config

        self._setup_ui()
        self._setup_connections()
        self._setup_menubar()
        self._setup_toolbar()
        self._setup_statusbar()
        self._apply_stylesheet()
        self._restore_window_geometry()

        logger.info("Main window initialized")

    def _setup_ui(self):
        """Initialize the user interface."""
        self.setWindowTitle("Resource Hacker")
        self.setMinimumSize(UI_CONSTANTS["MIN_WINDOW_WIDTH"], UI_CONSTANTS["MIN_WINDOW_HEIGHT"])
        # Window size will be restored in _restore_window_geometry

        # Create central widget
        central_widget = QWidget()
        self.setCentralWidget(central_widget)

        # Create main layout
        main_layout = QHBoxLayout(central_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)
        main_layout.setSpacing(0)

        # Create splitter for resizable panels
        splitter = QSplitter(Qt.Horizontal)
        main_layout.addWidget(splitter)

        # Create resource tree view (left panel)
        self.resource_tree = ResourceTreeView()
        splitter.addWidget(self.resource_tree)

        # Create preview widget (right panel)
        self.preview_widget = PreviewWidget()
        splitter.addWidget(self.preview_widget)

        # Set initial splitter sizes (60% for tree, 40% for preview)
        splitter.setSizes([720, 480])

    def _setup_connections(self):
        """Set up signal-slot connections."""
        # Connect resource tree signals
        self.resource_tree.resource_selected.connect(self._on_resource_selected)
        self.resource_tree.file_loaded.connect(self._on_file_loaded)

        # Connect internal signals
        self.file_loaded.connect(self._update_title)
        self.resource_selected.connect(self.preview_widget.display_resource)

    def _setup_menubar(self):
        """Set up the menu bar."""
        menubar = self.menuBar()

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

        # Open action
        open_action = QAction("&Open...", self)
        open_action.setShortcut("Ctrl+O")
        open_action.setStatusTip("Open a PE file")
        open_action.triggered.connect(self._open_file)
        file_menu.addAction(open_action)

        # Recent files submenu
        self.recent_menu = file_menu.addMenu("Open &Recent")
        self._update_recent_files_menu()

        # Restore window geometry after setting up UI
        self._restore_window_geometry()

        file_menu.addSeparator()

        # Save action
        save_action = QAction("&Save", self)
        save_action.setShortcut("Ctrl+S")
        save_action.setStatusTip("Save changes to current file")
        save_action.triggered.connect(self._save_file)
        save_action.setEnabled(False)
        file_menu.addAction(save_action)

        # Save As action
        save_as_action = QAction("Save &As...", self)
        save_as_action.setShortcut("Ctrl+Shift+S")
        save_as_action.setStatusTip("Save to a different file")
        save_as_action.triggered.connect(self._save_as_file)
        save_as_action.setEnabled(False)
        file_menu.addAction(save_as_action)

        file_menu.addSeparator()

        # Exit action
        exit_action = QAction("E&xit", self)
        exit_action.setShortcut("Ctrl+Q")
        exit_action.setStatusTip("Exit the application")
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)

        # Resources menu
        resources_menu = menubar.addMenu("&Resources")

        # Export selected resource action
        export_selected_action = QAction("&Export Selected Resource...", self)
        export_selected_action.setShortcut("Ctrl+E")
        export_selected_action.setStatusTip("Export the currently selected resource")
        export_selected_action.triggered.connect(self._export_selected_resource)
        export_selected_action.setEnabled(False)
        resources_menu.addAction(export_selected_action)

        # Replace selected resource action
        replace_selected_action = QAction("&Replace Selected Resource...", self)
        replace_selected_action.setShortcut("Ctrl+R")
        replace_selected_action.setStatusTip("Replace the currently selected resource")
        replace_selected_action.triggered.connect(self._replace_selected_resource)
        replace_selected_action.setEnabled(False)
        resources_menu.addAction(replace_selected_action)

        resources_menu.addSeparator()

        # Export all resources action
        export_all_action = QAction("Export &All Resources...", self)
        export_all_action.setStatusTip("Export all resources to a directory")
        export_all_action.triggered.connect(self._export_all_resources)
        resources_menu.addAction(export_all_action)

        # Tools menu
        tools_menu = menubar.addMenu("&Tools")

        # Create ICO from images action
        create_ico_action = QAction("Create &ICO from Images...", self)
        create_ico_action.setStatusTip("Create ICO file from multiple images")
        create_ico_action.triggered.connect(self._create_ico_from_images)
        tools_menu.addAction(create_ico_action)

        # Help menu
        help_menu = menubar.addMenu("&Help")

        # About action
        about_action = QAction("&About", self)
        about_action.setStatusTip("About Resource Hacker")
        about_action.triggered.connect(self._show_about)
        help_menu.addAction(about_action)

    def _setup_toolbar(self):
        """Set up the toolbar."""
        toolbar = self.addToolBar("Main")
        toolbar.setMovable(False)
        toolbar.setFloatable(False)
        toolbar.setIconSize(QSize(UI_CONSTANTS["TOOLBAR_HEIGHT"], UI_CONSTANTS["TOOLBAR_HEIGHT"]))

        # Open action
        open_action = QAction("Open", self)
        open_action.setStatusTip("Open a PE file")
        open_action.triggered.connect(self._open_file)
        toolbar.addAction(open_action)

        toolbar.addSeparator()

        # Export action
        export_action = QAction("Export", self)
        export_action.setStatusTip("Export selected resource")
        export_action.triggered.connect(self._export_selected_resource)
        export_action.setEnabled(False)
        toolbar.addAction(export_action)

        # Import action
        import_action = QAction("Import", self)
        import_action.setStatusTip("Import resource")
        import_action.triggered.connect(self._import_resource)
        import_action.setEnabled(False)
        toolbar.addAction(import_action)

        self.export_action = export_action
        self.import_action = import_action

    def _setup_statusbar(self):
        """Set up the status bar."""
        self.status_bar = QStatusBar()
        self.status_bar.setFixedHeight(UI_CONSTANTS["STATUSBAR_HEIGHT"])
        self.setStatusBar(self.status_bar)

        # Status label
        self.status_label = QLabel("Ready")
        self.status_bar.addWidget(self.status_label)

        # File info label
        self.file_info_label = QLabel("")
        self.status_bar.addPermanentWidget(self.file_info_label)

    def _apply_stylesheet(self):
        """Apply application stylesheet."""
        stylesheet = """
        QMainWindow {
            background-color: #f0f0f0;
            font-family: 'Segoe UI', 'Microsoft YaHei', sans-serif;
            font-size: 10pt;
        }

        QMenuBar {
            background-color: #e8e8e8;
            border-bottom: 1px solid #cccccc;
            padding: 2px;
        }

        QMenuBar::item {
            padding: 4px 8px;
            background: transparent;
        }

        QMenuBar::item:selected {
            background-color: #d0d0d0;
        }

        QToolBar {
            background-color: #f8f8f8;
            border: 1px solid #cccccc;
            padding: 2px;
        }

        QToolBar QToolButton {
            border: 1px solid transparent;
            padding: 4px;
            margin: 1px;
        }

        QToolBar QToolButton:hover {
            background-color: #e0e0e0;
            border: 1px solid #cccccc;
        }

        QStatusBar {
            background-color: #f8f8f8;
            border-top: 1px solid #cccccc;
            font-size: 9pt;
        }

        QTreeWidget {
            background-color: white;
            alternate-background-color: #f8f8f8;
            border: 1px solid #cccccc;
            selection-background-color: #3399ff;
        }

        QTreeWidget::item {
            padding: 2px;
        }

        QTreeWidget::item:selected {
            background-color: #3399ff;
            color: white;
        }

        QLabel#PreviewLabel {
            background-color: white;
            border: 1px solid #cccccc;
            padding: 10px;
            min-height: 200px;
        }
        """
        self.setStyleSheet(stylesheet)

    def _open_file(self):
        """Open a PE file dialog."""
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "Open PE File",
            "",
            "PE Files (*.exe *.dll *.sys *.ocx *.scr *.cpl *.ax *.acm *.drv);;All Files (*.*)",
        )

        if file_path:
            self.load_file(Path(file_path))

    def load_file(self, file_path: Path):
        """Load a PE file."""
        try:
            self.status_label.setText("Loading file...")
            QApplication.processEvents()

            if self.resource_manager.load_pe_file(file_path):
                self.current_file = file_path
                self.resource_tree.load_pe_file(file_path, self.resource_manager)
                FileUtils.add_recent_file(file_path)
                self._update_recent_files_menu()
                self._update_actions()
                self.file_loaded.emit(str(file_path))
                self.status_label.setText("File loaded successfully")
                logger.info(f"Loaded file: {file_path}")
            else:
                QMessageBox.critical(
                    self,
                    "Error",
                    f"Failed to load file: {file_path}\n\nThe file may not be a valid PE file or may be corrupted.",
                )
                self.status_label.setText("Failed to load file")

        except Exception as e:
            QMessageBox.critical(self, "Error", f"An error occurred while loading the file:\n\n{e!s}")
            self.status_label.setText("Error loading file")
            logger.error(f"Error loading file {file_path}: {e}")

    def _save_file(self):
        """Save changes to current file."""
        # Placeholder for save functionality
        QMessageBox.information(
            self,
            "Not Implemented",
            "Save functionality is not yet implemented in this version.",
        )

    def _save_as_file(self):
        """Save to a different file."""
        # Placeholder for save as functionality
        QMessageBox.information(
            self,
            "Not Implemented",
            "Save As functionality is not yet implemented in this version.",
        )

    def _export_selected_resource(self):
        """Export the currently selected resource."""
        if self.resource_tree:
            # Delegate to resource tree's export method
            self.resource_tree._export_resource()
        else:
            QMessageBox.information(
                self,
                "No Selection",
                "Please select a resource to export.",
            )

    def _replace_selected_resource(self):
        """Replace the currently selected resource."""
        if self.resource_tree:
            # Delegate to resource tree's replace method
            self.resource_tree._replace_resource()
        else:
            QMessageBox.information(
                self,
                "No Selection",
                "Please select a resource to replace.",
            )

    def _import_resource(self):
        """Import a resource."""
        # Placeholder for import functionality
        QMessageBox.information(
            self,
            "Not Implemented",
            "Import functionality is not yet implemented in this version.",
        )

    def _export_all_resources(self):
        """Export all resources to a directory."""
        if not self.current_file:
            QMessageBox.warning(self, "No File Loaded", "Please load a PE file first.")
            return

        dir_path = QFileDialog.getExistingDirectory(self, "Select Export Directory")

        if dir_path:
            try:
                self.status_label.setText("Exporting resources...")
                QApplication.processEvents()

                output_dir = Path(dir_path) / f"{self.current_file.stem}_resources"
                successful, total = self.resource_manager.export_all_resources(output_dir)

                QMessageBox.information(
                    self,
                    "Export Complete",
                    f"Exported {successful}/{total} resources to:\n{output_dir}",
                )
                self.status_label.setText("Export completed")

            except Exception as e:
                QMessageBox.critical(self, "Export Error", f"Failed to export resources:\n\n{e!s}")
                self.status_label.setText("Export failed")

    def _create_ico_from_images(self):
        """Create ICO file from multiple images."""
        # Placeholder for ICO creation functionality
        QMessageBox.information(
            self,
            "Not Implemented",
            "ICO creation functionality is not yet implemented in this version.",
        )

    def _show_about(self):
        """Show about dialog."""
        QMessageBox.about(
            self,
            "About Resource Hacker",
            "Resource Hacker v0.1.0\n\n"
            "A Python-based tool for extracting and modifying Windows executable resources.\n\n"
            "Built with:\n"
            "- pefile for PE file parsing\n"
            "- PySide2 for GUI\n"
            "- Pillow for image processing\n\n"
            "This is an open-source project.",
        )

    def _update_recent_files_menu(self):
        """Update the recent files menu."""
        self.recent_menu.clear()
        recent_files = FileUtils.get_recent_files()

        if not recent_files:
            no_files_action = QAction("(No recent files)", self)
            no_files_action.setEnabled(False)
            self.recent_menu.addAction(no_files_action)
            return

        for i, file_path in enumerate(recent_files[:10]):
            action = QAction(f"&{i + 1} {file_path.name}", self)
            action.setStatusTip(str(file_path))
            action.triggered.connect(lambda checked=False, path=file_path: self.load_file(path))
            self.recent_menu.addAction(action)

    def _update_actions(self):
        """Update action states based on current state."""
        has_file = self.current_file is not None
        has_selection = False

        # Check if there's a valid selection
        if self.resource_tree:
            selected_items = self.resource_tree.selectedItems()
            if selected_items:
                item = selected_items[0]
                from .resource_view import ResourceTreeWidgetItem

                if isinstance(item, ResourceTreeWidgetItem):
                    has_selection = True

        # Toolbar actions
        self.export_action.setEnabled(has_file and has_selection)
        self.import_action.setEnabled(has_file and has_selection)

        # Menu actions
        for action in self.menuBar().actions():
            if action.text() == "&Resources":
                resources_menu = action.menu()
                if resources_menu:
                    for menu_action in resources_menu.actions():
                        if "Selected" in menu_action.text():
                            menu_action.setEnabled(has_file and has_selection)
                break

    def _on_file_loaded(self, file_path: str):
        """Handle file loaded signal."""
        self.file_info_label.setText(f"File: {Path(file_path).name}")

    def _on_resource_selected(self, resource_info: dict):
        """Handle resource selected signal."""
        self.resource_selected.emit(resource_info)
        self.status_label.setText(
            f"Selected: {resource_info.get('type_name', 'Unknown')} [{resource_info.get('name_id', 'N/A')}]"
        )
        # Update action states when selection changes
        self._update_actions()

    def _update_title(self, file_path: str):
        """Update window title with loaded file."""
        file_name = Path(file_path).name
        self.setWindowTitle(f"Resource Hacker - {file_name}")

    def _restore_window_geometry(self) -> None:
        """Restore window geometry from configuration."""
        if self.config.window_x is not None and self.config.window_y is not None:
            self.move(self.config.window_x, self.config.window_y)
        self.resize(self.config.window_width, self.config.window_height)

    def _save_window_geometry(self) -> None:
        """Save current window geometry to configuration."""
        geometry = self.geometry()
        self.config.window_x = geometry.x()
        self.config.window_y = geometry.y()
        self.config.window_width = geometry.width()
        self.config.window_height = geometry.height()

    def closeEvent(self, event):
        """Handle window close event."""
        self._save_window_geometry()
        self.resource_manager.close()
        event.accept()
        logger.info("Application closed")
