"""
根据person_name查询用户信息 - 工具实现
支持模糊查询，可以查询某个用户的所有信息
"""

import json
from datetime import datetime
from src.common.logger import get_logger
from src.common.database.database_model import PersonInfo
from .tool_registry import register_memory_retrieval_tool

logger = get_logger("memory_retrieval_tools")


def _calculate_similarity(query: str, target: str) -> float:
    """计算查询词在目标字符串中的相似度比例

    Args:
        query: 查询词
        target: 目标字符串

    Returns:
        float: 相似度比例（0.0-1.0），查询词长度 / 目标字符串长度
    """
    if not query or not target:
        return 0.0
    query_len = len(query)
    target_len = len(target)
    if target_len == 0:
        return 0.0
    return query_len / target_len


def _format_group_nick_names(group_nick_name_field) -> str:
    """格式化群昵称信息

    Args:
        group_nick_name_field: 群昵称字段（可能是字符串JSON或None）

    Returns:
        str: 格式化后的群昵称信息字符串
    """
    if not group_nick_name_field:
        return ""

    try:
        # 解析JSON格式的群昵称列表
        group_nick_names_data = (
            json.loads(group_nick_name_field) if isinstance(group_nick_name_field, str) else group_nick_name_field
        )

        if not isinstance(group_nick_names_data, list) or not group_nick_names_data:
            return ""

        # 格式化群昵称列表
        group_nick_list = []
        for item in group_nick_names_data:
            if isinstance(item, dict):
                group_id = item.get("group_id", "未知群号")
                group_nick_name = item.get("group_nick_name", "未知群昵称")
                group_nick_list.append(f"  - 群号 {group_id}：{group_nick_name}")
            elif isinstance(item, str):
                # 兼容旧格式（如果存在）
                group_nick_list.append(f"  - {item}")

        if group_nick_list:
            return "群昵称：\n" + "\n".join(group_nick_list)
        return ""
    except (json.JSONDecodeError, TypeError, ValueError) as e:
        logger.warning(f"解析群昵称信息失败: {e}")
        # 如果解析失败，尝试显示原始内容（截断）
        if isinstance(group_nick_name_field, str):
            preview = group_nick_name_field[:200]
            if len(group_nick_name_field) > 200:
                preview += "..."
            return f"群昵称（原始数据）：{preview}"
        return ""


