"""
View operations mixin for pyPhotoAlbum
"""

from pyPhotoAlbum.decorators import ribbon_action
from pyPhotoAlbum.dialogs import PrintSettingsDialog


class ViewOperationsMixin:
    """Mixin providing view-related operations"""

    @ribbon_action(label="Zoom In", tooltip="Zoom in", tab="View", group="Zoom", shortcut="Ctrl++")
    def zoom_in(self):
        """Zoom in"""
        self.gl_widget.zoom_level *= 1.2
        if self.gl_widget.zoom_level > 5.0:
            self.gl_widget.zoom_level = 5.0
        self.update_view()
        self.show_status(f"Zoom: {int(self.gl_widget.zoom_level * 100)}%", 2000)

    @ribbon_action(label="Zoom Out", tooltip="Zoom out", tab="View", group="Zoom", shortcut="Ctrl+-")
    def zoom_out(self):
        """Zoom out"""
        self.gl_widget.zoom_level /= 1.2
        if self.gl_widget.zoom_level < 0.1:
            self.gl_widget.zoom_level = 0.1
        self.update_view()
        self.show_status(f"Zoom: {int(self.gl_widget.zoom_level * 100)}%", 2000)

    @ribbon_action(label="Fit to Window", tooltip="Fit page to window", tab="View", group="Zoom", shortcut="Ctrl+0")
    def zoom_fit(self):
        """Fit page to window"""
        if not self.project.pages:
            return

        current_page = self.project.pages[self.gl_widget.current_page_index]
        page_width_mm = current_page.layout.size[0]
        page_height_mm = current_page.layout.size[1]

        # Convert to pixels
        dpi = self.project.working_dpi
        page_width_px = page_width_mm * dpi / 25.4
        page_height_px = page_height_mm * dpi / 25.4

        # Get widget size
        widget_width = self.gl_widget.width() - 100  # Margins
        widget_height = self.gl_widget.height() - 100

        # Calculate zoom to fit
        zoom_w = widget_width / page_width_px
        zoom_h = widget_height / page_height_px

        self.gl_widget.zoom_level = min(zoom_w, zoom_h)
        self.gl_widget.zoom_level = max(0.1, min(5.0, self.gl_widget.zoom_level))
        self.update_view()
        self.show_status(f"Zoom: {int(self.gl_widget.zoom_level * 100)}%", 2000)

    @ribbon_action(
        label="Grid Snap",
        tooltip="Enable/disable snapping to grid (Ctrl+G)",
        tab="Insert",
        group="Snapping",
        shortcut="Ctrl+G",
    )
    def toggle_grid_snap(self):
        """Toggle grid snapping"""
        if not self.project:
            return

        self.project.snap_to_grid = not self.project.snap_to_grid

        status = "enabled" if self.project.snap_to_grid else "disabled"
        self.update_view()
        self.show_status(f"Grid snapping {status}", 2000)
        print(f"Grid snapping {status}")

    @ribbon_action(
        label="Edge Snap",
        tooltip="Enable/disable snapping to page edges (Ctrl+E)",
        tab="Insert",
        group="Snapping",
        shortcut="Ctrl+E",
    )
    def toggle_edge_snap(self):
        """Toggle edge snapping"""
        if not self.project:
            return

        self.project.snap_to_edges = not self.project.snap_to_edges

        status = "enabled" if self.project.snap_to_edges else "disabled"
        self.update_view()
        self.show_status(f"Edge snapping {status}", 2000)
        print(f"Edge snapping {status}")

    @ribbon_action(label="Guide Snap", tooltip="Enable/disable snapping to guides", tab="Insert", group="Snapping")
    def toggle_guide_snap(self):
        """Toggle guide snapping"""
        if not self.project:
            return

        self.project.snap_to_guides = not self.project.snap_to_guides

        status = "enabled" if self.project.snap_to_guides else "disabled"
        self.update_view()
        self.show_status(f"Guide snapping {status}", 2000)
        print(f"Guide snapping {status}")

    @ribbon_action(label="Show Grid", tooltip="Toggle visibility of grid lines", tab="Insert", group="Snapping")
    def toggle_show_grid(self):
        """Toggle grid visibility"""
        if not self.project:
            return

        self.project.show_grid = not self.project.show_grid

        status = "visible" if self.project.show_grid else "hidden"
        self.update_view()
        self.show_status(f"Grid {status}", 2000)
        print(f"Grid {status}")

    @ribbon_action(
        label="Print Settings...", tooltip="Configure bleed and safe area for all pages", tab="View", group="Guides"
    )
    def open_print_settings(self):
        """Open the print settings dialog (bleed and safe area)"""
        if not self.project:
            return

        dialog = PrintSettingsDialog(self, self.project)
        if dialog.exec():
            values = dialog.get_values()
            self.project.page_bleed_mm = values["page_bleed_mm"]
            self.project.page_safe_area_mm = values["page_safe_area_mm"]
            self.update_view()
            self.show_status(
                f"Bleed: {values['page_bleed_mm']:.1f}mm, Safe area: {values['page_safe_area_mm']:.1f}mm", 2000
            )

    @ribbon_action(
        label="Print Guides", tooltip="Toggle bleed/cut/safe-area guide lines in the editor", tab="View", group="Guides"
    )
    def toggle_print_guides(self):
        """Toggle print guide lines (bleed/cut/safe area)"""
        if not self.project:
            return

        self.project.show_print_guides = not self.project.show_print_guides

        status = "visible" if self.project.show_print_guides else "hidden"
        self.update_view()
        self.show_status(f"Print guides {status}", 2000)

    @ribbon_action(label="Show Guides", tooltip="Toggle visibility of guide lines", tab="Insert", group="Snapping")
    def toggle_snap_lines(self):
        """Toggle guide lines visibility"""
        if not self.project:
            return

        self.project.show_snap_lines = not self.project.show_snap_lines

        status = "visible" if self.project.show_snap_lines else "hidden"
        self.update_view()
        self.show_status(f"Guides {status}", 2000)
        print(f"Guides {status}")

    @ribbon_action(label="Add H Guide", tooltip="Add horizontal guide at page center", tab="View", group="Guides")
    def add_horizontal_guide(self):
        """Add a horizontal guide at page center"""
        current_page = self.get_current_page()
        if not current_page:
            return

        # Add guide at vertical center (in mm)
        center_y = current_page.layout.size[1] / 2.0
        current_page.layout.snapping_system.add_guide(center_y, "horizontal")

        self.update_view()
        self.show_status(f"Added horizontal guide at {center_y:.1f} mm", 2000)
        print(f"Added horizontal guide at {center_y:.1f} mm")

    @ribbon_action(label="Add V Guide", tooltip="Add vertical guide at page center", tab="View", group="Guides")
    def add_vertical_guide(self):
        """Add a vertical guide at page center"""
        current_page = self.get_current_page()
        if not current_page:
            return

        # Add guide at horizontal center (in mm)
        center_x = current_page.layout.size[0] / 2.0
        current_page.layout.snapping_system.add_guide(center_x, "vertical")

        self.update_view()
        self.show_status(f"Added vertical guide at {center_x:.1f} mm", 2000)
        print(f"Added vertical guide at {center_x:.1f} mm")

    @ribbon_action(label="Clear Guides", tooltip="Clear all guides from current page", tab="View", group="Guides")
    def clear_guides(self):
        """Clear all guides from current page"""
        current_page = self.get_current_page()
        if not current_page:
            return

        guide_count = len(current_page.layout.snapping_system.guides)
        current_page.layout.snapping_system.clear_guides()

        self.update_view()
        self.show_status(f"Cleared {guide_count} guides", 2000)
        print(f"Cleared {guide_count} guides")

    @ribbon_action(
        label="Image Browser",
        tooltip="Show/hide the image browser panel",
        tab="View",
        group="Panels",
        shortcut="Ctrl+B",
    )
    def toggle_image_browser(self):
        """Toggle the thumbnail browser visibility"""
        if hasattr(self, "_thumbnail_browser"):
            if self._thumbnail_browser.isVisible():
                self._thumbnail_browser.hide()
                self.show_status("Image browser hidden", 2000)
            else:
                self._thumbnail_browser.show()
                self.show_status("Image browser shown", 2000)

    @ribbon_action(
        label="Grid Settings...", tooltip="Configure grid size and snap threshold", tab="Insert", group="Snapping"
    )
    def set_grid_size(self):
        """Open dialog to set grid size"""
        from PyQt6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel, QDoubleSpinBox, QPushButton

        if not self.project:
            return

        # Create dialog
        dialog = QDialog(self)
        dialog.setWindowTitle("Grid Settings")
        dialog.setMinimumWidth(300)

        layout = QVBoxLayout()

        # Grid size setting
        size_layout = QHBoxLayout()
        size_layout.addWidget(QLabel("Grid Size:"))

        size_spinbox = QDoubleSpinBox()
        size_spinbox.setRange(1.0, 100.0)
        size_spinbox.setValue(self.project.grid_size_mm)
        size_spinbox.setSuffix(" mm")
        size_spinbox.setDecimals(1)
        size_spinbox.setSingleStep(1.0)
        size_layout.addWidget(size_spinbox)

        layout.addLayout(size_layout)

        # Snap threshold setting
        threshold_layout = QHBoxLayout()
        threshold_layout.addWidget(QLabel("Snap Threshold:"))

        threshold_spinbox = QDoubleSpinBox()
        threshold_spinbox.setRange(0.5, 20.0)
        threshold_spinbox.setValue(self.project.snap_threshold_mm)
        threshold_spinbox.setSuffix(" mm")
        threshold_spinbox.setDecimals(1)
        threshold_spinbox.setSingleStep(0.5)
        threshold_layout.addWidget(threshold_spinbox)

        layout.addLayout(threshold_layout)

        # Buttons
        button_layout = QHBoxLayout()
        cancel_btn = QPushButton("Cancel")
        cancel_btn.clicked.connect(dialog.reject)
        ok_btn = QPushButton("OK")
        ok_btn.clicked.connect(dialog.accept)
        ok_btn.setDefault(True)

        button_layout.addStretch()
        button_layout.addWidget(cancel_btn)
        button_layout.addWidget(ok_btn)
        layout.addLayout(button_layout)

        dialog.setLayout(layout)

        # Show dialog and apply if accepted
        if dialog.exec() == QDialog.DialogCode.Accepted:
            new_grid_size = size_spinbox.value()
            new_threshold = threshold_spinbox.value()

            self.project.grid_size_mm = new_grid_size
            self.project.snap_threshold_mm = new_threshold

            self.update_view()
            self.show_status(f"Grid size: {new_grid_size:.1f}mm, Threshold: {new_threshold:.1f}mm", 2000)
            print(f"Updated grid settings - Size: {new_grid_size:.1f}mm, Threshold: {new_threshold:.1f}mm")
