import asyncio
from typing import overload

import httpx
from html_to_markdown import ConversionOptions, convert
from pydantic import BaseModel, Field
from pydantic_ai import Agent

from app.agent.deps import Deps


class WebPageText(BaseModel):
    url: str
    content: str = Field(default_factory=str)
    error: str | None = None


def configure_web_fetch_tool(
    agent: Agent[Deps, str],
) -> Agent[Deps, str]:
    @overload
    async def web_fetch(urls: str) -> WebPageText: ...

    @overload
    async def web_fetch(urls: list[str]) -> list[WebPageText]: ...

    @agent.tool_plain
    async def web_fetch(
        urls: str | list[str],
        as_markdown: bool = True,
    ) -> WebPageText | list[WebPageText]:
        """Obtém o conteúdo textual de uma ou mais páginas da web.

        Args:
            urls: Uma única URL ou uma lista de URLs.
            as_markdown: Converte o HTML para markdown.
        """
        options = ConversionOptions(extract_metadata=False, skip_images=False)

        is_single = isinstance(urls, str)
        urls = [urls] if is_single else urls

        async with httpx.AsyncClient(
            timeout=15.0,
            follow_redirects=True,
            headers={"User-Agent": "Matraca/0.1"},
        ) as client:

            async def fetch(url: str) -> WebPageText:
                try:
                    response = await client.get(url)
                    if response.status_code != 200:
                        return WebPageText(
                            url=url,
                            error=f"[ERRO] Status {response.status_code}",
                        )
                    content = (
                        convert(response.text, options=options) if as_markdown else response.text
                    )
                    return WebPageText(url=url, content=content)
                except Exception as e:
                    return WebPageText(
                        url=url,
                        error=f"[ERRO] {type(e).__name__} | {str(e)}",
                    )

            results = await asyncio.gather(*(fetch(url) for url in urls))
            return results[0] if is_single else list(results)

    return agent
