"""
Alignment operations mixin for pyPhotoAlbum
"""

from pyPhotoAlbum.decorators import ribbon_action
from pyPhotoAlbum.alignment import AlignmentManager
from pyPhotoAlbum.commands import AlignElementsCommand, ResizeElementsCommand


class AlignmentOperationsMixin:
    """Mixin providing element alignment operations"""

    def _get_selected_elements_list(self):
        """Get list of selected elements for alignment operations"""
        return list(self.gl_widget.selected_elements) if self.gl_widget.selected_elements else []

    def _execute_alignment(self, alignment_func, status_msg: str):
        """
        Execute an alignment operation with common boilerplate.

        Args:
            alignment_func: AlignmentManager method to call with elements
            status_msg: Status message format string (will receive element count)
        """
        elements = self._get_selected_elements_list()
        if not self.require_selection(min_count=2):  # type: ignore[attr-defined]
            return

        changes = alignment_func(elements)
        if changes:
            cmd = AlignElementsCommand(changes)
            self.project.history.execute(cmd)  # type: ignore[attr-defined]
            self.update_view()  # type: ignore[attr-defined]
            self.show_status(status_msg.format(len(elements)), 2000)  # type: ignore[attr-defined]

    @ribbon_action(
        label="Align Left",
        tooltip="Align selected elements to the left",
        tab="Arrange",
        group="Align",
        requires_selection=True,
        min_selection=2,
    )
    def align_left(self):
        """Align selected elements to the left"""
        self._execute_alignment(AlignmentManager.align_left, "Aligned {} elements to left")

    @ribbon_action(
        label="Align Right",
        tooltip="Align selected elements to the right",
        tab="Arrange",
        group="Align",
        requires_selection=True,
        min_selection=2,
    )
    def align_right(self):
        """Align selected elements to the right"""
        self._execute_alignment(AlignmentManager.align_right, "Aligned {} elements to right")

    @ribbon_action(
        label="Align Top",
        tooltip="Align selected elements to the top",
        tab="Arrange",
        group="Align",
        requires_selection=True,
        min_selection=2,
    )
    def align_top(self):
        """Align selected elements to the top"""
        self._execute_alignment(AlignmentManager.align_top, "Aligned {} elements to top")

    @ribbon_action(
        label="Align Bottom",
        tooltip="Align selected elements to the bottom",
        tab="Arrange",
        group="Align",
        requires_selection=True,
        min_selection=2,
    )
    def align_bottom(self):
        """Align selected elements to the bottom"""
        self._execute_alignment(AlignmentManager.align_bottom, "Aligned {} elements to bottom")

    @ribbon_action(
        label="Align H-Center",
        tooltip="Align selected elements to horizontal center",
        tab="Arrange",
        group="Align",
        requires_selection=True,
        min_selection=2,
    )
    def align_horizontal_center(self):
        """Align selected elements to horizontal center"""
        self._execute_alignment(AlignmentManager.align_horizontal_center, "Aligned {} elements to horizontal center")

    @ribbon_action(
        label="Align V-Center",
        tooltip="Align selected elements to vertical center",
        tab="Arrange",
        group="Align",
        requires_selection=True,
        min_selection=2,
    )
    def align_vertical_center(self):
        """Align selected elements to vertical center"""
        self._execute_alignment(AlignmentManager.align_vertical_center, "Aligned {} elements to vertical center")

    @ribbon_action(
        label="Maximize Pattern",
        tooltip="Maximize selected elements using crystal growth algorithm",
        tab="Arrange",
        group="Size",
        requires_selection=True,
        min_selection=1,
    )
    def maximize_pattern(self):
        """Maximize selected elements until they are close to borders or each other"""
        elements = self._get_selected_elements_list()
        if not self.require_selection(min_count=1):
            return

        # Get page size from current page
        page = self.get_current_page()
        if not page:
            self.show_warning("No Page", "Please create a page first.")
            return

        page_size = page.layout.size

        changes = AlignmentManager.maximize_pattern(elements, page_size)
        if changes:
            cmd = ResizeElementsCommand(changes)
            self.project.history.execute(cmd)
            self.update_view()
            self.show_status(f"Maximized {len(elements)} element(s) using pattern growth", 2000)
