"""Web fetch tool — retrieve content from URLs."""

from __future__ import annotations

import re
from typing import Any
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError

from tsumugi.tools.base import BaseTool, PermissionLevel, ToolSpec


def _strip_html(html: str) -> str:
    """Very basic HTML to plain text conversion."""
    # Remove script and style blocks
    text = re.sub(r"<script[^>]*>.*?</script>", "", html, flags=re.DOTALL | re.IGNORECASE)
    text = re.sub(r"<style[^>]*>.*?</style>", "", text, flags=re.DOTALL | re.IGNORECASE)
    # Convert common block elements to newlines
    text = re.sub(r"<br\s*/?>", "\n", text, flags=re.IGNORECASE)
    text = re.sub(r"</(p|div|h[1-6]|li|tr)>", "\n", text, flags=re.IGNORECASE)
    # Remove remaining tags
    text = re.sub(r"<[^>]+>", "", text)
    # Collapse whitespace
    text = re.sub(r"[ \t]+", " ", text)
    text = re.sub(r"\n{3,}", "\n\n", text)
    # Decode common HTML entities
    text = text.replace("&amp;", "&").replace("&lt;", "<").replace("&gt;", ">")
    text = text.replace("&quot;", '"').replace("&nbsp;", " ")
    return text.strip()


class WebFetchTool(BaseTool):
    """Fetch content from a URL."""

    def spec(self) -> ToolSpec:
        return ToolSpec(
            name="web_fetch",
            description=(
                "Fetch content from a URL and return it as text. "
                "HTML pages are converted to plain text. "
                "Useful for reading documentation, API responses, etc."
            ),
            parameters={
                "type": "object",
                "properties": {
                    "url": {
                        "type": "string",
                        "description": "The URL to fetch",
                    },
                    "max_length": {
                        "type": "integer",
                        "description": "Maximum response length in characters (default: 10000)",
                    },
                },
                "required": ["url"],
            },
            permission=PermissionLevel.READ,
        )

    def execute(self, **kwargs: Any) -> str:
        url = kwargs["url"]
        max_length = kwargs.get("max_length", 10000)

        if not url.startswith(("http://", "https://")):
            return f"Error: Invalid URL (must start with http:// or https://): {url}"

        try:
            req = Request(url, headers={"User-Agent": "Tsumugi-Agent/0.1"})
            with urlopen(req, timeout=15) as resp:
                content_type = resp.headers.get("Content-Type", "")
                data = resp.read(max_length + 1000)  # read a bit extra for stripping

                # Detect encoding
                charset = "utf-8"
                if "charset=" in content_type:
                    charset = content_type.split("charset=")[-1].split(";")[0].strip()

                text = data.decode(charset, errors="replace")

                # Strip HTML if content looks like HTML
                if "html" in content_type.lower() or text.strip().startswith("<"):
                    text = _strip_html(text)

                if len(text) > max_length:
                    text = text[:max_length] + "\n... (truncated)"

                return f"URL: {url}\n\n{text}"

        except HTTPError as e:
            return f"HTTP Error {e.code}: {e.reason} for {url}"
        except URLError as e:
            return f"URL Error: {e.reason} for {url}"
        except TimeoutError:
            return f"Error: Request timed out for {url}"
        except Exception as e:
            return f"Error fetching {url}: {type(e).__name__}: {e}"
