from datetime import datetime
from src.config.config import global_config
import traceback
from src.chat.utils.chat_message_builder import (
    get_raw_msg_before_timestamp_with_chat,
    build_readable_messages,
    get_raw_msg_by_timestamp_with_chat,
    num_new_messages_since,
    get_person_id_list,
)
from src.chat.utils.prompt_builder import global_prompt_manager
from typing import Optional
import difflib
from src.chat.message_receive.message import MessageRecv  # 添加 MessageRecv 导入
from src.chat.heart_flow.observation.observation import Observation

from src.common.logger_manager import get_logger
from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info
from src.chat.utils.prompt_builder import Prompt


logger = get_logger("observation")


Prompt(
    """这是qq群聊的聊天记录，请总结以下聊天记录的主题：
{chat_logs}
请用一句话概括，包括人物、事件和主要信息，不要分点。""",
    "chat_summary_group_prompt",  # Template for group chat
)

Prompt(
    """这是你和{chat_target}的私聊记录，请总结以下聊天记录的主题：
{chat_logs}
请用一句话概括，包括事件，时间，和主要信息，不要分点。""",
    "chat_summary_private_prompt",  # Template for private chat
)
# --- End Prompt Template Definition ---


# 聊天观察
class ChattingObservation(Observation):
    def __init__(self, chat_id):
        super().__init__(chat_id)
        self.chat_id = chat_id
        self.platform = "qq"

        self.is_group_chat, self.chat_target_info = get_chat_type_and_target_info(self.chat_id)

        # --- Other attributes initialized in __init__ ---
        self.talking_message = []
        self.talking_message_str = ""
        self.talking_message_str_truncate = ""
        self.name = global_config.bot.nickname
        self.nick_name = global_config.bot.alias_names
        self.max_now_obs_len = global_config.focus_chat.observation_context_size
        self.overlap_len = global_config.focus_chat.compressed_length
        self.mid_memories = []
        self.max_mid_memory_len = global_config.focus_chat.compress_length_limit
        self.mid_memory_info = ""
        self.person_list = []
        self.oldest_messages = []
        self.oldest_messages_str = ""
        self.compressor_prompt = ""
        
        initial_messages = get_raw_msg_before_timestamp_with_chat(self.chat_id, self.last_observe_time, 10)
        self.last_observe_time = initial_messages[-1]["time"] if initial_messages else self.last_observe_time
        self.talking_message = initial_messages
        self.talking_message_str = build_readable_messages(self.talking_message, show_actions=True)


    def to_dict(self) -> dict:
        """将观察对象转换为可序列化的字典"""
        return {
            "chat_id": self.chat_id,
            "platform": self.platform,
            "is_group_chat": self.is_group_chat,
            "chat_target_info": self.chat_target_info,
            "talking_message_str": self.talking_message_str,
            "talking_message_str_truncate": self.talking_message_str_truncate,
            "name": self.name,
            "nick_name": self.nick_name,
            "mid_memory_info": self.mid_memory_info,
            "person_list": self.person_list,
            "oldest_messages_str": self.oldest_messages_str,
            "compressor_prompt": self.compressor_prompt,
            "last_observe_time": self.last_observe_time,
        }

    # 进行一次观察 返回观察结果observe_info
    def get_observe_info(self, ids=None):
        mid_memory_str = ""
        if ids:
            for id in ids:
                print(f"id：{id}")
                try:
                    for mid_memory in self.mid_memories:
                        if mid_memory["id"] == id:
                            mid_memory_by_id = mid_memory
                            msg_str = ""
                            for msg in mid_memory_by_id["messages"]:
                                msg_str += f"{msg['detailed_plain_text']}"
                            # time_diff = int((datetime.now().timestamp() - mid_memory_by_id["created_at"]) / 60)
                            # mid_memory_str += f"距离现在{time_diff}分钟前：\n{msg_str}\n"
                            mid_memory_str += f"{msg_str}\n"
                except Exception as e:
                    logger.error(f"获取mid_memory_id失败: {e}")
                    traceback.print_exc()
                    return self.talking_message_str

            return mid_memory_str + "现在群里正在聊：\n" + self.talking_message_str

        else:
            mid_memory_str = "之前的聊天内容：\n"
            for mid_memory in self.mid_memories:
                mid_memory_str += f"{mid_memory['theme']}\n"
            return mid_memory_str + "现在群里正在聊：\n" + self.talking_message_str

    def search_message_by_text(self, text: str) -> Optional[MessageRecv]:
        """
        根据回复的纯文本
        1. 在talking_message中查找最新的，最匹配的消息
        2. 如果找到，则返回消息
        """
        msg_list = []
        find_msg = None
        reverse_talking_message = list(reversed(self.talking_message))

        for message in reverse_talking_message:
            if message["processed_plain_text"] == text:
                find_msg = message
                # logger.debug(f"找到的锚定消息：find_msg: {find_msg}")
                break
            else:
                similarity = difflib.SequenceMatcher(None, text, message["processed_plain_text"]).ratio()
                msg_list.append({"message": message, "similarity": similarity})
            # logger.debug(f"对锚定消息检查：message: {message['processed_plain_text']},similarity: {similarity}")
        if not find_msg:
            if msg_list:
                msg_list.sort(key=lambda x: x["similarity"], reverse=True)
                if msg_list[0]["similarity"] >= 0.5:  # 只返回相似度大于等于0.5的消息
                    find_msg = msg_list[0]["message"]
                else:
                    logger.debug("没有找到锚定消息,相似度低")
                    return None
            else:
                logger.debug("没有找到锚定消息，没有消息捕获")
                return None

        # logger.debug(f"找到的锚定消息：find_msg: {find_msg}")

        # 创建所需的user_info字段
        user_info = {
            "platform": find_msg.get("user_platform", ""),
            "user_id": find_msg.get("user_id", ""),
            "user_nickname": find_msg.get("user_nickname", ""),
            "user_cardname": find_msg.get("user_cardname", ""),
        }

        # 创建所需的group_info字段，如果是群聊的话
        group_info = {}
        if find_msg.get("chat_info_group_id"):
            group_info = {
                "platform": find_msg.get("chat_info_group_platform", ""),
                "group_id": find_msg.get("chat_info_group_id", ""),
                "group_name": find_msg.get("chat_info_group_name", ""),
            }

        content_format = ""
        accept_format = ""
        template_items = {}

        format_info = {"content_format": content_format, "accept_format": accept_format}
        template_info = {
            "template_items": template_items,
        }

        message_info = {
            "platform": self.platform,
            "message_id": find_msg.get("message_id"),
            "time": find_msg.get("time"),
            "group_info": group_info,
            "user_info": user_info,
            "additional_config": find_msg.get("additional_config"),
            "format_info": format_info,
            "template_info": template_info,
        }
        message_dict = {
            "message_info": message_info,
            "raw_message": find_msg.get("processed_plain_text"),
            "detailed_plain_text": find_msg.get("processed_plain_text"),
            "processed_plain_text": find_msg.get("processed_plain_text"),
        }
        find_rec_msg = MessageRecv(message_dict)
        # logger.debug(f"锚定消息处理后：find_rec_msg: {find_rec_msg}")
        return find_rec_msg

    async def observe(self):
        # 自上一次观察的新消息
        new_messages_list = get_raw_msg_by_timestamp_with_chat(
            chat_id=self.chat_id,
            timestamp_start=self.last_observe_time,
            timestamp_end=datetime.now().timestamp(),
            limit=self.max_now_obs_len,
            limit_mode="latest",
        )

        # print(f"new_messages_list: {new_messages_list}")

        last_obs_time_mark = self.last_observe_time
        if new_messages_list:
            self.last_observe_time = new_messages_list[-1]["time"]
            self.talking_message.extend(new_messages_list)

        if len(self.talking_message) > self.max_now_obs_len:
            # 计算需要移除的消息数量，保留最新的 max_now_obs_len 条
            messages_to_remove_count = len(self.talking_message) - self.max_now_obs_len
            oldest_messages = self.talking_message[:messages_to_remove_count]
            self.talking_message = self.talking_message[messages_to_remove_count:]  # 保留后半部分，即最新的

            # print(f"压缩中：oldest_messages: {oldest_messages}")
            oldest_messages_str = build_readable_messages(
                messages=oldest_messages, timestamp_mode="normal_no_YMD", read_mark=0, show_actions=True
            )

            # --- Build prompt using template ---
            prompt = None  # Initialize prompt as None
            try:
                # 构建 Prompt - 根据 is_group_chat 选择模板
                if self.is_group_chat:
                    prompt_template_name = "chat_summary_group_prompt"
                    prompt = await global_prompt_manager.format_prompt(
                        prompt_template_name, chat_logs=oldest_messages_str
                    )
                else:
                    # For private chat, add chat_target to the prompt variables
                    prompt_template_name = "chat_summary_private_prompt"
                    # Determine the target name for the prompt
                    chat_target_name = "对方"  # Default fallback
                    if self.chat_target_info:
                        # Prioritize person_name, then nickname
                        chat_target_name = (
                            self.chat_target_info.get("person_name")
                            or self.chat_target_info.get("user_nickname")
                            or chat_target_name
                        )

                    # Format the private chat prompt
                    prompt = await global_prompt_manager.format_prompt(
                        prompt_template_name,
                        # Assuming the private prompt template uses {chat_target}
                        chat_target=chat_target_name,
                        chat_logs=oldest_messages_str,
                    )
            except Exception as e:
                logger.error(f"构建总结 Prompt 失败 for chat {self.chat_id}: {e}")
                # prompt remains None

            if prompt:  # Check if prompt was built successfully
                self.compressor_prompt = prompt
                self.oldest_messages = oldest_messages
                self.oldest_messages_str = oldest_messages_str

        # 构建中
        # print(f"构建中：self.talking_message: {self.talking_message}")
        self.talking_message_str = build_readable_messages(
            messages=self.talking_message,
            timestamp_mode="lite",
            read_mark=last_obs_time_mark,
            show_actions=True,
        )
        # print(f"构建中：self.talking_message_str: {self.talking_message_str}")
        self.talking_message_str_truncate = build_readable_messages(
            messages=self.talking_message,
            timestamp_mode="normal_no_YMD",
            read_mark=last_obs_time_mark,
            truncate=True,
            show_actions=True,
        )
        # print(f"构建中：self.talking_message_str_truncate: {self.talking_message_str_truncate}")

        self.person_list = await get_person_id_list(self.talking_message)
        # print(f"构建中：self.person_list: {self.person_list}")

        logger.trace(
            f"Chat {self.chat_id} - 压缩早期记忆：{self.mid_memory_info}\n现在聊天内容：{self.talking_message_str}"
        )

    async def has_new_messages_since(self, timestamp: float) -> bool:
        """检查指定时间戳之后是否有新消息"""
        count = num_new_messages_since(chat_id=self.chat_id, timestamp_start=timestamp)
        return count > 0
