"""
Navigation overlay sub-application.

Provides tabbed interface for Contents (TOC) and Bookmarks.
"""

from __future__ import annotations
from typing import TYPE_CHECKING, List, Tuple, Dict, Any, Optional
from PIL import Image

from .base import OverlaySubApplication
from ..gesture import GestureResponse, ActionType
from ..state import OverlayState
from ..html_generator import generate_navigation_overlay

if TYPE_CHECKING:
    from ..application import EbookReader


class NavigationOverlay(OverlaySubApplication):
    """
    Unified navigation overlay with Contents and Bookmarks tabs.

    Features:
    - Tab switching between Contents and Bookmarks
    - Chapter navigation via clickable links
    - Bookmark navigation
    - Close button
    """

    def __init__(self, reader: 'EbookReader'):
        """Initialize navigation overlay."""
        super().__init__(reader)

        # Tab state
        self._active_tab: str = "contents"
        self._cached_chapters: List[Tuple[str, int]] = []
        self._cached_bookmarks: List[Dict[str, Any]] = []

        # Pagination state
        self._toc_page: int = 0  # Current page in TOC
        self._toc_items_per_page: int = 10  # Items per page
        self._bookmarks_page: int = 0  # Current page in bookmarks

    def get_overlay_type(self) -> OverlayState:
        """Return NAVIGATION overlay type."""
        return OverlayState.NAVIGATION

    def open(self, base_page: Image.Image, **kwargs) -> Image.Image:
        """
        Open the navigation overlay.

        Args:
            base_page: Current reading page to show underneath
            chapters: List of (chapter_title, chapter_index) tuples
            bookmarks: List of bookmark dicts with 'name' and optional 'position'
            active_tab: Which tab to show initially ("contents" or "bookmarks")

        Returns:
            Composited image with navigation overlay
        """
        chapters = kwargs.get('chapters', [])
        bookmarks = kwargs.get('bookmarks', [])
        active_tab = kwargs.get('active_tab', 'contents')

        # Store for later use (tab switching)
        self._cached_chapters = chapters
        self._cached_bookmarks = bookmarks
        self._active_tab = active_tab

        # Reset pagination when opening
        self._toc_page = 0
        self._bookmarks_page = 0

        # Calculate panel size (60% width, 70% height)
        panel_size = self._calculate_panel_size(0.6, 0.7)

        # Convert chapters to format expected by HTML generator
        chapter_data = [
            {"index": idx, "title": title}
            for title, idx in chapters
        ]

        # Generate navigation HTML with tabs
        html = generate_navigation_overlay(
            chapters=chapter_data,
            bookmarks=bookmarks,
            active_tab=active_tab,
            page_size=panel_size,
            toc_page=self._toc_page,
            toc_items_per_page=self._toc_items_per_page,
            bookmarks_page=self._bookmarks_page
        )

        # Render HTML to image
        overlay_panel = self.render_html_to_image(html, panel_size)

        # Cache for later use
        self._cached_base_page = base_page.copy()
        self._cached_overlay_image = overlay_panel

        # Composite and return
        return self.composite_overlay(base_page, overlay_panel)

    def handle_tap(self, x: int, y: int) -> GestureResponse:
        """
        Handle tap within navigation overlay.

        Detects:
        - Tab switching (tab:contents, tab:bookmarks)
        - Chapter selection (chapter:N)
        - Bookmark selection (bookmark:name)
        - Close button (action:close)
        - Tap outside overlay (closes)

        Args:
            x, y: Screen coordinates of tap

        Returns:
            GestureResponse with appropriate action
        """
        import logging
        logger = logging.getLogger(__name__)
        logger.info(f"[NAV_OVERLAY] Handling tap at ({x}, {y})")
        logger.info(f"[NAV_OVERLAY] Panel offset: {self._overlay_panel_offset}, Panel size: {self._panel_size}")

        # Query the overlay to see what was tapped
        query_result = self.query_overlay_pixel(x, y)

        logger.info(f"[NAV_OVERLAY] Query result: {query_result}")

        # If query failed (tap outside overlay panel), close it
        if query_result is None:
            logger.info(f"[NAV_OVERLAY] Tap outside overlay panel, closing")
            return GestureResponse(ActionType.OVERLAY_CLOSED, {})

        # Check if tapped on a link
        if query_result.get("is_interactive") and query_result.get("link_target"):
            link_target = query_result["link_target"]
            logger.info(f"[NAV_OVERLAY] Found interactive link: {link_target}")

            # Parse "tab:tabname" format for tab switching
            if link_target.startswith("tab:"):
                tab_name = link_target.split(":", 1)[1]
                self._switch_tab(tab_name)
                return GestureResponse(ActionType.TAB_SWITCHED, {
                    "tab": tab_name
                })

            # Parse "chapter:N" format for chapter navigation
            elif link_target.startswith("chapter:"):
                try:
                    chapter_idx = int(link_target.split(":")[1])

                    # Get chapter title for response
                    chapter_title = None
                    for title, idx in self._cached_chapters:
                        if idx == chapter_idx:
                            chapter_title = title
                            break

                    # Jump to selected chapter
                    self.reader.jump_to_chapter(chapter_idx)

                    return GestureResponse(ActionType.CHAPTER_SELECTED, {
                        "chapter_index": chapter_idx,
                        "chapter_title": chapter_title or f"Chapter {chapter_idx}"
                    })
                except (ValueError, IndexError):
                    pass

            # Parse "bookmark:name" format for bookmark navigation
            elif link_target.startswith("bookmark:"):
                bookmark_name = link_target.split(":", 1)[1]

                # Load the bookmark position
                page = self.reader.load_position(bookmark_name)
                if page:
                    return GestureResponse(ActionType.BOOKMARK_SELECTED, {
                        "bookmark_name": bookmark_name
                    })
                else:
                    # Failed to load bookmark
                    return GestureResponse(ActionType.ERROR, {
                        "message": f"Failed to load bookmark: {bookmark_name}"
                    })

            # Parse "action:close" format for close button
            elif link_target.startswith("action:"):
                action = link_target.split(":", 1)[1]
                if action == "close":
                    logger.info(f"[NAV_OVERLAY] Close button clicked")
                    return GestureResponse(ActionType.OVERLAY_CLOSED, {})

            # Parse "page:direction" format for pagination
            elif link_target.startswith("page:"):
                direction = link_target.split(":", 1)[1]
                logger.info(f"[NAV_OVERLAY] Pagination button clicked: {direction}")
                self._handle_pagination(direction)
                return GestureResponse(ActionType.PAGE_CHANGED, {
                    "direction": direction,
                    "tab": self._active_tab
                })

        # Tap inside overlay but not on interactive element - keep overlay open
        logger.info(f"[NAV_OVERLAY] Tap on non-interactive area inside overlay, ignoring")
        return GestureResponse(ActionType.NONE, {})

    def switch_tab(self, new_tab: str) -> Optional[Image.Image]:
        """
        Switch between tabs in the navigation overlay.

        Args:
            new_tab: Tab to switch to ("contents" or "bookmarks")

        Returns:
            Updated image with new tab active
        """
        return self._switch_tab(new_tab)

    def _switch_tab(self, new_tab: str) -> Optional[Image.Image]:
        """
        Internal tab switching implementation.

        Args:
            new_tab: Tab to switch to

        Returns:
            Updated composited image with new tab active
        """
        if not self._cached_base_page:
            return None

        self._active_tab = new_tab

        # Regenerate overlay with new active tab
        panel_size = self._calculate_panel_size(0.6, 0.7)

        # Convert chapters to format expected by HTML generator
        chapter_data = [
            {"index": idx, "title": title}
            for title, idx in self._cached_chapters
        ]

        # Generate navigation HTML with new active tab
        html = generate_navigation_overlay(
            chapters=chapter_data,
            bookmarks=self._cached_bookmarks,
            active_tab=new_tab,
            page_size=panel_size,
            toc_page=self._toc_page,
            toc_items_per_page=self._toc_items_per_page,
            bookmarks_page=self._bookmarks_page
        )

        # Render HTML to image
        overlay_panel = self.render_html_to_image(html, panel_size)

        # Update cache
        self._cached_overlay_image = overlay_panel

        # Composite and return
        return self.composite_overlay(self._cached_base_page, overlay_panel)

    def _handle_pagination(self, direction: str) -> Optional[Image.Image]:
        """
        Handle pagination within the active tab.

        Args:
            direction: Either "next" or "prev"

        Returns:
            Updated composited image with new page, or None if invalid
        """
        import logging
        logger = logging.getLogger(__name__)

        if self._active_tab == "contents":
            # Calculate total pages
            total_items = len(self._cached_chapters)
            total_pages = (total_items + self._toc_items_per_page - 1) // self._toc_items_per_page

            # Update page number
            if direction == "next" and self._toc_page < total_pages - 1:
                self._toc_page += 1
                logger.info(f"[NAV_OVERLAY] TOC page -> {self._toc_page + 1}/{total_pages}")
            elif direction == "prev" and self._toc_page > 0:
                self._toc_page -= 1
                logger.info(f"[NAV_OVERLAY] TOC page -> {self._toc_page + 1}/{total_pages}")
            else:
                logger.info(f"[NAV_OVERLAY] Can't paginate {direction} from page {self._toc_page + 1}/{total_pages}")
                return None

        elif self._active_tab == "bookmarks":
            # Calculate total pages
            total_items = len(self._cached_bookmarks)
            total_pages = (total_items + self._toc_items_per_page - 1) // self._toc_items_per_page

            # Update page number
            if direction == "next" and self._bookmarks_page < total_pages - 1:
                self._bookmarks_page += 1
                logger.info(f"[NAV_OVERLAY] Bookmarks page -> {self._bookmarks_page + 1}/{total_pages}")
            elif direction == "prev" and self._bookmarks_page > 0:
                self._bookmarks_page -= 1
                logger.info(f"[NAV_OVERLAY] Bookmarks page -> {self._bookmarks_page + 1}/{total_pages}")
            else:
                logger.info(f"[NAV_OVERLAY] Can't paginate {direction} from page {self._bookmarks_page + 1}/{total_pages}")
                return None

        # Regenerate the overlay with new page
        return self._switch_tab(self._active_tab)
