"""Interaction tools for browser control."""

from typing import Literal

from mcp.server.fastmcp import FastMCP

from ..browser import browser_manager


def _parse_ref(ref: str) -> str:
    """Parse a ref string into a selector.

    The ref format is "role:name" or just a CSS selector.
    """
    if ":" in ref and not ref.startswith(("http", "//")):
        role, name = ref.split(":", 1)
        # Use Playwright's role selector
        return f"role={role}[name='{name}']"
    return ref


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

    @mcp.tool()
    async def browser_click(
        element: str,
        ref: str,
        button: Literal["left", "right", "middle"] = "left",
        double_click: bool = False,
    ) -> str:
        """Perform click on a web page element.

        Args:
            element: Human-readable element description
            ref: Exact target element reference from the page snapshot
            button: Button to click (left, right, middle). Defaults to left.
            double_click: Whether to perform a double click

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

        try:
            selector = _parse_ref(ref)

            if double_click:
                await page.dblclick(selector, button=button)
                return f"Double-clicked on {element}"
            else:
                await page.click(selector, button=button)
                return f"Clicked on {element}"
        except Exception as e:
            return f"Click failed on {element}: {e}"

    @mcp.tool()
    async def browser_type(
        element: str,
        ref: str,
        text: str,
        slowly: bool = False,
        submit: bool = False,
    ) -> str:
        """Type text into an editable element.

        Args:
            element: Human-readable element description
            ref: Exact target element reference from the page snapshot
            text: Text to type into the element
            slowly: Whether to type one character at a time (useful for key handlers)
            submit: Whether to submit entered text (press Enter after)

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

        try:
            selector = _parse_ref(ref)

            if slowly:
                await page.type(selector, text, delay=100)
            else:
                await page.fill(selector, text)

            if submit:
                await page.press(selector, "Enter")

            action = "Typed and submitted" if submit else "Typed"
            return f"{action} '{text}' into {element}"
        except Exception as e:
            return f"Type failed on {element}: {e}"

    @mcp.tool()
    async def browser_hover(element: str, ref: str) -> str:
        """Hover over an element on the page.

        Args:
            element: Human-readable element description
            ref: Exact target element reference from the page snapshot

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

        try:
            selector = _parse_ref(ref)
            await page.hover(selector)
            return f"Hovering over {element}"
        except Exception as e:
            return f"Hover failed on {element}: {e}"

    @mcp.tool()
    async def browser_drag(
        start_element: str,
        start_ref: str,
        end_element: str,
        end_ref: str,
    ) -> str:
        """Perform drag and drop between two elements.

        Args:
            start_element: Human-readable source element description
            start_ref: Exact source element reference from the page snapshot
            end_element: Human-readable target element description
            end_ref: Exact target element reference from the page snapshot

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

        try:
            start_selector = _parse_ref(start_ref)
            end_selector = _parse_ref(end_ref)

            await page.drag_and_drop(start_selector, end_selector)
            return f"Dragged from {start_element} to {end_element}"
        except Exception as e:
            return f"Drag failed from {start_element} to {end_element}: {e}"

    @mcp.tool()
    async def browser_press_key(key: str) -> str:
        """Press a key on the keyboard.

        Args:
            key: Name of the key to press (e.g., 'ArrowLeft', 'Enter', 'a')

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

        try:
            await page.keyboard.press(key)
            return f"Pressed key: {key}"
        except Exception as e:
            return f"Key press failed: {e}"

    @mcp.tool()
    async def browser_select_option(
        element: str,
        ref: str,
        values: list[str],
    ) -> str:
        """Select an option in a dropdown.

        Args:
            element: Human-readable element description
            ref: Exact target element reference from the page snapshot
            values: Array of values to select (can be single or multiple)

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

        try:
            selector = _parse_ref(ref)
            await page.select_option(selector, values)
            return f"Selected '{', '.join(values)}' in {element}"
        except Exception as e:
            return f"Select failed on {element}: {e}"
