# 封装给外部调用的原生终端流式打印接口
import sys

def _safe_print(*args, **kwargs):
    """安全打印：处理 Windows GBK 控制台无法编码 emoji/特殊字符的问题"""
    try:
        print(*args, **kwargs)
    except UnicodeEncodeError:
        # 将无法编码的字符替换为 ?
        text = " ".join(str(a) for a in args)
        encoding = sys.stdout.encoding or 'utf-8'
        text = text.encode(encoding, errors='replace').decode(encoding)
        print(text, **{k: v for k, v in kwargs.items() if k != 'end' and k != 'flush'}, 
              end=kwargs.get('end', '\n'), flush=kwargs.get('flush', False))

def run_terminal_agent_stream(agent, task: str, thread_id: str) -> dict:
    """辅助函数：运行 agent，捕捉流式输出并在控制台打印，返回最终的执行结果
    包含完整的事件解析与用量统计
    """
    _safe_print("\n" + "=" * 60)
    _safe_print(f"[Agent 开始执行] (Thread: {thread_id})")
    _safe_print("-" * 60)
    
    result = {}
    has_printed_reasoning_header = False
    has_printed_answer_header = False
    has_streamed_reasoning = False
    has_streamed_answer = False

    try:
        for event in agent.invoke(task=task, thread_id=thread_id):
            etype = event.get("type", "")
            content = event.get("content", "")
            
            if etype == "done":
                result = event
            elif etype == "iteration":
                _safe_print(f"\n{content}")
            elif etype == "reasoning_token":
                if not has_printed_reasoning_header:
                    _safe_print("\n[思考过程]", end="\n", flush=True)
                    has_printed_reasoning_header = True
                _safe_print(content, end="", flush=True)
                has_streamed_reasoning = True
            elif etype == "token":
                if not has_printed_answer_header:
                    _safe_print("\n[回答]", end="\n", flush=True)
                    has_printed_answer_header = True
                _safe_print(content, end="", flush=True)
                has_streamed_answer = True
            elif etype == "reasoning":
                if not has_streamed_reasoning:
                    _safe_print(f"\n[思考过程]\n{content}")
            elif etype == "answer":
                if not has_streamed_answer:
                    _safe_print(f"\n[回答]\n{content}")
            elif etype == "summary":
                _safe_print(f"\n[总结]\n{content}")
            elif etype == "tool_exec":
                _safe_print(content)
            elif etype == "tool_result":
                _safe_print(f"  结果:\n{content}")
            elif etype == "tool_calls":
                _safe_print(content)
            elif etype == "token_usage":
                _safe_print(content)
            elif etype == "context_stats":
                _safe_print(content)
            elif etype == "routing":
                _safe_print(content)
            elif etype == "complete":
                _safe_print(f"\n{content}")
            elif etype == "warning":
                _safe_print(f"⚠ {content}")
            elif etype == "error":
                _safe_print(f"✗ {content}")
            elif etype == "info":
                _safe_print(content)
            else:
                pass
                
    except KeyboardInterrupt:
        _safe_print("\n\n[系统] Agent 被手动中断。")
    except Exception as e:
         _safe_print(f"\n❌ 执行发生异常: {e}")
         
    _safe_print("\n" + "-" * 60)
    _safe_print(f"[Agent 执行完毕]")
    
    # 打印统计信息
    round_tokens = result.get('total_tokens', 0)
    task_completed = result.get('task_completed', False)
    _safe_print(f"本轮 Token 消耗: {round_tokens}")
    _safe_print(f"任务是否完成: {'是' if task_completed else '否'}")
    _safe_print("=" * 60 + "\n")
    
    return result


def run_terminal_ask_stream(agent, message: str, system_prompt: str = None, thread_id: str = "default") -> str:
    """辅助函数：运行 agent.ask()，流式打印回答，返回完整回答文本"""
    has_printed_reasoning_header = False
    has_printed_answer_header = False
    full_answer = ""
    
    for event in agent.ask(message=message, system_prompt=system_prompt, thread_id=thread_id):
        etype = event.get("type", "")
        content = event.get("content", "")
        
        if etype == "reasoning_token":
            if not has_printed_reasoning_header:
                _safe_print("\n[思考]", end="\n", flush=True)
                has_printed_reasoning_header = True
            _safe_print(content, end="", flush=True)
        elif etype == "token":
            if not has_printed_answer_header:
                _safe_print("\n[回答]", end="\n", flush=True)
                has_printed_answer_header = True
            _safe_print(content, end="", flush=True)
        elif etype == "reasoning":
            if not has_printed_reasoning_header:
                _safe_print(f"\n[思考]\n{content}")
        elif etype == "answer":
            if not has_printed_answer_header:
                _safe_print(f"\n[回答]\n{content}")
        elif etype == "error":
            _safe_print(f"\n❌ {content}")
        elif etype == "done":
            full_answer = event.get("answer", "")
    
    _safe_print()
    return full_answer
