"""
渲染事件处理器
处理解析数据并调用 renderer 渲染的事件
"""

from typing import Dict, Any


class RenderHandler:
    """渲染事件处理器 - 解析数据并调用 renderer"""

    def __init__(self, ws_client, tui, renderer, app_state):
        """
        Args:
            ws_client: WebSocket 客户端
            tui: TUI 实例
            renderer: 流式渲染器
            app_state: 应用状态
        """
        self.ws_client = ws_client
        self.tui = tui
        self.renderer = renderer
        self.app_state = app_state

    async def handle_text_chunk(self, event: Dict[str, Any]):
        """处理文本块事件"""
        self.app_state.set_processing_state()
        if self.app_state.interrupt_requested:
            return
        data = event.get("data", {})
        self.renderer.on_text_chunk(data.get("content", ""))

    async def handle_text_chunk_complete(self, event: Dict[str, Any]):
        """处理文本流结束事件"""
        self.renderer.on_text_chunk_complete()

    async def handle_tool_start(self, event: Dict[str, Any]):
        """处理工具开始事件"""
        self.app_state.set_processing_state()
        data = event.get("data", {})
        tool_id = data.get("call_id", data.get("tool_id", ""))
        tool_name = data.get("tool", data.get("tool_name", "unknown"))
        args = data.get("args", {})
        self.renderer.on_tool_start(tool_id, tool_name, args)

    async def handle_tool_end(self, event: Dict[str, Any]):
        """处理工具结束事件"""
        from core.logger import log_event

        data = event.get("data", {})
        tool_id = data.get("call_id", data.get("tool_id", ""))
        tool_name = data.get("tool", data.get("tool_name", "unknown"))
        success = data.get("success", True)
        result = data.get("result", "")
        args = data.get("args", {})

        log_event("cli_tool_end_received",
            tool_id=tool_id,
            success=success,
            data_keys=list(data.keys()),
        )

        self.renderer.on_tool_end(tool_id, success, result, args)

        # 如果是 TodoWrite 工具执行成功，触发一次 Todo 查询并显示
        if tool_name.lower() == "todowrite" and success:
            await self._fetch_and_display_todos()

    async def _fetch_and_display_todos(self):
        """获取并显示当前会话的 Todo 列表"""
        from core.todo import TodoManager
        from rich.markdown import Markdown

        session_id = self.ws_client.session_id if self.ws_client else None
        if not session_id:
            return

        try:
            manager = TodoManager()
            todos = await manager.get(session_id)

            if not todos:
                return

            lines = ["**Todo (待办事项)：**"]
            for todo in todos:
                checkbox = "[x]" if todo.status == "completed" else "[ ]"
                if todo.status == "completed":
                    lines.append(f"- {checkbox} ~~{todo.content}~~")
                else:
                    lines.append(f"- {checkbox} **{todo.content}**")

            self.tui._write_safe(Markdown("\n".join(lines)))
            self.tui._write_safe("\n")
        except Exception:
            # 静默失败，不影响主流程
            return

    async def handle_thinking_start(self, event: Dict[str, Any]):
        """处理思考开始事件"""
        self.renderer.on_thinking_start()

    async def handle_thinking_end(self, event: Dict[str, Any]):
        """处理思考结束事件"""
        self.renderer.on_thinking_end()

    async def handle_error(self, event: Dict[str, Any]):
        """处理错误事件"""
        from core.logger import log_event

        data = event.get("data", {})
        message = data.get("message", "Unknown error")
        will_retry = data.get("will_retry", False)

        log_event("DEBUG_error_event_received",
            event_type=event.get("type"),
            message=message[:50] if message else None,
            will_retry=will_retry,
        )

        if will_retry:
            self.renderer.on_error_warning(message)
        else:
            self.renderer.on_error(message)
            self.app_state.set_input_state()

    async def handle_response_end(self, event: Dict[str, Any]):
        """处理响应结束事件"""
        event_type = event.get("type", "")
        interrupted = (event_type == "task_interrupted")
        self.renderer.on_response_end(interrupted=interrupted)
        self.app_state.set_input_state()

    async def handle_connected(self, event: Dict[str, Any]):
        """处理连接成功事件"""
        data = event.get("data", {})
        server_session_id = data.get("session_id", "")
        
        # 清空输出，展示欢迎信息
        self.tui.clear_output()
        self.tui.print_welcome()
        
        # 返回 session_id 供调用方使用
        return server_session_id

    async def handle_subtask_started(self, event: Dict[str, Any]):
        """处理子任务开始事件"""
        data = event.get("data", {})
        self.renderer.on_subtask_started(data)

    async def handle_subtask_completed(self, event: Dict[str, Any]):
        """处理子任务完成事件"""
        data = event.get("data", {})
        self.renderer.on_subtask_completed(data)

    async def handle_context_compress_start(self, event: Dict[str, Any]):
        """处理上下文压缩开始事件"""
        if self.app_state.is_input_state:
            return
        self.renderer.on_context_compress_start()

    async def handle_context_compress_end(self, event: Dict[str, Any]):
        """处理上下文压缩结束事件"""
        if self.app_state.is_input_state:
            return
        data = event.get("data", {})
        success = data.get("success", True)
        self.renderer.on_context_compress_end(success)

    async def handle_compact_result(self, event: Dict[str, Any]):
        """处理压缩上下文响应"""
        data = event.get("data", {})
        success = data.get("success", False)
        skipped = data.get("skipped", False)
        message = data.get("message", "")

        self.renderer.on_manual_compact_end(success, message if skipped else None)

    async def handle_query_todo_response(self, event: Dict[str, Any]):
        """处理查询 TODO 响应"""
        data = event.get("data", {})
        todos = data.get("todos", [])

        if not todos:
            self.tui.print_command_result("暂无 TODO", success=True)
            return

        lines = ["TODO 列表:\n"]
        for todo in todos:
            content = todo.get("content", "")[:50]
            lines.append(f"  - {content}")

        self.tui.print_command_result("\n".join(lines), success=True)

    async def handle_query_tools_response(self, event: Dict[str, Any]):
        """处理查询工具响应"""
        data = event.get("data", {})
        categorized_tools = data.get("categorized_tools", {})

        if not categorized_tools:
            self.tui.print_command_result("暂无工具", success=True)
            return

        from tools.registry import TOOL_CATEGORIES

        lines = ["## 可用工具\n"]

        for cat_key, cat_info in TOOL_CATEGORIES.items():
            cat_name = cat_info["name"]
            cat_tools = categorized_tools.get(cat_key, [])

            if not cat_tools:
                continue

            lines.append(f"### {cat_name}\n")
            for tool in cat_tools:
                name = tool.get("name", "")
                desc = tool.get("description", "")
                desc = desc.replace("\n", " ").replace("\r", "").strip()
                if len(desc) > 80:
                    desc = desc[:80] + "..."
                if desc:
                    lines.append(f"- **{name}**: {desc}")
                else:
                    lines.append(f"- **{name}**")
            lines.append("")

        from interface.widgets import LeftAlignedMarkdown
        self.tui._write_safe(LeftAlignedMarkdown("\n".join(lines)))

    async def handle_query_skills_response(self, event: Dict[str, Any]):
        """处理查询 skills 响应"""
        from rich.markdown import Markdown

        data = event.get("data", {})
        skills = data.get("skills", [])

        if not skills:
            self.tui.print_command_result("暂无 skills", success=True)
            return

        lines = ["## 可用 Skills\n"]
        for skill in skills:
            name = skill.get("name", "")
            desc = skill.get("description", "")
            if desc:
                lines.append(f"- **{name}**: {desc}")
            else:
                lines.append(f"- **{name}**")

        md_content = "\n".join(lines)
        self.tui._write_safe(Markdown(md_content))
