"""请求分发 — 按 tool_id 路由到实际运行的服务端点"""

from __future__ import annotations

import asyncio
import logging
from typing import Any, TYPE_CHECKING

import httpx

if TYPE_CHECKING:
    from tool_agent.router.status import ToolStatusManager

logger = logging.getLogger(__name__)


class Dispatcher:
    """根据工具的运行状态分发请求到对应端点"""

    def __init__(self, status_manager: ToolStatusManager) -> None:
        self._status_manager = status_manager

    async def dispatch(self, tool_id: str, params: dict[str, Any], stream: bool = False) -> dict[str, Any]:
        """分发调用请求到工具的活跃端点；无可用端点时先尝试启动（本地 uv 进程等）。"""
        
        # 0. 拦截处于维护或不可用的工具
        BLOCKED_TOOLS = {
            "launch_comfy_env", "runcomfy_workflow_executor", "runcomfy_stop_env", "runcomfy_check_status",
            "ji_meng_add_task", "ji_meng_query_task",
            "midjourney_submit_job", "midjourney_query_job_status", "midjourney_get_image_urls"
        }
        if tool_id in BLOCKED_TOOLS:
            logger.warning(f"Intercepted call to blocked tool: {tool_id}")
            return {
                "status": "error", 
                "error": f"Tool '{tool_id}' 暂时不可用或正处于停机维护状态，请尝试换一种生图工具（如 flux, seedream, liblibai 等）。"
            }

        sm = self._status_manager
        endpoint = sm.get_active_endpoint(tool_id)
        if not endpoint:
            await asyncio.to_thread(sm.start_tool, tool_id)
            endpoint = sm.get_active_endpoint(tool_id)
        if not endpoint:
            route = sm.get_status(tool_id)
            err = (route.last_error or "").strip() if route else ""
            msg = err or f"Tool '{tool_id}' is not running or has no active endpoint"
            return {"status": "error", "error": msg}

        # 2. 根据端点类型调用
        try:
            async with httpx.AsyncClient(timeout=600.0) as client:
                headers = {}
                if endpoint.get("api_key"):
                    headers["Authorization"] = f"Bearer {endpoint['api_key']}"

                if endpoint["http_method"].upper() == "POST":
                    response = await client.post(endpoint["url"], json=params, headers=headers)
                else:
                    response = await client.get(endpoint["url"], params=params, headers=headers)

                response.raise_for_status()
                return response.json()

        except httpx.HTTPStatusError as e:
            logger.error(f"HTTP error calling '{tool_id}': {e.response.status_code} {e.response.text}")
            return {"status": "error", "error": f"HTTP {e.response.status_code}: {e.response.text}"}
        except Exception as e:
            logger.error(f"Error calling '{tool_id}': {e}")
            return {"status": "error", "error": str(e)}
