"""Navigation tools for browser control."""

from mcp.server.fastmcp import FastMCP

from ..browser import browser_manager


def register(mcp: FastMCP) -> None:
    """Register navigation tools with the MCP server."""

    @mcp.tool()
    async def browser_navigate(url: str) -> str:
        """Navigate to a URL.

        Args:
            url: The URL to navigate to

        Returns:
            Success message with the page title
        """
        page = await browser_manager.get_page()

        try:
            await page.goto(url, wait_until=browser_manager._config.wait_strategy)
            title = await page.title()
            return f"Navigated to {url}\nPage title: {title}"
        except Exception as e:
            return f"Navigation failed: {e}"

    @mcp.tool()
    async def browser_navigate_back() -> str:
        """Go back to the previous page.

        Returns:
            Success message with the new page title
        """
        page = await browser_manager.get_page()

        try:
            await page.go_back(wait_until=browser_manager._config.wait_strategy)
            title = await page.title()
            url = page.url
            return f"Navigated back to {url}\nPage title: {title}"
        except Exception as e:
            return f"Navigation back failed: {e}"

    @mcp.tool()
    async def browser_snapshot() -> str:
        """Capture accessibility snapshot of the current page.

        This provides a structured view of the page content that is better
        for understanding page structure than screenshots.

        Returns:
            Accessibility tree of the current page
        """
        page = await browser_manager.get_page()

        try:
            snapshot = await page.accessibility.snapshot()
            if snapshot is None:
                return "No accessibility tree available for this page"

            def format_node(node: dict, indent: int = 0) -> str:
                """Format an accessibility node recursively."""
                lines = []
                prefix = "  " * indent

                role = node.get("role", "")
                name = node.get("name", "")
                value = node.get("value", "")

                # Build node description
                parts = [role]
                if name:
                    parts.append(f'"{name}"')
                if value:
                    parts.append(f"value={value}")

                # Add ref for interactive elements
                if role in [
                    "button",
                    "link",
                    "textbox",
                    "checkbox",
                    "radio",
                    "combobox",
                    "menuitem",
                    "tab",
                    "slider",
                ]:
                    # Generate a ref based on role and name
                    ref = f"{role}:{name}" if name else f"{role}:{id(node)}"
                    parts.append(f"[ref={ref}]")

                lines.append(f"{prefix}{' '.join(parts)}")

                # Process children
                for child in node.get("children", []):
                    lines.append(format_node(child, indent + 1))

                return "\n".join(lines)

            return format_node(snapshot)
        except Exception as e:
            return f"Failed to capture snapshot: {e}"

    @mcp.tool()
    async def browser_wait_for(
        text: str | None = None,
        text_gone: str | None = None,
        time: float | None = None,
    ) -> str:
        """Wait for text to appear, disappear, or a specified time to pass.

        Args:
            text: Text to wait for to appear
            text_gone: Text to wait for to disappear
            time: Time to wait in seconds

        Returns:
            Success message when condition is met
        """
        page = await browser_manager.get_page()

        try:
            if text:
                await page.wait_for_selector(f"text={text}", state="visible")
                return f"Text '{text}' appeared on the page"
            elif text_gone:
                await page.wait_for_selector(f"text={text_gone}", state="hidden")
                return f"Text '{text_gone}' is no longer visible"
            elif time:
                await page.wait_for_timeout(time * 1000)  # Convert to ms
                return f"Waited for {time} seconds"
            else:
                return "No wait condition specified. Provide text, text_gone, or time."
        except Exception as e:
            return f"Wait failed: {e}"
