"""插件运行时的浏览器渲染能力。"""

from typing import Any, Dict

from src.common.logger import get_logger
from src.services.html_render_service import HtmlRenderRequest, get_html_render_service

logger = get_logger("plugin_runtime.integration")


class RuntimeRenderCapabilityMixin:
    """插件运行时的浏览器渲染能力混入。"""

    @staticmethod
    def _coerce_int(value: Any, default: int) -> int:
        """将任意值尽量转换为整数。

        Args:
            value: 原始输入值。
            default: 转换失败时返回的默认值。

        Returns:
            int: 规范化后的整数结果。
        """

        try:
            return int(value)
        except (TypeError, ValueError):
            return default

    @staticmethod
    def _coerce_float(value: Any, default: float) -> float:
        """将任意值尽量转换为浮点数。

        Args:
            value: 原始输入值。
            default: 转换失败时返回的默认值。

        Returns:
            float: 规范化后的浮点结果。
        """

        try:
            return float(value)
        except (TypeError, ValueError):
            return default

    @staticmethod
    def _coerce_bool(value: Any, default: bool = False) -> bool:
        """将任意值转换为布尔值。

        Args:
            value: 原始输入值。
            default: 输入为空时返回的默认值。

        Returns:
            bool: 规范化后的布尔结果。
        """

        if value is None:
            return default
        if isinstance(value, str):
            normalized_value = value.strip().lower()
            if normalized_value in {"0", "false", "no", "off"}:
                return False
            if normalized_value in {"1", "true", "yes", "on"}:
                return True
        return bool(value)

    def _build_html_render_request(self, args: Dict[str, Any]) -> HtmlRenderRequest:
        """根据 capability 调用参数构造渲染请求。

        Args:
            args: capability 调用参数。

        Returns:
            HtmlRenderRequest: 结构化后的渲染请求。
        """

        viewport = args.get("viewport", {})
        viewport_width = 900
        viewport_height = 500
        if isinstance(viewport, dict):
            viewport_width = self._coerce_int(viewport.get("width"), viewport_width)
            viewport_height = self._coerce_int(viewport.get("height"), viewport_height)

        return HtmlRenderRequest(
            html=str(args.get("html", "") or ""),
            selector=str(args.get("selector", "body") or "body"),
            viewport_width=viewport_width,
            viewport_height=viewport_height,
            device_scale_factor=self._coerce_float(args.get("device_scale_factor"), 2.0),
            full_page=self._coerce_bool(args.get("full_page"), False),
            omit_background=self._coerce_bool(args.get("omit_background"), False),
            wait_until=str(args.get("wait_until", "load") or "load"),
            wait_for_selector=str(args.get("wait_for_selector", "") or ""),
            wait_for_timeout_ms=self._coerce_int(args.get("wait_for_timeout_ms"), 0),
            timeout_ms=self._coerce_int(args.get("timeout_ms"), 0),
            allow_network=self._coerce_bool(args.get("allow_network"), False),
        )

    async def _cap_render_html2png(self, plugin_id: str, capability: str, args: Dict[str, Any]) -> Any:
        """将 HTML 内容渲染为 PNG 图片。

        Args:
            plugin_id: 调用该能力的插件 ID。
            capability: 当前能力名称。
            args: 能力调用参数。

        Returns:
            Any: 标准化后的能力返回结构。
        """

        del plugin_id, capability
        try:
            request = self._build_html_render_request(args)
            result = await get_html_render_service().render_html_to_png(request)
            return {"success": True, "result": result.to_payload()}
        except Exception as exc:
            logger.error(f"[cap.render.html2png] 执行失败: {exc}", exc_info=True)
            return {"success": False, "error": str(exc)}
