"""WebCrawlTool - 基于 Crawl4AI 的网页抓取工具，支持优雅降级"""

import logging
from typing import Any

from agentkit.tools.base import Tool

logger = logging.getLogger(__name__)

# 检测 Crawl4AI 是否可用
_CRAWL4AI_AVAILABLE = False
AsyncWebCrawler = None
JsonCssExtractionStrategy = None
try:
    from crawl4ai import AsyncWebCrawler
    from crawl4ai.extraction_strategy import JsonCssExtractionStrategy

    _CRAWL4AI_AVAILABLE = True
except ImportError:
    pass


class WebCrawlTool(Tool):
    """网页抓取工具 - 使用 Crawl4AI，可选依赖未安装时优雅降级

    支持 Markdown/HTML 输出、CSS 选择器提取、JS 渲染等待。
    当 Crawl4AI 未安装时，返回包含安装提示的错误信息。
    """

    def __init__(
        self,
        name: str = "web_crawl",
        description: str = "抓取网页内容，支持 Markdown/HTML 输出和 CSS 选择器提取",
        input_schema: dict[str, Any] | None = None,
        output_schema: dict[str, Any] | None = None,
        version: str = "1.0.0",
        tags: list[str] | None = None,
    ):
        super().__init__(
            name=name,
            description=description,
            input_schema=input_schema or self._default_input_schema(),
            output_schema=output_schema or self._default_output_schema(),
            version=version,
            tags=tags or ["web", "crawl"],
        )

    @staticmethod
    def _default_input_schema() -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "url": {
                    "type": "string",
                    "description": "要抓取的 URL",
                },
                "format": {
                    "type": "string",
                    "description": "输出格式：markdown 或 html",
                    "default": "markdown",
                    "enum": ["markdown", "html"],
                },
                "css_selector": {
                    "type": "string",
                    "description": "可选的 CSS 选择器，用于结构化提取",
                },
                "js_wait": {
                    "type": "number",
                    "description": "等待 JS 渲染的秒数",
                    "default": 0,
                },
            },
            "required": ["url"],
        }

    @staticmethod
    def _default_output_schema() -> dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "content": {"type": "string", "description": "抓取到的内容"},
                "status_code": {"type": "integer", "description": "HTTP 状态码"},
                "links": {"type": "array", "items": {"type": "string"}, "description": "页面中的链接"},
                "success": {"type": "boolean", "description": "是否成功"},
                "error": {"type": "string", "description": "错误信息（仅失败时）"},
            },
        }

    async def execute(self, **kwargs) -> dict:
        """执行网页抓取

        Args:
            url: 要抓取的 URL（必需）
            format: 输出格式 - "markdown" 或 "html"（默认 "markdown"）
            css_selector: 可选的 CSS 选择器，用于结构化提取
            js_wait: 等待 JS 渲染的秒数（默认 0）

        Returns:
            包含 content, status_code, links, success 的字典
        """
        url = kwargs.get("url")
        if not url:
            return {"error": "url 参数是必需的", "success": False}

        output_format = kwargs.get("format", "markdown")
        css_selector = kwargs.get("css_selector")
        js_wait = kwargs.get("js_wait", 0)

        # 优雅降级：Crawl4AI 未安装
        if not _CRAWL4AI_AVAILABLE:
            return {
                "error": "Crawl4AI not installed. Run: pip install crawl4ai",
                "success": False,
            }

        try:
            extraction_strategy = None
            if css_selector:
                extraction_strategy = JsonCssExtractionStrategy(css_selector)

            async with AsyncWebCrawler() as crawler:
                result = await crawler.arun(
                    url=url,
                    extraction_strategy=extraction_strategy,
                    js_wait=js_wait if js_wait else None,
                )

            # 提取内容
            if output_format == "html":
                content = result.html or ""
            else:
                content = result.markdown or ""

            # 提取链接
            links: list[str] = []
            if hasattr(result, "links") and result.links:
                links = result.links if isinstance(result.links, list) else []

            status_code = result.status_code if hasattr(result, "status_code") else 200

            response: dict[str, Any] = {
                "content": content,
                "status_code": status_code,
                "links": links,
                "success": True,
            }

            # 如果使用了 CSS 选择器提取，附加提取结果
            if extraction_strategy and hasattr(result, "extracted_content") and result.extracted_content:
                response["extracted"] = result.extracted_content

            return response

        except Exception as e:
            logger.error(f"WebCrawlTool 抓取失败: {url} - {e}")
            return {
                "error": str(e),
                "success": False,
            }
