"""Form tools for browser control."""

from mcp.server.fastmcp import FastMCP

from ..browser import browser_manager
from ..types import FormField


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

    @mcp.tool()
    async def browser_fill_form(fields: list[dict]) -> str:
        """Fill multiple form fields.

        Args:
            fields: List of form fields to fill. Each field should have:
                   - name: Human-readable field name
                   - ref: Exact target field reference from the page snapshot
                   - type: Field type (textbox, checkbox, radio, combobox, slider)
                   - value: Value to fill (for checkbox use 'true'/'false',
                           for combobox use option text)

        Returns:
            Success message with filled fields
        """
        from .interaction import _parse_ref

        page = await browser_manager.get_page()

        filled = []
        errors = []

        for field_data in fields:
            try:
                field = FormField(**field_data)
                selector = _parse_ref(field.ref)

                if field.type == "textbox":
                    await page.fill(selector, field.value)
                elif field.type == "checkbox":
                    is_checked = await page.is_checked(selector)
                    should_check = field.value.lower() == "true"
                    if is_checked != should_check:
                        await page.click(selector)
                elif field.type == "radio":
                    await page.click(selector)
                elif field.type == "combobox":
                    await page.select_option(selector, field.value)
                elif field.type == "slider":
                    # For sliders, we need to set the value via JavaScript
                    await page.evaluate(
                        f"document.querySelector('{selector}').value = '{field.value}'"
                    )

                filled.append(field.name)
            except Exception as e:
                errors.append(f"{field_data.get('name', 'unknown')}: {e}")

        result = []
        if filled:
            result.append(f"Filled fields: {', '.join(filled)}")
        if errors:
            result.append(f"Errors: {'; '.join(errors)}")

        return "\n".join(result) if result else "No fields processed"

    @mcp.tool()
    async def browser_file_upload(paths: list[str] | None = None) -> str:
        """Upload one or multiple files.

        This tool should be called when a file chooser dialog appears.
        If paths is omitted, the file chooser is cancelled.

        Args:
            paths: The absolute paths to the files to upload. Can be single
                  or multiple files. If omitted, file chooser is cancelled.

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

        try:
            # Wait for file chooser with a timeout
            async with page.expect_file_chooser(timeout=5000) as fc_info:
                # The file chooser should already be triggered
                pass

            file_chooser = await fc_info.value

            if paths:
                await file_chooser.set_files(paths)
                return f"Uploaded files: {', '.join(paths)}"
            else:
                # Cancel by setting empty files
                await file_chooser.set_files([])
                return "File chooser cancelled"
        except Exception as e:
            return f"File upload failed: {e}"

    @mcp.tool()
    async def browser_handle_dialog(
        accept: bool,
        prompt_text: str | None = None,
    ) -> str:
        """Handle a dialog (alert, confirm, prompt, beforeunload).

        Args:
            accept: Whether to accept the dialog.
            prompt_text: The text of the prompt in case of a prompt dialog.

        Returns:
            Success message
        """
        handled = await browser_manager.handle_dialog(accept, prompt_text)

        if handled:
            action = "accepted" if accept else "dismissed"
            return f"Dialog {action}"
        else:
            return "No pending dialog to handle"
