"""
Gesture event types for touch input.

This module defines touch gestures that can be received from a HAL (Hardware Abstraction Layer)
or touch input system, and the response format for actions to be performed.
"""

from __future__ import annotations
from enum import Enum
from dataclasses import dataclass
from typing import Optional, Dict, Any


class GestureType(Enum):
    """Touch gesture types from HAL"""
    TAP = "tap"                      # Single finger tap
    LONG_PRESS = "long_press"        # Hold for 500ms+
    SWIPE_LEFT = "swipe_left"        # Swipe left (page forward)
    SWIPE_RIGHT = "swipe_right"      # Swipe right (page back)
    SWIPE_UP = "swipe_up"            # Swipe up (scroll down)
    SWIPE_DOWN = "swipe_down"        # Swipe down (scroll up)
    PINCH_IN = "pinch_in"            # Pinch fingers together (zoom out)
    PINCH_OUT = "pinch_out"          # Spread fingers apart (zoom in)
    DRAG_START = "drag_start"        # Start dragging/selection
    DRAG_MOVE = "drag_move"          # Continue dragging
    DRAG_END = "drag_end"            # End dragging/selection


@dataclass
class TouchEvent:
    """
    Touch event from HAL.

    Represents a single touch gesture with its coordinates and metadata.
    """
    gesture: GestureType
    x: int  # Primary touch point X coordinate
    y: int  # Primary touch point Y coordinate
    x2: Optional[int] = None  # Secondary point X (for pinch/drag)
    y2: Optional[int] = None  # Secondary point Y (for pinch/drag)
    timestamp_ms: float = 0   # Timestamp in milliseconds

    @classmethod
    def from_hal(cls, hal_data: dict) -> 'TouchEvent':
        """
        Parse a touch event from HAL format.

        Args:
            hal_data: Dictionary with gesture data from HAL
                Expected keys: 'gesture', 'x', 'y', optionally 'x2', 'y2', 'timestamp'

        Returns:
            TouchEvent instance

        Example:
            >>> event = TouchEvent.from_hal({
            ...     'gesture': 'tap',
            ...     'x': 450,
            ...     'y': 320
            ... })
        """
        return cls(
            gesture=GestureType(hal_data['gesture']),
            x=hal_data['x'],
            y=hal_data['y'],
            x2=hal_data.get('x2'),
            y2=hal_data.get('y2'),
            timestamp_ms=hal_data.get('timestamp', 0)
        )

    def to_dict(self) -> dict:
        """Convert to dictionary for serialization"""
        return {
            'gesture': self.gesture.value,
            'x': self.x,
            'y': self.y,
            'x2': self.x2,
            'y2': self.y2,
            'timestamp_ms': self.timestamp_ms
        }


@dataclass
class GestureResponse:
    """
    Response from handling a gesture.

    This encapsulates the action that should be performed by the UI
    in response to a gesture, keeping all business logic in the library.
    """
    action: str  # Action type: "navigate", "define", "select", "zoom", "page_turn", "none", etc.
    data: Dict[str, Any]  # Action-specific data

    def to_dict(self) -> dict:
        """
        Convert to dictionary for Flask JSON response.

        Returns:
            Dictionary with action and data
        """
        return {
            'action': self.action,
            'data': self.data
        }


# Action type constants for clarity
class ActionType:
    """Constants for gesture response action types"""
    NONE = "none"
    PAGE_TURN = "page_turn"
    NAVIGATE = "navigate"
    DEFINE = "define"
    SELECT = "select"
    ZOOM = "zoom"
    BOOK_LOADED = "book_loaded"
    WORD_SELECTED = "word_selected"
    SHOW_MENU = "show_menu"
    SELECTION_START = "selection_start"
    SELECTION_UPDATE = "selection_update"
    SELECTION_COMPLETE = "selection_complete"
    AT_START = "at_start"
    AT_END = "at_end"
    ERROR = "error"
    OVERLAY_OPENED = "overlay_opened"
    OVERLAY_CLOSED = "overlay_closed"
    CHAPTER_SELECTED = "chapter_selected"
    BOOKMARK_SELECTED = "bookmark_selected"
    TAB_SWITCHED = "tab_switched"
    SETTING_CHANGED = "setting_changed"
    BACK_TO_LIBRARY = "back_to_library"
