import asyncio
import datetime
from typing import Dict, Any
from ..chat.message import Message
from .pfc_types import ConversationState
from .pfc import ChatObserver, GoalAnalyzer, Waiter, DirectMessageSender
from src.common.logger import get_module_logger
from .action_planner import ActionPlanner
from .observation_info import ObservationInfo
from .conversation_info import ConversationInfo
from .reply_generator import ReplyGenerator
from ..chat.chat_stream import ChatStream
from ..message.message_base import UserInfo
from src.plugins.chat.chat_stream import chat_manager
from .pfc_KnowledgeFetcher import KnowledgeFetcher
import traceback

logger = get_module_logger("pfc_conversation")


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

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

        Args:
            stream_id: 聊天流ID
        """
        self.stream_id = stream_id
        self.state = ConversationState.INIT
        self.should_continue = False

        # 回复相关
        self.generated_reply = ""

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

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

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

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

        try:
            # 决策所需要的信息，包括自身自信和观察信息两部分
            # 注册观察器和观测信息
            self.chat_observer = ChatObserver.get_instance(self.stream_id)
            self.chat_observer.start()
            self.observation_info = ObservationInfo()
            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"初始化对话实例：注册信息组件失败: {e}")
            logger.error(traceback.format_exc())
            raise

        # 组件准备完成，启动该论对话
        self.should_continue = True
        asyncio.create_task(self.start())

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

    async def _plan_and_action_loop(self):
        """思考步，PFC核心循环模块"""
        # 获取最近的消息历史
        while self.should_continue:
            # 使用决策信息来辅助行动规划
            action, reason = await self.action_planner.plan(self.observation_info, self.conversation_info)
            if self._check_new_messages_after_planning():
                continue

            # 执行行动
            await self._handle_action(action, reason, self.observation_info, self.conversation_info)

    def _check_new_messages_after_planning(self):
        """检查在规划后是否有新消息"""
        if self.observation_info.new_messages_count > 0:
            logger.info(f"发现{self.observation_info.new_messages_count}条新消息，可能需要重新考虑行动")
            # 如果需要，可以在这里添加逻辑来根据新消息重新决定行动
            return True
        return False

    def _convert_to_message(self, msg_dict: Dict[str, Any]) -> Message:
        """将消息字典转换为Message对象"""
        try:
            chat_info = msg_dict.get("chat_info", {})
            chat_stream = ChatStream.from_dict(chat_info)
            user_info = UserInfo.from_dict(msg_dict.get("user_info", {}))

            return Message(
                message_id=msg_dict["message_id"],
                chat_stream=chat_stream,
                time=msg_dict["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"转换消息时出错: {e}")
            raise

    async def _handle_action(
        self, action: str, reason: str, observation_info: ObservationInfo, conversation_info: ConversationInfo
    ):
        """处理规划的行动"""
        logger.info(f"执行行动: {action}, 原因: {reason}")

        # 记录action历史，先设置为stop，完成后再设置为done
        conversation_info.done_action.append(
            {
                "action": action,
                "reason": reason,
                "status": "start",
                "time": datetime.datetime.now().strftime("%H:%M:%S"),
            }
        )

        if action == "direct_reply":
            self.state = ConversationState.GENERATING
            self.generated_reply = await self.reply_generator.generate(observation_info, conversation_info)
            print(f"生成回复: {self.generated_reply}")

            # # 检查回复是否合适
            # is_suitable, reason, need_replan = await self.reply_generator.check_reply(
            #     self.generated_reply,
            #     self.current_goal
            # )

            if self._check_new_messages_after_planning():
                logger.info("333333发现新消息，重新考虑行动")
                return None

            await self._send_reply()

            conversation_info.done_action.append(
                {
                    "action": action,
                    "reason": reason,
                    "status": "done",
                    "time": datetime.datetime.now().strftime("%H:%M:%S"),
                }
            )

        elif action == "fetch_knowledge":
            self.state = ConversationState.FETCHING
            knowledge = "TODO:知识"
            topic = "TODO:关键词"

            logger.info(f"假装获取到知识{knowledge}，关键词是: {topic}")

            if knowledge:
                if topic not in self.conversation_info.knowledge_list:
                    self.conversation_info.knowledge_list.append({"topic": topic, "knowledge": knowledge})
                else:
                    self.conversation_info.knowledge_list[topic] += knowledge

        elif action == "rethink_goal":
            self.state = ConversationState.RETHINKING
            await self.goal_analyzer.analyze_goal(conversation_info, observation_info)

        elif action == "listening":
            self.state = ConversationState.LISTENING
            logger.info("倾听对方发言...")
            if await self.waiter.wait():  # 如果返回True表示超时
                await self._send_timeout_message()
                await self._stop_conversation()

        else:  # wait
            self.state = ConversationState.WAITING
            logger.info("等待更多信息...")
            if await self.waiter.wait():  # 如果返回True表示超时
                await self._send_timeout_message()
                await self._stop_conversation()

    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"发送超时消息失败: {str(e)}")

    async def _send_reply(self):
        """发送回复"""
        if not self.generated_reply:
            logger.warning("没有生成回复")
            return

        try:
            await self.direct_sender.send_message(
                chat_stream=self.chat_stream, content=self.generated_reply
            )
            self.chat_observer.trigger_update()  # 触发立即更新
            if not await self.chat_observer.wait_for_update():
                logger.warning("等待消息更新超时")

            self.state = ConversationState.ANALYZING
        except Exception as e:
            logger.error(f"发送消息失败: {str(e)}")
            self.state = ConversationState.ANALYZING
