"""CLI 通道实现"""

import logging
import os
from typing import TYPE_CHECKING, Optional

from ..base import Channel

# 尝试导入 UI 组件
try:
    from .ui import ConsoleManager, EnhancedInput, MessageRenderer
    UI_AVAILABLE = True
except ImportError:
    ConsoleManager = None
    MessageRenderer = None
    EnhancedInput = None
    UI_AVAILABLE = False

if TYPE_CHECKING:
    from ...agent import Agent

logger = logging.getLogger("agent")


def _safe_print(*args, **kwargs) -> None:
    """安全打印，处理 Unicode 代理字符"""
    try:
        # 将所有参数转换为安全字符串
        safe_args = []
        for arg in args:
            if isinstance(arg, str):
                safe_args.append(arg.encode('utf-8', errors='replace').decode('utf-8'))
            else:
                safe_args.append(arg)
        print(*safe_args, **kwargs)
    except Exception:
        # 如果失败，尝试使用 ASCII
        safe_args = []
        for arg in args:
            if isinstance(arg, str):
                safe_args.append(arg.encode('ascii', errors='replace').decode('ascii'))
            else:
                safe_args.append(arg)
        print(*safe_args, **kwargs)


class CLIChannel(Channel):
    """CLI 交互通道

    支持富文本渲染和增强输入。
    """

    def __init__(self):
        super().__init__()
        self._console_manager: Optional[ConsoleManager] = None
        self._renderer: Optional[MessageRenderer] = None
        self._input: Optional[EnhancedInput] = None

    def _init_ui(self):
        """初始化 UI 组件"""
        if not UI_AVAILABLE:
            return

        self._console_manager = ConsoleManager()
        self._renderer = MessageRenderer(self._console_manager.console)
        self._input = EnhancedInput()

    @property
    def console(self):
        """获取 Console 管理器"""
        if self._console_manager is None:
            self._init_ui()
        return self._console_manager

    @property
    def renderer(self):
        """获取消息渲染器"""
        if self._renderer is None:
            self._init_ui()
        return self._renderer

    @property
    def input_handler(self):
        """获取输入处理器"""
        if self._input is None:
            self._init_ui()
        return self._input

    def send(self, message: str) -> None:
        """发送消息到控制台

        使用 Rich 渲染 Markdown、代码块等格式。
        """
        if self.renderer and UI_AVAILABLE:
            self.renderer.render(message)
        else:
            _safe_print(f"\nAgent: {message}")

    def receive(self) -> str:
        """从控制台接收输入"""
        if self.input_handler and UI_AVAILABLE:
            return self.input_handler.prompt("\n你: ")
        return input("\n你: ").strip()

    def _display_thinking(self, thinking: list) -> None:
        """显示思考过程"""
        if not thinking:
            return

        if self.renderer and UI_AVAILABLE:
            self.renderer.render_thinking(thinking)
        else:
            _safe_print("\n" + "=" * 40)
            _safe_print("💭 思考过程")
            _safe_print("=" * 40)
            for step in thinking:
                _safe_print(f"  {step}")
            _safe_print("=" * 40)

    def _display_welcome(self) -> None:
        """显示欢迎信息"""
        if self.renderer and UI_AVAILABLE:
            self.renderer.render_welcome("0.3.0")
        else:
            _safe_print("=" * 50)
            _safe_print("Agent 对话模式")
            _safe_print("输入 /quit 退出")
            _safe_print("输入 /reset 清空对话历史")
            _safe_print("输入 /think 切换思考过程显示")
            _safe_print("输入 /new 创建新会话")
            _safe_print("输入 /help 查看可用 Skill")
            _safe_print("=" * 50)

    def run(self, agent: "Agent") -> None:
        """运行交互式对话"""
        # 初始化 UI
        self._init_ui()

        # 显示欢迎信息
        self._display_welcome()

        show_thinking = agent._show_thinking

        # 获取当前目录
        cwd = os.getcwd()

        # 调用 Agent 获取或创建会话
        context = {'source': 'cli', 'directory': cwd}
        agent.get_or_create_session(source='cli', directory=cwd)

        # 初始化 Skill 注册表
        from ...skills import get_skill_registry
        skill_registry = get_skill_registry()

        # 设置内置 Skill 的注册表引用
        for skill in skill_registry.list_skills():
            if hasattr(skill, 'set_registry'):
                skill.set_registry(skill_registry)

        # 获取可用命令列表用于补全
        command_names = [s.name for s in skill_registry.list_skills()]
        command_names.extend(["quit", "exit", "reset", "think", "new", "help"])

        if self.input_handler and UI_AVAILABLE:
            self.input_handler.update_commands(command_names)

        while True:
            try:
                user_input = self.receive()

                if not user_input:
                    continue

                # 先处理内置指令（/quit, /exit 等）
                cmd = user_input.strip().lower()
                if cmd in ["/quit", "/exit", "quit", "exit"]:
                    if self.console and UI_AVAILABLE:
                        self.console.print_success("再见!")
                    else:
                        _safe_print("再见!")
                    break

                # 检查是否是 Skill 命令（不包括 /quit 和 /exit）
                if user_input.strip().startswith("/"):
                    # 解析 Skill 命令
                    from ...skills.parser import SkillCommandParser
                    parsed = SkillCommandParser.parse(user_input)

                    if parsed:
                        skill_name, args = parsed
                        # 创建 Skill 上下文
                        from ...skills.base import SkillContext
                        skill_context = SkillContext(
                            source="cli",
                            directory=cwd,
                            session_id=agent.session_id,
                        )

                        # 执行 Skill
                        import asyncio
                        result = asyncio.run(skill_registry.execute(skill_name, args, skill_context))

                        if result.success:
                            self.send(result.message)
                        else:
                            if self.console and UI_AVAILABLE:
                                self.console.print_error(result.message)
                            else:
                                _safe_print(f"\n错误: {result.message}")

                        continue

                # 统一指令处理（使用 Agent 的 process_command）
                response = agent.process_command(user_input, context)
                if response:
                    if self.console and UI_AVAILABLE:
                        self.console.print(response)
                    else:
                        _safe_print(response)
                    continue

                # 使用 process_with_thinking 获取思考过程
                if show_thinking:
                    result = agent.process_with_thinking(user_input)
                    thinking = result.get("thinking", [])
                    response = result.get("response", "")
                    self._display_thinking(thinking)
                    self.send(response)
                else:
                    response = agent.process(user_input)
                    self.send(response)

                # 保存会话信息（目录映射）
                if agent.memory:
                    agent.memory.save(**context)

            except KeyboardInterrupt:
                if self.console and UI_AVAILABLE:
                    self.console.print_warning("\n\n退出对话")
                else:
                    _safe_print("\n\n退出对话")
                break
            except Exception as e:
                # 安全处理错误消息中的 Unicode 字符
                error_msg = str(e).encode('utf-8', errors='replace').decode('utf-8')
                logger.error(f"对话错误: {error_msg}")
                if self.console and UI_AVAILABLE:
                    self.console.print_error(f"发生错误: {error_msg}")
                else:
                    _safe_print(f"发生错误: {error_msg}")
