import time
import asyncio
import datetime

# from .message_storage import MongoDBMessageStorage
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat

# from ...config.config import global_config
from typing import Dict, Any, Optional
from src.chat.message_receive.message import Message
from .pfc_types import ConversationState
from .pfc import ChatObserver, GoalAnalyzer
from .message_sender import DirectMessageSender
from src.common.logger import get_logger
from .action_planner import ActionPlanner
from .observation_info import ObservationInfo
from .conversation_info import ConversationInfo  # 确保导入 ConversationInfo
from .reply_generator import ReplyGenerator
from src.chat.message_receive.chat_stream import ChatStream
from src.chat.message_receive.message import UserInfo
from src.chat.message_receive.chat_stream import get_chat_manager
from .pfc_KnowledgeFetcher import KnowledgeFetcher
from .waiter import Waiter

import traceback
from rich.traceback import install

install(extra_lines=3)

logger = get_logger("pfc")


class Conversation:
    """对话类，负责管理单个对话的状态和行为"""

    def __init__(self, stream_id: str, private_name: str):
        """初始化对话实例

        Args:
            stream_id: 聊天流ID
        """
        self.stream_id = stream_id
        self.private_name = private_name
        self.state = ConversationState.INIT
        self.should_continue = False
        self.ignore_until_timestamp: Optional[float] = None

        # 回复相关
        self.generated_reply = ""

    async def _initialize(self):
        """初始化实例，注册所有组件"""

        try:
            self.action_planner = ActionPlanner(self.stream_id, self.private_name)
            self.goal_analyzer = GoalAnalyzer(self.stream_id, self.private_name)
            self.reply_generator = ReplyGenerator(self.stream_id, self.private_name)
            self.knowledge_fetcher = KnowledgeFetcher(self.private_name)
            self.waiter = Waiter(self.stream_id, self.private_name)
            self.direct_sender = DirectMessageSender(self.private_name)

            # 获取聊天流信息
            self.chat_stream = get_chat_manager().get_stream(self.stream_id)

            self.stop_action_planner = False
        except Exception as e:
            logger.error(f"[私聊][{self.private_name}]初始化对话实例：注册运行组件失败: {e}")
            logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}")
            raise

        try:
            # 决策所需要的信息，包括自身自信和观察信息两部分
            # 注册观察器和观测信息
            self.chat_observer = ChatObserver.get_instance(self.stream_id, self.private_name)
            self.chat_observer.start()
            self.observation_info = ObservationInfo(self.private_name)
            self.observation_info.bind_to_chat_observer(self.chat_observer)
            # print(self.chat_observer.get_cached_messages(limit=)

            self.conversation_info = ConversationInfo()
        except Exception as e:
            logger.error(f"[私聊][{self.private_name}]初始化对话实例：注册信息组件失败: {e}")
            logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}")
            raise
        try:
            logger.info(f"[私聊][{self.private_name}]为 {self.stream_id} 加载初始聊天记录...")
            initial_messages = get_raw_msg_before_timestamp_with_chat(  #
                chat_id=self.stream_id,
                timestamp=time.time(),
                limit=30,  # 加载最近30条作为初始上下文，可以调整
            )
            chat_talking_prompt = build_readable_messages(
                initial_messages,
                replace_bot_name=True,
                merge_messages=False,
                timestamp_mode="relative",
                read_mark=0.0,
            )
            if initial_messages:
                # 将加载的消息填充到 ObservationInfo 的 chat_history
                self.observation_info.chat_history = initial_messages
                self.observation_info.chat_history_str = chat_talking_prompt + "\n"
                self.observation_info.chat_history_count = len(initial_messages)

                # 更新 ObservationInfo 中的时间戳等信息
                last_msg = initial_messages[-1]
                self.observation_info.last_message_time = last_msg.get("time")
                last_user_info = UserInfo.from_dict(last_msg.get("user_info", {}))
                self.observation_info.last_message_sender = last_user_info.user_id
                self.observation_info.last_message_content = last_msg.get("processed_plain_text", "")

                logger.info(
                    f"[私聊][{self.private_name}]成功加载 {len(initial_messages)} 条初始聊天记录。最后一条消息时间: {self.observation_info.last_message_time}"
                )

                # 让 ChatObserver 从加载的最后一条消息之后开始同步
                self.chat_observer.last_message_time = self.observation_info.last_message_time
                self.chat_observer.last_message_read = last_msg  # 更新 observer 的最后读取记录
            else:
                logger.info(f"[私聊][{self.private_name}]没有找到初始聊天记录。")

        except Exception as load_err:
            logger.error(f"[私聊][{self.private_name}]加载初始聊天记录时出错: {load_err}")
            # 出错也要继续，只是没有历史记录而已
        # 组件准备完成，启动该论对话
        self.should_continue = True
        asyncio.create_task(self.start())

    async def start(self):
        """开始对话流程"""
        try:
            logger.info(f"[私聊][{self.private_name}]对话系统启动中...")
            asyncio.create_task(self._plan_and_action_loop())
        except Exception as e:
            logger.error(f"[私聊][{self.private_name}]启动对话系统失败: {e}")
            raise

    async def _plan_and_action_loop(self):
        """思考步，PFC核心循环模块"""
        while self.should_continue:
            # 忽略逻辑
            if self.ignore_until_timestamp and time.time() < self.ignore_until_timestamp:
                await asyncio.sleep(30)
                continue
            elif self.ignore_until_timestamp and time.time() >= self.ignore_until_timestamp:
                logger.info(f"[私聊][{self.private_name}]忽略时间已到 {self.stream_id}，准备结束对话。")
                self.ignore_until_timestamp = None
                self.should_continue = False
                continue
            try:
                # --- 在规划前记录当前新消息数量 ---
                initial_new_message_count = 0
                if hasattr(self.observation_info, "new_messages_count"):
                    initial_new_message_count = self.observation_info.new_messages_count + 1  # 算上麦麦自己发的那一条
                else:
                    logger.warning(
                        f"[私聊][{self.private_name}]ObservationInfo missing 'new_messages_count' before planning."
                    )

                # --- 调用 Action Planner ---
                # 传递 self.conversation_info.last_successful_reply_action
                action, reason = await self.action_planner.plan(
                    self.observation_info, self.conversation_info, self.conversation_info.last_successful_reply_action
                )

                # --- 规划后检查是否有 *更多* 新消息到达 ---
                current_new_message_count = 0
                if hasattr(self.observation_info, "new_messages_count"):
                    current_new_message_count = self.observation_info.new_messages_count
                else:
                    logger.warning(
                        f"[私聊][{self.private_name}]ObservationInfo missing 'new_messages_count' after planning."
                    )

                if current_new_message_count > initial_new_message_count + 2:
                    logger.info(
                        f"[私聊][{self.private_name}]规划期间发现新增消息 ({initial_new_message_count} -> {current_new_message_count})，跳过本次行动，重新规划"
                    )
                    # 如果规划期间有新消息，也应该重置上次回复状态，因为现在要响应新消息了
                    self.conversation_info.last_successful_reply_action = None
                    await asyncio.sleep(0.1)
                    continue

                #  包含 send_new_message
                if initial_new_message_count > 0 and action in ["direct_reply", "send_new_message"]:
                    if hasattr(self.observation_info, "clear_unprocessed_messages"):
                        logger.debug(
                            f"[私聊][{self.private_name}]准备执行 {action}，清理 {initial_new_message_count} 条规划时已知的新消息。"
                        )
                        await self.observation_info.clear_unprocessed_messages()
                        if hasattr(self.observation_info, "new_messages_count"):
                            self.observation_info.new_messages_count = 0
                    else:
                        logger.error(
                            f"[私聊][{self.private_name}]无法清理未处理消息: ObservationInfo 缺少 clear_unprocessed_messages 方法！"
                        )

                await self._handle_action(action, reason, self.observation_info, self.conversation_info)

                # 检查是否需要结束对话 (逻辑不变)
                goal_ended = False
                if hasattr(self.conversation_info, "goal_list") and self.conversation_info.goal_list:
                    for goal_item in self.conversation_info.goal_list:
                        if isinstance(goal_item, dict):
                            current_goal = goal_item.get("goal")

                        if current_goal == "结束对话":
                            goal_ended = True
                            break

                if goal_ended:
                    self.should_continue = False
                    logger.info(f"[私聊][{self.private_name}]检测到'结束对话'目标，停止循环。")

            except Exception as loop_err:
                logger.error(f"[私聊][{self.private_name}]PFC主循环出错: {loop_err}")
                logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}")
                await asyncio.sleep(1)

            if self.should_continue:
                await asyncio.sleep(0.1)

        logger.info(f"[私聊][{self.private_name}]PFC 循环结束 for stream_id: {self.stream_id}")

    def _check_new_messages_after_planning(self):
        """检查在规划后是否有新消息"""
        # 检查 ObservationInfo 是否已初始化并且有 new_messages_count 属性
        if not hasattr(self, "observation_info") or not hasattr(self.observation_info, "new_messages_count"):
            logger.warning(
                f"[私聊][{self.private_name}]ObservationInfo 未初始化或缺少 'new_messages_count' 属性，无法检查新消息。"
            )
            return False  # 或者根据需要抛出错误

        if self.observation_info.new_messages_count > 2:
            logger.info(
                f"[私聊][{self.private_name}]生成/执行动作期间收到 {self.observation_info.new_messages_count} 条新消息，取消当前动作并重新规划"
            )
            # 如果有新消息，也应该重置上次回复状态
            if hasattr(self, "conversation_info"):  # 确保 conversation_info 已初始化
                self.conversation_info.last_successful_reply_action = None
            else:
                logger.warning(
                    f"[私聊][{self.private_name}]ConversationInfo 未初始化，无法重置 last_successful_reply_action。"
                )
            return True
        return False

    def _convert_to_message(self, msg_dict: Dict[str, Any]) -> Message:
        """将消息字典转换为Message对象"""
        try:
            # 尝试从 msg_dict 直接获取 chat_stream，如果失败则从全局 get_chat_manager 获取
            chat_info = msg_dict.get("chat_info")
            if chat_info and isinstance(chat_info, dict):
                chat_stream = ChatStream.from_dict(chat_info)
            elif self.chat_stream:  # 使用实例变量中的 chat_stream
                chat_stream = self.chat_stream
            else:  # Fallback: 尝试从 manager 获取 (可能需要 stream_id)
                chat_stream = get_chat_manager().get_stream(self.stream_id)
                if not chat_stream:
                    raise ValueError(f"无法确定 ChatStream for stream_id {self.stream_id}")

            user_info = UserInfo.from_dict(msg_dict.get("user_info", {}))

            return Message(
                message_id=msg_dict.get("message_id", f"gen_{time.time()}"),  # 提供默认 ID
                chat_stream=chat_stream,  # 使用确定的 chat_stream
                time=msg_dict.get("time", time.time()),  # 提供默认时间
                user_info=user_info,
                processed_plain_text=msg_dict.get("processed_plain_text", ""),
                detailed_plain_text=msg_dict.get("detailed_plain_text", ""),
            )
        except Exception as e:
            logger.warning(f"[私聊][{self.private_name}]转换消息时出错: {e}")
            # 可以选择返回 None 或重新抛出异常，这里选择重新抛出以指示问题
            raise ValueError(f"无法将字典转换为 Message 对象: {e}") from e

    async def _handle_action(
        self, action: str, reason: str, observation_info: ObservationInfo, conversation_info: ConversationInfo
    ):
        """处理规划的行动"""

        logger.debug(f"[私聊][{self.private_name}]执行行动: {action}, 原因: {reason}")

        # 记录action历史 (逻辑不变)
        current_action_record = {
            "action": action,
            "plan_reason": reason,
            "status": "start",
            "time": datetime.datetime.now().strftime("%H:%M:%S"),
            "final_reason": None,
        }
        # 确保 done_action 列表存在
        if not hasattr(conversation_info, "done_action"):
            conversation_info.done_action = []
        conversation_info.done_action.append(current_action_record)
        action_index = len(conversation_info.done_action) - 1

        action_successful = False  # 用于标记动作是否成功完成

        # --- 根据不同的 action 执行 ---

        # send_new_message 失败后执行 wait
        if action == "send_new_message":
            max_reply_attempts = 3
            reply_attempt_count = 0
            is_suitable = False
            need_replan = False
            check_reason = "未进行尝试"
            final_reply_to_send = ""

            while reply_attempt_count < max_reply_attempts and not is_suitable:
                reply_attempt_count += 1
                logger.info(
                    f"[私聊][{self.private_name}]尝试生成追问回复 (第 {reply_attempt_count}/{max_reply_attempts} 次)..."
                )
                self.state = ConversationState.GENERATING

                # 1. 生成回复 (调用 generate 时传入 action_type)
                self.generated_reply = await self.reply_generator.generate(
                    observation_info, conversation_info, action_type="send_new_message"
                )
                logger.info(
                    f"[私聊][{self.private_name}]第 {reply_attempt_count} 次生成的追问回复: {self.generated_reply}"
                )

                # 2. 检查回复 (逻辑不变)
                self.state = ConversationState.CHECKING
                try:
                    current_goal_str = conversation_info.goal_list[0]["goal"] if conversation_info.goal_list else ""
                    is_suitable, check_reason, need_replan = await self.reply_generator.check_reply(
                        reply=self.generated_reply,
                        goal=current_goal_str,
                        chat_history=observation_info.chat_history,
                        chat_history_str=observation_info.chat_history_str,
                        retry_count=reply_attempt_count - 1,
                    )
                    logger.info(
                        f"[私聊][{self.private_name}]第 {reply_attempt_count} 次追问检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}"
                    )
                    if is_suitable:
                        final_reply_to_send = self.generated_reply
                        break
                    elif need_replan:
                        logger.warning(
                            f"[私聊][{self.private_name}]第 {reply_attempt_count} 次追问检查建议重新规划，停止尝试。原因: {check_reason}"
                        )
                        break
                except Exception as check_err:
                    logger.error(
                        f"[私聊][{self.private_name}]第 {reply_attempt_count} 次调用 ReplyChecker (追问) 时出错: {check_err}"
                    )
                    check_reason = f"第 {reply_attempt_count} 次检查过程出错: {check_err}"
                    break

            # 循环结束，处理最终结果
            if is_suitable:
                # 检查是否有新消息
                if self._check_new_messages_after_planning():
                    logger.info(f"[私聊][{self.private_name}]生成追问回复期间收到新消息，取消发送，重新规划行动")
                    conversation_info.done_action[action_index].update(
                        {"status": "recall", "final_reason": f"有新消息，取消发送追问: {final_reply_to_send}"}
                    )
                    return  # 直接返回，重新规划

                # 发送合适的回复
                self.generated_reply = final_reply_to_send
                # --- 在这里调用 _send_reply ---
                await self._send_reply()  # <--- 调用恢复后的函数

                # 更新状态: 标记上次成功是 send_new_message
                self.conversation_info.last_successful_reply_action = "send_new_message"
                action_successful = True  # 标记动作成功

            elif need_replan:
                # 打回动作决策
                logger.warning(
                    f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试，追问回复决定打回动作决策。打回原因: {check_reason}"
                )
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"追问尝试{reply_attempt_count}次后打回: {check_reason}"}
                )

            else:
                # 追问失败
                logger.warning(
                    f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试，未能生成合适的追问回复。最终原因: {check_reason}"
                )
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"追问尝试{reply_attempt_count}次后失败: {check_reason}"}
                )
                # 重置状态: 追问失败，下次用初始 prompt
                self.conversation_info.last_successful_reply_action = None

                # 执行 Wait 操作
                logger.info(f"[私聊][{self.private_name}]由于无法生成合适追问回复，执行 'wait' 操作...")
                self.state = ConversationState.WAITING
                await self.waiter.wait(self.conversation_info)
                wait_action_record = {
                    "action": "wait",
                    "plan_reason": "因 send_new_message 多次尝试失败而执行的后备等待",
                    "status": "done",
                    "time": datetime.datetime.now().strftime("%H:%M:%S"),
                    "final_reason": None,
                }
                conversation_info.done_action.append(wait_action_record)

        elif action == "direct_reply":
            max_reply_attempts = 3
            reply_attempt_count = 0
            is_suitable = False
            need_replan = False
            check_reason = "未进行尝试"
            final_reply_to_send = ""

            while reply_attempt_count < max_reply_attempts and not is_suitable:
                reply_attempt_count += 1
                logger.info(
                    f"[私聊][{self.private_name}]尝试生成首次回复 (第 {reply_attempt_count}/{max_reply_attempts} 次)..."
                )
                self.state = ConversationState.GENERATING

                # 1. 生成回复
                self.generated_reply = await self.reply_generator.generate(
                    observation_info, conversation_info, action_type="direct_reply"
                )
                logger.info(
                    f"[私聊][{self.private_name}]第 {reply_attempt_count} 次生成的首次回复: {self.generated_reply}"
                )

                # 2. 检查回复
                self.state = ConversationState.CHECKING
                try:
                    current_goal_str = conversation_info.goal_list[0]["goal"] if conversation_info.goal_list else ""
                    is_suitable, check_reason, need_replan = await self.reply_generator.check_reply(
                        reply=self.generated_reply,
                        goal=current_goal_str,
                        chat_history=observation_info.chat_history,
                        chat_history_str=observation_info.chat_history_str,
                        retry_count=reply_attempt_count - 1,
                    )
                    logger.info(
                        f"[私聊][{self.private_name}]第 {reply_attempt_count} 次首次回复检查结果: 合适={is_suitable}, 原因='{check_reason}', 需重新规划={need_replan}"
                    )
                    if is_suitable:
                        final_reply_to_send = self.generated_reply
                        break
                    elif need_replan:
                        logger.warning(
                            f"[私聊][{self.private_name}]第 {reply_attempt_count} 次首次回复检查建议重新规划，停止尝试。原因: {check_reason}"
                        )
                        break
                except Exception as check_err:
                    logger.error(
                        f"[私聊][{self.private_name}]第 {reply_attempt_count} 次调用 ReplyChecker (首次回复) 时出错: {check_err}"
                    )
                    check_reason = f"第 {reply_attempt_count} 次检查过程出错: {check_err}"
                    break

            # 循环结束，处理最终结果
            if is_suitable:
                # 检查是否有新消息
                if self._check_new_messages_after_planning():
                    logger.info(f"[私聊][{self.private_name}]生成首次回复期间收到新消息，取消发送，重新规划行动")
                    conversation_info.done_action[action_index].update(
                        {"status": "recall", "final_reason": f"有新消息，取消发送首次回复: {final_reply_to_send}"}
                    )
                    return  # 直接返回，重新规划

                # 发送合适的回复
                self.generated_reply = final_reply_to_send
                # --- 在这里调用 _send_reply ---
                await self._send_reply()  # <--- 调用恢复后的函数

                # 更新状态: 标记上次成功是 direct_reply
                self.conversation_info.last_successful_reply_action = "direct_reply"
                action_successful = True  # 标记动作成功

            elif need_replan:
                # 打回动作决策
                logger.warning(
                    f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试，首次回复决定打回动作决策。打回原因: {check_reason}"
                )
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"首次回复尝试{reply_attempt_count}次后打回: {check_reason}"}
                )

            else:
                # 首次回复失败
                logger.warning(
                    f"[私聊][{self.private_name}]经过 {reply_attempt_count} 次尝试，未能生成合适的首次回复。最终原因: {check_reason}"
                )
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"首次回复尝试{reply_attempt_count}次后失败: {check_reason}"}
                )
                # 重置状态: 首次回复失败，下次还是用初始 prompt
                self.conversation_info.last_successful_reply_action = None

                # 执行 Wait 操作 (保持原有逻辑)
                logger.info(f"[私聊][{self.private_name}]由于无法生成合适首次回复，执行 'wait' 操作...")
                self.state = ConversationState.WAITING
                await self.waiter.wait(self.conversation_info)
                wait_action_record = {
                    "action": "wait",
                    "plan_reason": "因 direct_reply 多次尝试失败而执行的后备等待",
                    "status": "done",
                    "time": datetime.datetime.now().strftime("%H:%M:%S"),
                    "final_reason": None,
                }
                conversation_info.done_action.append(wait_action_record)

        elif action == "fetch_knowledge":
            self.state = ConversationState.FETCHING
            knowledge_query = reason
            try:
                # 检查 knowledge_fetcher 是否存在
                if not hasattr(self, "knowledge_fetcher"):
                    logger.error(f"[私聊][{self.private_name}]KnowledgeFetcher 未初始化，无法获取知识。")
                    raise AttributeError("KnowledgeFetcher not initialized")

                knowledge, source = await self.knowledge_fetcher.fetch(knowledge_query, observation_info.chat_history)
                logger.info(f"[私聊][{self.private_name}]获取到知识: {knowledge[:100]}..., 来源: {source}")
                if knowledge:
                    # 确保 knowledge_list 存在
                    if not hasattr(conversation_info, "knowledge_list"):
                        conversation_info.knowledge_list = []
                    conversation_info.knowledge_list.append(
                        {"query": knowledge_query, "knowledge": knowledge, "source": source}
                    )
                action_successful = True
            except Exception as fetch_err:
                logger.error(f"[私聊][{self.private_name}]获取知识时出错: {str(fetch_err)}")
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"获取知识失败: {str(fetch_err)}"}
                )
                self.conversation_info.last_successful_reply_action = None  # 重置状态

        elif action == "rethink_goal":
            self.state = ConversationState.RETHINKING
            try:
                # 检查 goal_analyzer 是否存在
                if not hasattr(self, "goal_analyzer"):
                    logger.error(f"[私聊][{self.private_name}]GoalAnalyzer 未初始化，无法重新思考目标。")
                    raise AttributeError("GoalAnalyzer not initialized")
                await self.goal_analyzer.analyze_goal(conversation_info, observation_info)
                action_successful = True
            except Exception as rethink_err:
                logger.error(f"[私聊][{self.private_name}]重新思考目标时出错: {rethink_err}")
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"重新思考目标失败: {rethink_err}"}
                )
                self.conversation_info.last_successful_reply_action = None  # 重置状态

        elif action == "listening":
            self.state = ConversationState.LISTENING
            logger.info(f"[私聊][{self.private_name}]倾听对方发言...")
            try:
                # 检查 waiter 是否存在
                if not hasattr(self, "waiter"):
                    logger.error(f"[私聊][{self.private_name}]Waiter 未初始化，无法倾听。")
                    raise AttributeError("Waiter not initialized")
                await self.waiter.wait_listening(conversation_info)
                action_successful = True  # Listening 完成就算成功
            except Exception as listen_err:
                logger.error(f"[私聊][{self.private_name}]倾听时出错: {listen_err}")
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"倾听失败: {listen_err}"}
                )
                self.conversation_info.last_successful_reply_action = None  # 重置状态

        elif action == "say_goodbye":
            self.state = ConversationState.GENERATING  # 也可以定义一个新的状态，如 ENDING
            logger.info(f"[私聊][{self.private_name}]执行行动: 生成并发送告别语...")
            try:
                # 1. 生成告别语 (使用 'say_goodbye' action_type)
                self.generated_reply = await self.reply_generator.generate(
                    observation_info, conversation_info, action_type="say_goodbye"
                )
                logger.info(f"[私聊][{self.private_name}]生成的告别语: {self.generated_reply}")

                # 2. 直接发送告别语 (不经过检查)
                if self.generated_reply:  # 确保生成了内容
                    await self._send_reply()  # 调用发送方法
                    # 发送成功后，标记动作成功
                    action_successful = True
                    logger.info(f"[私聊][{self.private_name}]告别语已发送。")
                else:
                    logger.warning(f"[私聊][{self.private_name}]未能生成告别语内容，无法发送。")
                    action_successful = False  # 标记动作失败
                    conversation_info.done_action[action_index].update(
                        {"status": "recall", "final_reason": "未能生成告别语内容"}
                    )

                # 3. 无论是否发送成功，都准备结束对话
                self.should_continue = False
                logger.info(f"[私聊][{self.private_name}]发送告别语流程结束，即将停止对话实例。")

            except Exception as goodbye_err:
                logger.error(f"[私聊][{self.private_name}]生成或发送告别语时出错: {goodbye_err}")
                logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}")
                # 即使出错，也结束对话
                self.should_continue = False
                action_successful = False  # 标记动作失败
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"生成或发送告别语时出错: {goodbye_err}"}
                )

        elif action == "end_conversation":
            # 这个分支现在只会在 action_planner 最终决定不告别时被调用
            self.should_continue = False
            logger.info(f"[私聊][{self.private_name}]收到最终结束指令，停止对话...")
            action_successful = True  # 标记这个指令本身是成功的

        elif action == "block_and_ignore":
            logger.info(f"[私聊][{self.private_name}]不想再理你了...")
            ignore_duration_seconds = 10 * 60
            self.ignore_until_timestamp = time.time() + ignore_duration_seconds
            logger.info(
                f"[私聊][{self.private_name}]将忽略此对话直到: {datetime.datetime.fromtimestamp(self.ignore_until_timestamp)}"
            )
            self.state = ConversationState.IGNORED
            action_successful = True  # 标记动作成功

        else:  # 对应 'wait' 动作
            self.state = ConversationState.WAITING
            logger.info(f"[私聊][{self.private_name}]等待更多信息...")
            try:
                # 检查 waiter 是否存在
                if not hasattr(self, "waiter"):
                    logger.error(f"[私聊][{self.private_name}]Waiter 未初始化，无法等待。")
                    raise AttributeError("Waiter not initialized")
                _timeout_occurred = await self.waiter.wait(self.conversation_info)
                action_successful = True  # Wait 完成就算成功
            except Exception as wait_err:
                logger.error(f"[私聊][{self.private_name}]等待时出错: {wait_err}")
                conversation_info.done_action[action_index].update(
                    {"status": "recall", "final_reason": f"等待失败: {wait_err}"}
                )
                self.conversation_info.last_successful_reply_action = None  # 重置状态

        # --- 更新 Action History 状态 ---
        # 只有当动作本身成功时，才更新状态为 done
        if action_successful:
            conversation_info.done_action[action_index].update(
                {
                    "status": "done",
                    "time": datetime.datetime.now().strftime("%H:%M:%S"),
                }
            )
            # 重置状态: 对于非回复类动作的成功，清除上次回复状态
            if action not in ["direct_reply", "send_new_message"]:
                self.conversation_info.last_successful_reply_action = None
                logger.debug(f"[私聊][{self.private_name}]动作 {action} 成功完成，重置 last_successful_reply_action")
        # 如果动作是 recall 状态，在各自的处理逻辑中已经更新了 done_action

    async def _send_reply(self):
        """发送回复"""
        if not self.generated_reply:
            logger.warning(f"[私聊][{self.private_name}]没有生成回复内容，无法发送。")
            return

        try:
            _current_time = time.time()
            reply_content = self.generated_reply

            # 发送消息 (确保 direct_sender 和 chat_stream 有效)
            if not hasattr(self, "direct_sender") or not self.direct_sender:
                logger.error(f"[私聊][{self.private_name}]DirectMessageSender 未初始化，无法发送回复。")
                return
            if not self.chat_stream:
                logger.error(f"[私聊][{self.private_name}]ChatStream 未初始化，无法发送回复。")
                return

            await self.direct_sender.send_message(chat_stream=self.chat_stream, content=reply_content)

            # 发送成功后，手动触发 observer 更新可能导致重复处理自己发送的消息
            # 更好的做法是依赖 observer 的自动轮询或数据库触发器（如果支持）
            # 暂时注释掉，观察是否影响 ObservationInfo 的更新
            # self.chat_observer.trigger_update()
            # if not await self.chat_observer.wait_for_update():
            #     logger.warning(f"[私聊][{self.private_name}]等待 ChatObserver 更新完成超时")

            self.state = ConversationState.ANALYZING  # 更新状态

        except Exception as e:
            logger.error(f"[私聊][{self.private_name}]发送消息或更新状态时失败: {str(e)}")
            logger.error(f"[私聊][{self.private_name}]{traceback.format_exc()}")
            self.state = ConversationState.ANALYZING

    async def _send_timeout_message(self):
        """发送超时结束消息"""
        try:
            messages = self.chat_observer.get_cached_messages(limit=1)
            if not messages:
                return

            latest_message = self._convert_to_message(messages[0])
            await self.direct_sender.send_message(
                chat_stream=self.chat_stream, content="TODO:超时消息", reply_to_message=latest_message
            )
        except Exception as e:
            logger.error(f"[私聊][{self.private_name}]发送超时消息失败: {str(e)}")
