"""
Mixin for automatic undo/redo handling in interactive mouse operations
"""

from typing import Optional
from pyPhotoAlbum.models import BaseLayoutElement
from .interaction_command_factory import InteractionCommandFactory, InteractionState


class UndoableInteractionMixin:
    """
    Mixin providing automatic undo/redo for interactive mouse operations.

    This mixin tracks the state of elements before interactive operations
    (move, resize, rotate) and automatically creates appropriate Command
    objects when the interaction completes.
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # Command factory for creating undo/redo commands
        self._command_factory = InteractionCommandFactory()

        # Interaction state tracking
        self._interaction_state = InteractionState()

    def _begin_move(self, element: BaseLayoutElement):
        """
        Begin tracking a move operation.

        Args:
            element: The element being moved
        """
        self._interaction_state.element = element
        self._interaction_state.interaction_type = "move"
        self._interaction_state.position = element.position

    def _begin_resize(self, element: BaseLayoutElement):
        """
        Begin tracking a resize operation.

        Args:
            element: The element being resized
        """
        self._interaction_state.element = element
        self._interaction_state.interaction_type = "resize"
        self._interaction_state.position = element.position
        self._interaction_state.size = element.size

    def _begin_rotate(self, element: BaseLayoutElement):
        """
        Begin tracking a rotate operation.

        Args:
            element: The element being rotated
        """
        self._interaction_state.element = element
        self._interaction_state.interaction_type = "rotate"
        self._interaction_state.rotation = element.rotation

    def _begin_image_pan(self, element):
        """
        Begin tracking an image pan operation.

        Args:
            element: The ImageData element being panned
        """
        from pyPhotoAlbum.models import ImageData

        if not isinstance(element, ImageData):
            return

        self._interaction_state.element = element
        self._interaction_state.interaction_type = "image_pan"
        self._interaction_state.crop_info = element.crop_info

    def _end_interaction(self):
        """
        End the current interaction and create appropriate undo/redo command.

        This method uses the command factory to create the appropriate
        Command object based on what changed during the interaction.
        """
        # Validate interaction state
        if not self._interaction_state.is_valid():
            self._clear_interaction_state()
            return

        # Get main window to access project history
        main_window = self.window()
        if not hasattr(main_window, "project"):
            self._clear_interaction_state()
            return

        # Use factory to create command based on interaction type and changes
        command = self._command_factory.create_command(
            interaction_type=self._interaction_state.interaction_type,
            element=self._interaction_state.element,
            start_state=self._interaction_state.to_dict(),
        )

        # Execute the command through history if one was created
        if command:
            main_window.project.history.execute(command)

        # Clear interaction state
        self._clear_interaction_state()

    def _clear_interaction_state(self):
        """Clear all interaction tracking state"""
        self._interaction_state.clear()

    def _cancel_interaction(self):
        """Cancel the current interaction without creating a command"""
        self._clear_interaction_state()
