"""Tool to query DOM elements via CSS selectors (zero LLM cost)."""

from __future__ import annotations

import json
from typing import Any

from .base import Tool


class DomQueryTool(Tool):
    """Query the current browser page with CSS selectors."""

    def __init__(self, *, browser_backend: Any = None) -> None:
        self._backend = browser_backend

    @property
    def name(self) -> str:
        return "dom_query"

    @property
    def description(self) -> str:
        return (
            "Query DOM elements by CSS selector. Returns structured data "
            "(tag, text, attributes, href, src) for matching elements. Zero LLM cost."
        )

    @property
    def parameters(self) -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "selector": {
                    "type": "string",
                    "description": "CSS selector to query (e.g. 'a.nav-link', 'table tr', '#main h2').",
                },
                "max_results": {
                    "type": "integer",
                    "description": "Max elements to return. Default 50.",
                    "minimum": 1,
                    "maximum": 500,
                },
                "attributes": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Extra attributes to extract (e.g. ['data-id', 'aria-label']).",
                },
            },
            "required": ["selector"],
        }

    async def execute(self, **kwargs: Any) -> str:
        if self._backend is None:
            return json.dumps({"error": "No browser backend available"})

        from .browser import NativePlaywrightBrowserBackend

        if not isinstance(self._backend, NativePlaywrightBrowserBackend):
            return json.dumps({"error": "dom_query requires native Playwright backend"})

        selector = kwargs["selector"]
        max_results = kwargs.get("max_results", 50)
        extra_attrs = kwargs.get("attributes") or []

        try:
            page = await self._backend._current_page()

            js_code = """
            (args) => {
                const [selector, maxResults, extraAttrs] = args;
                const elements = document.querySelectorAll(selector);
                const results = [];
                for (let i = 0; i < Math.min(elements.length, maxResults); i++) {
                    const el = elements[i];
                    const item = {
                        tag: el.tagName.toLowerCase(),
                        text: (el.textContent || '').trim().substring(0, 200),
                        id: el.id || null,
                        class: el.className || null,
                        href: el.getAttribute('href'),
                        src: el.getAttribute('src'),
                        value: el.value !== undefined ? el.value : null,
                    };
                    for (const attr of extraAttrs) {
                        item[attr] = el.getAttribute(attr);
                    }
                    results.push(item);
                }
                return { count: elements.length, results };
            }
            """

            data = await page.evaluate(js_code, [selector, max_results, extra_attrs])
            return json.dumps({
                "ok": True,
                "selector": selector,
                "total_matches": data["count"],
                "returned": len(data["results"]),
                "elements": data["results"],
            })
        except Exception as exc:
            return json.dumps({"error": str(exc)})
