"""Session tools for browser control."""

import re
import subprocess
from typing import Literal

from mcp.server.fastmcp import FastMCP

from ..browser import browser_manager


def _parse_proxy(proxy: str) -> dict:
    """Parse proxy string to Camoufox dict format.

    Supported formats:
    - login:password@ip:port
    - ip:port:login:password
    - protocol://login:password@ip:port
    - ip:port

    Output: {'server': 'http://ip:port', 'username': '...', 'password': '...'}
    """
    # Remove protocol prefix if present
    proxy = re.sub(r'^https?://', '', proxy)

    # Format: login:password@ip:port
    if '@' in proxy:
        auth, server = proxy.rsplit('@', 1)
        if ':' in auth:
            username, password = auth.split(':', 1)
            return {
                'server': f'http://{server}',
                'username': username,
                'password': password
            }
        raise ValueError("Invalid auth format in proxy")

    parts = proxy.split(':')

    # Format: ip:port:login:password
    if len(parts) == 4:
        return {
            'server': f'http://{parts[0]}:{parts[1]}',
            'username': parts[2],
            'password': parts[3]
        }

    # Format: ip:port
    if len(parts) == 2:
        return {'server': f'http://{parts[0]}:{parts[1]}'}

    raise ValueError("Invalid proxy format")


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

    @mcp.tool()
    async def browser_configure(proxy: str | None = None) -> str:
        """Configure proxy before launching browser.

        Call BEFORE browser_navigate. If browser running, call browser_close first.

        Args:
            proxy: Supports formats:
                   - login:password@ip:port
                   - ip:port:login:password
                   - http://login:password@ip:port
                   - ip:port

        Returns:
            Status message
        """
        if browser_manager.is_initialized:
            return "Browser running. Call browser_close first."

        if proxy:
            try:
                proxy_config = _parse_proxy(proxy)
                browser_manager.update_config(proxy=proxy_config)
                return f"Proxy configured: {proxy_config['server']}"
            except ValueError as e:
                return str(e)
        return "No proxy provided."

    @mcp.tool()
    async def browser_tabs(
        action: Literal["list", "new", "close", "select"],
        index: int | None = None,
    ) -> str:
        """List, create, close, or select a browser tab.

        Args:
            action: Operation to perform:
                   - list: List all open tabs
                   - new: Create a new tab
                   - close: Close a tab (uses index if provided, else current tab)
                   - select: Select a tab by index
            index: Tab index, used for close/select operations.
                  If omitted for close, current tab is closed.

        Returns:
            Result of the tab operation
        """
        try:
            if action == "list":
                tabs = await browser_manager.list_pages()
                if not tabs:
                    return "No tabs open"

                lines = []
                for tab in tabs:
                    active = " (active)" if tab.is_active else ""
                    lines.append(f"[{tab.index}]{active} {tab.title} - {tab.url}")
                return "\n".join(lines)

            elif action == "new":
                page, idx = await browser_manager.create_page()
                return f"Created new tab at index {idx}"

            elif action == "close":
                await browser_manager.close_page(index)
                return f"Closed tab at index {index if index is not None else 'current'}"

            elif action == "select":
                if index is None:
                    return "Error: index is required for select action"
                await browser_manager.select_page(index)
                tabs = await browser_manager.list_pages()
                active_tab = next((t for t in tabs if t.is_active), None)
                if active_tab:
                    return f"Selected tab {index}: {active_tab.title}"
                return f"Selected tab {index}"

            else:
                return f"Unknown action: {action}"

        except Exception as e:
            return f"Tab operation failed: {e}"

    @mcp.tool()
    async def browser_resize(width: int, height: int) -> str:
        """Resize the browser window.

        Args:
            width: Width of the browser window in pixels
            height: Height of the browser window in pixels

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

        try:
            await page.set_viewport_size({"width": width, "height": height})
            return f"Resized browser to {width}x{height}"
        except Exception as e:
            return f"Resize failed: {e}"

    @mcp.tool()
    async def browser_close() -> str:
        """Close the browser.

        This will terminate the browser instance and clean up all resources.
        A new browser will be launched on the next navigation command.

        Returns:
            Success message
        """
        try:
            await browser_manager.close()
            return "Browser closed successfully"
        except Exception as e:
            return f"Failed to close browser: {e}"

    @mcp.tool()
    async def browser_install() -> str:
        """Install Camoufox browser.

        Call this if you get an error about the browser not being installed.
        This will download and install the Camoufox browser binary.

        Returns:
            Installation result
        """
        try:
            # Run camoufox fetch command
            result = subprocess.run(
                ["python", "-m", "camoufox", "fetch"],
                capture_output=True,
                text=True,
                timeout=300,  # 5 minute timeout
            )

            if result.returncode == 0:
                output = result.stdout.strip() if result.stdout else "Installation completed"
                return f"Camoufox installed successfully.\n{output}"
            else:
                error = result.stderr.strip() if result.stderr else "Unknown error"
                return f"Installation failed: {error}"

        except subprocess.TimeoutExpired:
            return "Installation timed out after 5 minutes"
        except FileNotFoundError:
            return "Python not found. Ensure Python is installed and in PATH."
        except Exception as e:
            return f"Installation failed: {e}"
