"""
Gesture routing and handling.

This module handles all touch event routing and gesture logic.
"""

from __future__ import annotations
from typing import TYPE_CHECKING, Optional, Tuple

from ..gesture import TouchEvent, GestureType, GestureResponse, ActionType

if TYPE_CHECKING:
    from ..application import EbookReader
    from pyWebLayout.core.query import SelectionRange


class GestureRouter:
    """
    Routes and handles all gestures.

    This class centralizes all gesture handling logic, making it easier
    to test and maintain gesture interactions.
    """

    def __init__(self, reader: 'EbookReader'):
        """
        Initialize the gesture router.

        Args:
            reader: EbookReader instance to route gestures for
        """
        self.reader = reader

        # Selection state (for text selection gestures)
        self._selection_start: Optional[Tuple[int, int]] = None
        self._selection_end: Optional[Tuple[int, int]] = None
        self._selected_range: Optional['SelectionRange'] = None

    def handle_touch(self, event: TouchEvent) -> GestureResponse:
        """
        Handle a touch event from HAL.

        This is the main entry point for all touch interactions.

        Args:
            event: TouchEvent from HAL with gesture type and coordinates

        Returns:
            GestureResponse with action and data for UI to process
        """
        if not self.reader.is_loaded():
            return GestureResponse(ActionType.ERROR, {"message": "No book loaded"})

        # Handle overlay-specific gestures first
        if self.reader.is_overlay_open():
            if event.gesture == GestureType.TAP:
                return self._handle_overlay_tap(event.x, event.y)
            elif event.gesture == GestureType.SWIPE_DOWN:
                return self._handle_overlay_close()

        # Dispatch based on gesture type for normal reading mode
        if event.gesture == GestureType.TAP:
            return self._handle_tap(event.x, event.y)
        elif event.gesture == GestureType.LONG_PRESS:
            return self._handle_long_press(event.x, event.y)
        elif event.gesture == GestureType.SWIPE_LEFT:
            return self._handle_page_forward()
        elif event.gesture == GestureType.SWIPE_RIGHT:
            return self._handle_page_back()
        elif event.gesture == GestureType.SWIPE_UP:
            return self._handle_swipe_up(event.y)
        elif event.gesture == GestureType.SWIPE_DOWN:
            return self._handle_swipe_down(event.y)
        elif event.gesture == GestureType.PINCH_IN:
            return self._handle_zoom_out()
        elif event.gesture == GestureType.PINCH_OUT:
            return self._handle_zoom_in()
        elif event.gesture == GestureType.DRAG_START:
            return self._handle_selection_start(event.x, event.y)
        elif event.gesture == GestureType.DRAG_MOVE:
            return self._handle_selection_move(event.x, event.y)
        elif event.gesture == GestureType.DRAG_END:
            return self._handle_selection_end(event.x, event.y)

        return GestureResponse(ActionType.NONE, {})

    # ===================================================================
    # Reading Mode Gesture Handlers
    # ===================================================================

    def _handle_tap(self, x: int, y: int) -> GestureResponse:
        """Handle tap gesture - activates links or selects words"""
        page = self.reader.manager.get_current_page()
        result = page.query_point((x, y))

        if not result or result.object_type == "empty":
            return GestureResponse(ActionType.NONE, {})

        # If it's a link, navigate
        if result.is_interactive and result.link_target:
            # Handle different link types
            if result.link_target.endswith('.epub'):
                # Open new book
                success = self.reader.load_epub(result.link_target)
                if success:
                    return GestureResponse(ActionType.BOOK_LOADED, {
                        "title": self.reader.book_title,
                        "author": self.reader.book_author,
                        "path": result.link_target
                    })
                else:
                    return GestureResponse(ActionType.ERROR, {
                        "message": f"Failed to load {result.link_target}"
                    })
            else:
                # Internal navigation (chapter)
                self.reader.jump_to_chapter(result.link_target)
                return GestureResponse(ActionType.NAVIGATE, {
                    "target": result.link_target,
                    "chapter": self.reader.get_current_chapter_info()
                })

        # Just a tap on text - select word
        if result.text:
            return GestureResponse(ActionType.WORD_SELECTED, {
                "word": result.text,
                "bounds": result.bounds
            })

        return GestureResponse(ActionType.NONE, {})

    def _handle_long_press(self, x: int, y: int) -> GestureResponse:
        """Handle long-press - show definition or menu"""
        page = self.reader.manager.get_current_page()
        result = page.query_point((x, y))

        if result and result.text:
            return GestureResponse(ActionType.DEFINE, {
                "word": result.text,
                "bounds": result.bounds
            })

        # Long-press on empty - show menu
        return GestureResponse(ActionType.SHOW_MENU, {
            "options": ["bookmark", "settings", "toc", "search"]
        })

    def _handle_page_forward(self) -> GestureResponse:
        """Handle swipe left - next page"""
        img = self.reader.next_page()
        if img:
            return GestureResponse(ActionType.PAGE_TURN, {
                "direction": "forward",
                "progress": self.reader.get_reading_progress(),
                "chapter": self.reader.get_current_chapter_info()
            })
        return GestureResponse(ActionType.AT_END, {})

    def _handle_page_back(self) -> GestureResponse:
        """Handle swipe right - previous page"""
        img = self.reader.previous_page()
        if img:
            return GestureResponse(ActionType.PAGE_TURN, {
                "direction": "back",
                "progress": self.reader.get_reading_progress(),
                "chapter": self.reader.get_current_chapter_info()
            })
        return GestureResponse(ActionType.AT_START, {})

    def _handle_zoom_in(self) -> GestureResponse:
        """Handle pinch out - increase font"""
        self.reader.increase_font_size()
        return GestureResponse(ActionType.ZOOM, {
            "direction": "in",
            "font_scale": self.reader.base_font_scale
        })

    def _handle_zoom_out(self) -> GestureResponse:
        """Handle pinch in - decrease font"""
        self.reader.decrease_font_size()
        return GestureResponse(ActionType.ZOOM, {
            "direction": "out",
            "font_scale": self.reader.base_font_scale
        })

    def _handle_selection_start(self, x: int, y: int) -> GestureResponse:
        """Start text selection"""
        self._selection_start = (x, y)
        self._selection_end = None
        self._selected_range = None

        return GestureResponse(ActionType.SELECTION_START, {
            "start": (x, y)
        })

    def _handle_selection_move(self, x: int, y: int) -> GestureResponse:
        """Update text selection"""
        if not self._selection_start:
            return GestureResponse(ActionType.NONE, {})

        self._selection_end = (x, y)

        # Query range
        page = self.reader.manager.get_current_page()
        self._selected_range = page.query_range(
            self._selection_start,
            self._selection_end
        )

        return GestureResponse(ActionType.SELECTION_UPDATE, {
            "start": self._selection_start,
            "end": self._selection_end,
            "text_count": len(self._selected_range.results),
            "bounds": self._selected_range.bounds_list
        })

    def _handle_selection_end(self, x: int, y: int) -> GestureResponse:
        """End text selection and return selected text"""
        if not self._selection_start:
            return GestureResponse(ActionType.NONE, {})

        self._selection_end = (x, y)

        page = self.reader.manager.get_current_page()
        self._selected_range = page.query_range(
            self._selection_start,
            self._selection_end
        )

        return GestureResponse(ActionType.SELECTION_COMPLETE, {
            "text": self._selected_range.text,
            "word_count": len(self._selected_range.results),
            "bounds": self._selected_range.bounds_list
        })

    def _handle_swipe_up(self, y: int) -> GestureResponse:
        """Handle swipe up gesture - opens Navigation overlay (TOC + Bookmarks)"""
        # Open navigation overlay from anywhere on screen
        overlay_image = self.reader.open_navigation_overlay(active_tab="contents")
        if overlay_image:
            return GestureResponse(ActionType.OVERLAY_OPENED, {
                "overlay_type": "navigation",
                "active_tab": "contents",
                "chapters": self.reader.get_chapters()
            })

        return GestureResponse(ActionType.NONE, {})

    def _handle_swipe_down(self, y: int) -> GestureResponse:
        """Handle swipe down gesture - opens Settings overlay (only from top 20% of screen)"""
        # Only open settings overlay if swipe starts from top 20% of screen
        top_threshold = self.reader.page_size[1] * 0.2
        if y > top_threshold:
            return GestureResponse(ActionType.NONE, {})

        overlay_image = self.reader.open_settings_overlay()
        if overlay_image:
            return GestureResponse(ActionType.OVERLAY_OPENED, {
                "overlay_type": "settings",
                "font_scale": self.reader.base_font_scale,
                "line_spacing": self.reader.page_style.line_spacing,
                "inter_block_spacing": self.reader.page_style.inter_block_spacing
            })

        return GestureResponse(ActionType.NONE, {})

    # ===================================================================
    # Overlay Mode Gesture Handlers
    # ===================================================================

    def _handle_overlay_tap(self, x: int, y: int) -> GestureResponse:
        """Handle tap when overlay is open - delegates to EbookReader overlay handlers"""
        # This remains in EbookReader because it's tightly coupled with overlay state
        return self.reader._handle_overlay_tap(x, y)

    def _handle_overlay_close(self) -> GestureResponse:
        """Handle overlay close gesture (swipe down)"""
        self.reader.close_overlay()
        return GestureResponse(ActionType.OVERLAY_CLOSED, {})
