"""
事件分发器
将事件路由到对应的处理器
"""

from typing import Dict, Any, Optional, Callable
from core.logger import log_event


class EventDispatcher:
    """事件分发器 - 根据事件类型路由到对应的处理器"""

    def __init__(
        self,
        render_handler,
        interaction_handler,
    ):
        """
        Args:
            render_handler: 渲染事件处理器
            interaction_handler: 用户交互处理器
        """
        self.render_handler = render_handler
        self.interaction_handler = interaction_handler

        # 事件到处理器的映射
        self._handlers: Dict[str, Callable] = {
            # 渲染类事件
            "text_chunk": self._handle_render,
            "text_chunk_complete": self._handle_render,
            "tool_call_start": self._handle_render,
            "tool_call_end": self._handle_render,
            "thinking_start": self._handle_render,
            "thinking_end": self._handle_render,
            "error": self._handle_render,
            "task_error": self._handle_render,
            "task_started": self._handle_render,
            "task_completed": self._handle_render,
            "task_interrupted": self._handle_render,
            "subtask_started": self._handle_render,
            "subtask_completed": self._handle_render,
            "context_compress_start": self._handle_render,
            "context_compress_end": self._handle_render,
            "compact_result": self._handle_render,
            "connected": self._handle_render,
            "query_todo_response": self._handle_render,
            "query_tools_response": self._handle_render,
            "query_skills_response": self._handle_render,
            "model_switched": self._handle_render,
            "agent_switched": self._handle_render,
            # 交互类事件
            "permission_request": self._handle_interaction,
            "interaction_request": self._handle_interaction,
        }

    @property
    def event_types(self) -> list[str]:
        """返回所有可处理的事件类型"""
        return list(self._handlers.keys())

    async def dispatch(self, event: Dict[str, Any]):
        """分发事件到对应的处理器

        Args:
            event: 事件字典，必须包含 "type" 字段
        """
        event_type = event.get("type", "")

        handler = self._handlers.get(event_type)
        if handler:
            await handler(event)
        else:
            log_event("unhandled_event", event_type=event_type)

    async def _handle_render(self, event: Dict[str, Any]):
        """处理渲染类事件"""
        event_type = event.get("type", "")
        method_name = f"handle_{self._to_method_name(event_type)}"

        handler = getattr(self.render_handler, method_name, None)
        if handler:
            await handler(event)

    async def _handle_interaction(self, event: Dict[str, Any]):
        """处理交互类事件"""
        event_type = event.get("type", "")
        method_name = f"handle_{self._to_method_name(event_type)}"

        handler = getattr(self.interaction_handler, method_name, None)
        if handler:
            await handler(event)

    def _to_method_name(self, event_type: str) -> str:
        """将事件类型转换为方法名

        Examples:
            text_chunk -> text_chunk
            permission_request -> permission_request
            task_completed -> response_end
        """
        # 特殊映射
        mapping = {
            "task_completed": "response_end",
            "task_interrupted": "response_end",
            "tool_call_start": "tool_start",
            "tool_call_end": "tool_end",
        }
        if event_type in mapping:
            return mapping[event_type]
        return event_type