async def query_person_info(person_name: str) -> str:
    """根据person_name查询用户信息，使用模糊查询

    Args:
        person_name: 用户名称（person_name字段）

    Returns:
        str: 查询结果，包含用户的所有信息
    """
    try:
        person_name = str(person_name).strip()
        if not person_name:
            return "用户名称为空"

        # 构建查询条件（使用模糊查询）
        query = PersonInfo.select().where(PersonInfo.person_name.contains(person_name))

        # 执行查询
        records = list(query.limit(20))  # 最多返回20条记录

        if not records:
            return f"未找到模糊匹配'{person_name}'的用户信息"

        # 根据相似度过滤结果：查询词在目标字符串中至少占50%
        SIMILARITY_THRESHOLD = 0.5
        filtered_records = []
        for record in records:
            if not record.person_name:
                continue
            # 精确匹配总是保留（相似度100%）
            if record.person_name.strip() == person_name:
                filtered_records.append(record)
            else:
                # 模糊匹配需要检查相似度
                similarity = _calculate_similarity(person_name, record.person_name.strip())
                if similarity >= SIMILARITY_THRESHOLD:
                    filtered_records.append(record)

        if not filtered_records:
            return f"未找到相似度≥50%的匹配'{person_name}'的用户信息"

        # 区分精确匹配和模糊匹配的结果
        exact_matches = []
        fuzzy_matches = []

        for record in filtered_records:
            # 检查是否是精确匹配
            if record.person_name and record.person_name.strip() == person_name:
                exact_matches.append(record)
            else:
                fuzzy_matches.append(record)

        # 构建结果文本
        results = []

        # 先处理精确匹配的结果
        for record in exact_matches:
            result_parts = []
            result_parts.append("【精确匹配】")  # 标注为精确匹配

            # 基本信息
            if record.person_name:
                result_parts.append(f"用户名称：{record.person_name}")
            if record.nickname:
                result_parts.append(f"昵称：{record.nickname}")
            if record.person_id:
                result_parts.append(f"用户ID：{record.person_id}")
            if record.platform:
                result_parts.append(f"平台：{record.platform}")
            if record.user_id:
                result_parts.append(f"平台用户ID：{record.user_id}")

            # 群昵称信息
            group_nick_name_str = _format_group_nick_names(getattr(record, "group_nick_name", None))
            if group_nick_name_str:
                result_parts.append(group_nick_name_str)

            # 名称设定原因
            if record.name_reason:
                result_parts.append(f"名称设定原因：{record.name_reason}")

            # 认识状态
            result_parts.append(f"是否已认识：{'是' if record.is_known else '否'}")

            # 时间信息
            if record.know_since:
                know_since_str = datetime.fromtimestamp(record.know_since).strftime("%Y-%m-%d %H:%M:%S")
                result_parts.append(f"首次认识时间：{know_since_str}")
            if record.last_know:
                last_know_str = datetime.fromtimestamp(record.last_know).strftime("%Y-%m-%d %H:%M:%S")
                result_parts.append(f"最后认识时间：{last_know_str}")
            if record.know_times:
                result_parts.append(f"认识次数：{int(record.know_times)}")

            # 记忆点（memory_points）
            if record.memory_points:
                try:
                    memory_points_data = (
                        json.loads(record.memory_points)
                        if isinstance(record.memory_points, str)
                        else record.memory_points
                    )
                    if isinstance(memory_points_data, list) and memory_points_data:
                        # 解析记忆点格式：category:content:weight
                        memory_list = []
                        for memory_point in memory_points_data:
                            if memory_point and isinstance(memory_point, str):
                                parts = memory_point.split(":", 2)
                                if len(parts) >= 3:
                                    category = parts[0].strip()
                                    content = parts[1].strip()
                                    weight = parts[2].strip()
                                    memory_list.append(f"  - [{category}] {content} (权重: {weight})")
                                else:
                                    memory_list.append(f"  - {memory_point}")

                        if memory_list:
                            result_parts.append("记忆点：\n" + "\n".join(memory_list))
                except (json.JSONDecodeError, TypeError, ValueError) as e:
                    logger.warning(f"解析用户 {record.person_id} 的memory_points失败: {e}")
                    # 如果解析失败，直接显示原始内容（截断）
                    memory_preview = str(record.memory_points)[:200]
                    if len(str(record.memory_points)) > 200:
                        memory_preview += "..."
                    result_parts.append(f"记忆点（原始数据）：{memory_preview}")

            results.append("\n".join(result_parts))

        # 再处理模糊匹配的结果
        for record in fuzzy_matches:
            result_parts = []
            result_parts.append("【模糊匹配】")  # 标注为模糊匹配

            # 基本信息
            if record.person_name:
                result_parts.append(f"用户名称：{record.person_name}")
            if record.nickname:
                result_parts.append(f"昵称：{record.nickname}")
            if record.person_id:
                result_parts.append(f"用户ID：{record.person_id}")
            if record.platform:
                result_parts.append(f"平台：{record.platform}")
            if record.user_id:
                result_parts.append(f"平台用户ID：{record.user_id}")

            # 群昵称信息
            group_nick_name_str = _format_group_nick_names(getattr(record, "group_nick_name", None))
            if group_nick_name_str:
                result_parts.append(group_nick_name_str)

            # 名称设定原因
            if record.name_reason:
                result_parts.append(f"名称设定原因：{record.name_reason}")

            # 认识状态
            result_parts.append(f"是否已认识：{'是' if record.is_known else '否'}")

            # 时间信息
            if record.know_since:
                know_since_str = datetime.fromtimestamp(record.know_since).strftime("%Y-%m-%d %H:%M:%S")
                result_parts.append(f"首次认识时间：{know_since_str}")
            if record.last_know:
                last_know_str = datetime.fromtimestamp(record.last_know).strftime("%Y-%m-%d %H:%M:%S")
                result_parts.append(f"最后认识时间：{last_know_str}")
            if record.know_times:
                result_parts.append(f"认识次数：{int(record.know_times)}")

            # 记忆点（memory_points）
            if record.memory_points:
                try:
                    memory_points_data = (
                        json.loads(record.memory_points)
                        if isinstance(record.memory_points, str)
                        else record.memory_points
                    )
                    if isinstance(memory_points_data, list) and memory_points_data:
                        # 解析记忆点格式：category:content:weight
                        memory_list = []
                        for memory_point in memory_points_data:
                            if memory_point and isinstance(memory_point, str):
                                parts = memory_point.split(":", 2)
                                if len(parts) >= 3:
                                    category = parts[0].strip()
                                    content = parts[1].strip()
                                    weight = parts[2].strip()
                                    memory_list.append(f"  - [{category}] {content} (权重: {weight})")
                                else:
                                    memory_list.append(f"  - {memory_point}")

                        if memory_list:
                            result_parts.append("记忆点：\n" + "\n".join(memory_list))
                except (json.JSONDecodeError, TypeError, ValueError) as e:
                    logger.warning(f"解析用户 {record.person_id} 的memory_points失败: {e}")
                    # 如果解析失败，直接显示原始内容（截断）
                    memory_preview = str(record.memory_points)[:200]
                    if len(str(record.memory_points)) > 200:
                        memory_preview += "..."
                    result_parts.append(f"记忆点（原始数据）：{memory_preview}")

            results.append("\n".join(result_parts))

        # 组合所有结果
        if not results:
            return f"未找到匹配'{person_name}'的用户信息"

        response_text = "\n\n---\n\n".join(results)

        # 添加统计信息
        total_count = len(filtered_records)
        exact_count = len(exact_matches)
        fuzzy_count = len(fuzzy_matches)

        # 显示精确匹配和模糊匹配的统计
        if exact_count > 0 or fuzzy_count > 0:
            stats_parts = []
            if exact_count > 0:
                stats_parts.append(f"精确匹配：{exact_count} 条")
            if fuzzy_count > 0:
                stats_parts.append(f"模糊匹配：{fuzzy_count} 条")
            stats_text = "，".join(stats_parts)
            response_text = f"找到 {total_count} 条匹配的用户信息（{stats_text}）：\n\n{response_text}"
        elif total_count > 1:
            response_text = f"找到 {total_count} 条匹配的用户信息：\n\n{response_text}"
        else:
            response_text = f"找到用户信息：\n\n{response_text}"

        # 如果结果数量达到限制，添加提示
        if total_count >= 20:
            response_text += "\n\n(已显示前20条结果，可能还有更多匹配记录)"

        return response_text

    except Exception as e:
        logger.error(f"查询用户信息失败: {e}")
        return f"查询失败: {str(e)}"


def register_tool():
    """注册工具"""
    register_memory_retrieval_tool(
        name="query_person_info",
        description="根据查询某个用户的所有信息。名称、昵称、平台、用户ID、qq号、群昵称等",
        parameters=[
            {"name": "person_name", "type": "string", "description": "用户名称，用于查询用户信息", "required": True}
        ],
        execute_func=query_person_info,
    )
