"""
故障类型统计工具模块
用于统计故障诊断智能体记录的故障信息
数据来源：PostgreSQL fault_records 表
"""
import os
import re
import json
import httpx
from datetime import datetime, timedelta
from typing import Dict, Any, Optional, List
from difflib import SequenceMatcher
import asyncio

from langchain_core.tools import tool
from utils.function_tracker import track_function_calls
from config import REPAIR_FEEDBACK_CONFIG

neo4j_cache = {}


def fuzzy_match_system(user_input: str, system_name: str, threshold: float = 0.6) -> bool:
    if not user_input or not system_name:
        return False

    user_input = user_input.strip().lower()
    system_name = system_name.strip().lower()

    if user_input == system_name:
        return True

    if user_input in system_name or system_name in user_input:
        return True

    similarity = SequenceMatcher(None, user_input, system_name).ratio()

    return similarity >= threshold


async def get_device_system_from_neo4j(device_name: str) -> str:
    """
    从 Neo4j 图谱中查询设备对应的系统（调用外部接口），带缓存机制
    """
    if not device_name or not device_name.strip():
        return "其他"

    device_name_clean = device_name.strip().lower()

    if device_name_clean in neo4j_cache:
        return neo4j_cache[device_name_clean]

    try:
        from tools.graph_tools import find_system_by_device

        result_json = await find_system_by_device(
            device_name=device_name.strip(),
            min_hops=2,
            max_hops=8,
            top_k=10,
        )

        if not result_json.get("success", False):
            result = "其他"
            neo4j_cache[device_name_clean] = result
            return result

        systems = result_json.get("systems", [])
        if not systems or not isinstance(systems, list):
            result = "其他"
            neo4j_cache[device_name_clean] = result
            return result

        first_system = systems[0]
        if isinstance(first_system, dict):
            system_name = first_system.get("name") or first_system.get("系统名称") or first_system.get("名称")
            if system_name:
                result = system_name.strip()
                neo4j_cache[device_name_clean] = result
                return result

        result = "其他"
        neo4j_cache[device_name_clean] = result
        return result

    except Exception as e:
        print(f"查询设备系统失败: {str(e)}")
        result = "其他"
        neo4j_cache[device_name_clean] = result
        return result


def generate_color_palette(n: int) -> List[str]:
    predefined_colors = [
        "#00C2FF", "#4E7CFE", "#9153FF", "#FFB800", "#00D16B",
        "#FF6B6B", "#4ECDC4", "#45B7D1", "#FFA07A", "#98D8C8",
        "#F7DC6F", "#BB8FCE", "#85C1E9", "#F8B500", "#00E676",
        "#FF4081", "#7C4DFF", "#18FFFF", "#69F0AE", "#FFD740"
    ]

    if n <= len(predefined_colors):
        return predefined_colors[:n]

    colors = predefined_colors.copy()

    import colorsys
    for i in range(len(predefined_colors), n):
        hue = (i * 0.618033988749895) % 1.0
        saturation = 0.7 + (i % 3) * 0.1
        value = 0.8 + (i % 2) * 0.1

        rgb = colorsys.hsv_to_rgb(hue, saturation, value)
        color = "#{:02X}{:02X}{:02X}".format(
            int(rgb[0] * 255),
            int(rgb[1] * 255),
            int(rgb[2] * 255)
        )
        colors.append(color)

    return colors


async def _query_fault_records_from_db(
    ship_number: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    system_name: Optional[str] = None,
    limit: int = 5000
) -> List[Dict[str, Any]]:
    """
    从数据库查询故障记录（内部共用方法）
    """
    from tools.fault_record_db import query_fault_records
    return await query_fault_records(
        ship_number=ship_number,
        system_name=system_name,
        start_date=start_date,
        end_date=end_date,
        limit=limit
    )


async def statistics_fault_types(
    ship_number_filter: Optional[str] = None
) -> Dict[str, Any]:
    """
    统计故障类型（从数据库读取），按系统分类计算百分比

    Args:
        ship_number_filter: 舷号过滤（可选）

    Returns:
        包含统计结果的字典
    """
    try:
        records = await _query_fault_records_from_db(ship_number=ship_number_filter)

        if not records:
            return {
                "success": True,
                "faultTypeData": []
            }

        system_totals = {}
        valid_count = 0

        for record in records:
            system_name = record.get("system_name", "其他")
            if not system_name:
                system_name = "其他"
            valid_count += 1

            if system_name not in system_totals:
                system_totals[system_name] = 0
            system_totals[system_name] += 1

        fault_type_data = []
        if valid_count > 0:
            unique_systems = sorted(system_totals.keys())
            colors = generate_color_palette(len(unique_systems))
            system_color_map = {system: color for system, color in zip(unique_systems, colors)}

            for system_name, count in system_totals.items():
                percentage = round((count / valid_count) * 100)
                color = system_color_map.get(system_name, "#6E7D91")
                fault_type_data.append({
                    "value": percentage,
                    "name": system_name,
                    "itemStyle": {
                        "color": color
                    }
                })

        fault_type_data.sort(key=lambda x: x["value"], reverse=True)

        return {
            "success": True,
            "faultTypeData": fault_type_data
        }

    except Exception as e:
        print(f"[故障类型统计错误] {str(e)}")
        import traceback
        traceback.print_exc()
        return {
            "success": False,
            "faultTypeData": []
        }


@tool
async def fault_type_statistics_tool(
    ship_number_filter: Optional[str] = None
) -> Dict[str, Any]:
    """
    故障类型统计工具（供工作流调用）
    统计故障类型，按系统分类并计算百分比

    Args:
        ship_number_filter: 舷号过滤（可选）

    Returns:
        统计结果，包含 success 和 faultTypeData 字段
    """
    result = await statistics_fault_types(ship_number_filter=ship_number_filter)
    return result


async def merge_similar_faults_with_embedding(
    fault_counter: Dict[str, int],
    fault_system_map: Dict[str, str],
    similarity_threshold: float = 0.85
) -> tuple:
    """
    使用embedding合并相似的故障
    """
    if not fault_counter:
        return {}, {}, {}

    fault_keys = list(fault_counter.keys())

    if len(fault_keys) <= 1:
        return fault_counter.copy(), fault_system_map.copy(), {}

    try:
        from modelsAPI.model_api import OpenaiAPI

        embeddings = await OpenaiAPI.get_embeddings_batch_async(fault_keys)

        fault_embedding_map = {key: emb for key, emb in zip(fault_keys, embeddings)}

        merged_counter = {}
        merged_system_map = {}
        merge_mapping = {}
        merged_keys = set()

        sorted_faults = sorted(fault_counter.items(), key=lambda x: x[1], reverse=True)

        for fault_key, count in sorted_faults:
            if fault_key in merged_keys:
                continue

            merged_keys.add(fault_key)
            merged_counter[fault_key] = count
            merged_system_map[fault_key] = fault_system_map.get(fault_key, "其他")

            for other_key, other_count in sorted_faults:
                if other_key in merged_keys or other_key == fault_key:
                    continue

                if fault_embedding_map.get(fault_key) and fault_embedding_map.get(other_key):
                    similarity = OpenaiAPI.cosine_similarity(
                        fault_embedding_map[fault_key],
                        fault_embedding_map[other_key]
                    )

                    if similarity >= similarity_threshold:
                        merged_counter[fault_key] += other_count
                        merged_keys.add(other_key)
                        merge_mapping[other_key] = fault_key

        return merged_counter, merged_system_map, merge_mapping

    except Exception as e:
        print(f"Embedding合并失败，使用原始数据: {str(e)}")
        return fault_counter.copy(), fault_system_map.copy(), {}


async def statistics_fault_frequency(
    top_n: int = 10,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    system_filter: Optional[str] = None,
    use_embedding_merge: bool = True,
    similarity_threshold: float = 0.85
) -> Dict[str, Any]:
    """
    统计故障发生次数（从数据库读取），按频率排序
    统计所有故障的数据，但只返回top N展示在表格中

    Args:
        top_n: 返回前 N 个高频故障（默认为 10）
        start_date: 开始日期（格式：YYYY-MM-DD，可选）
        end_date: 结束日期（格式：YYYY-MM-DD，可选）
        system_filter: 系统名称过滤（可选）
        use_embedding_merge: 是否使用embedding合并相似故障（默认True）
        similarity_threshold: 相似度阈值（默认0.85）

    Returns:
        包含统计结果的字典
    """
    try:
        records = await _query_fault_records_from_db(
            start_date=start_date,
            end_date=end_date
        )

        if not records:
            return {
                "success": True,
                "totalCount": 0,
                "totalTypes": 0,
                "highFreqFaults": []
            }

        fault_counter = {}
        fault_system_map = {}

        for record in records:
            device_name = record.get("device_name", "")
            fault = record.get("fault", "")
            system_name = record.get("system_name", "其他")

            if not device_name or not fault:
                continue

            if system_filter and not fuzzy_match_system(system_filter, system_name):
                continue

            fault_key = f"{device_name}{fault}"

            if fault_key not in fault_counter:
                fault_counter[fault_key] = 0
                fault_system_map[fault_key] = system_name

            fault_counter[fault_key] += 1

        if use_embedding_merge and len(fault_counter) > 1:
            fault_counter, fault_system_map, merge_mapping = await merge_similar_faults_with_embedding(
                fault_counter,
                fault_system_map,
                similarity_threshold
            )

            if merge_mapping:
                print(f"合并了 {len(merge_mapping)} 个相似故障")

        # 先计算全部数据的统计量
        total_count = sum(fault_counter.values())
        total_types = len(fault_counter)
        
        # 对全部数据排序
        sorted_faults_all = sorted(fault_counter.items(), key=lambda x: x[1], reverse=True)
        
        # 只取top N用于展示表格
        sorted_faults = sorted_faults_all[:top_n]

        high_freq_faults = []
        for rank, (fault_key, count) in enumerate(sorted_faults, start=1):
            system_name = fault_system_map.get(fault_key, "其他")

            high_freq_faults.append({
                "rank": rank,
                "name": fault_key,
                "system": system_name,
                "count": count
            })

        return {
            "success": True,
            "totalCount": total_count,
            "totalTypes": total_types,
            "highFreqFaults": high_freq_faults
        }

    except Exception as e:
        print(f"[故障频率统计错误] {str(e)}")
        import traceback
        traceback.print_exc()
        return {
            "success": False,
            "highFreqFaults": []
        }


@tool
async def fault_frequency_statistics_tool(
    top_n: Optional[int] = 6,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    system_filter: Optional[str] = None
) -> Dict[str, Any]:
    """
    故障发生次数统计工具（供工作流调用）
    统计故障发生次数，按频率排序

    Args:
        top_n: 返回前 N 个高频故障（默认为 6）
        start_date: 开始日期（格式：YYYY-MM-DD，可选）
        end_date: 结束日期（格式：YYYY-MM-DD，可选）
        system_filter: 系统名称过滤（可选）

    Returns:
        统计结果，包含 success 和 highFreqFaults 字段
    """
    result = await statistics_fault_frequency(
        top_n=top_n or 10,
        start_date=start_date,
        end_date=end_date,
        system_filter=system_filter
    )

    return result


async def statistics_spare_parts(
    ship_number_filter: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    top_n: int = 6
) -> Dict[str, Any]:
    """
    统计备件消耗（从数据库读取）
    统计所有备件的数据，但只返回top N展示在表格中

    Args:
        ship_number_filter: 舷号过滤（可选）
        start_date: 开始日期（格式：YYYY-MM-DD，可选）
        end_date: 结束日期（格式：YYYY-MM-DD，可选）
        top_n: 表格中展示的前 N 个备件（默认为 5）

    Returns:
        包含统计结果的字典
    """
    try:
        records = await _query_fault_records_from_db(
            ship_number=ship_number_filter,
            start_date=start_date,
            end_date=end_date
        )

        if not records:
            return {
                "success": True,
                "totalCount": 0,
                "totalTypes": 0,
                "sparePartData": {
                    "categories": [],
                    "system": [],
                    "counter": []
                }
            }

        spare_part_counter = {}
        spare_part_system_map = {}

        for record in records:
            spare_parts = record.get("spare_parts", [])
            system_name = record.get("system_name", "其他")

            if not spare_parts:
                continue

            for part in spare_parts:
                if not part or not part.strip():
                    continue

                part_key = part.strip()

                if part_key not in spare_part_counter:
                    spare_part_counter[part_key] = 0
                    spare_part_system_map[part_key] = system_name

                spare_part_counter[part_key] += 1

        # 先计算全部数据的统计量
        total_count = sum(spare_part_counter.values())
        total_types = len(spare_part_counter)
        
        # 对全部数据排序
        sorted_parts_all = sorted(spare_part_counter.items(), key=lambda x: x[1], reverse=True)
        
        # 只取top N用于展示表格
        sorted_parts = sorted_parts_all[:top_n]

        categories = []
        systems = []
        counters = []

        for part_key, count in sorted_parts:
            categories.append(part_key)
            systems.append(spare_part_system_map.get(part_key, "其他"))
            counters.append(count)

        return {
            "success": True,
            "totalCount": total_count,
            "totalTypes": total_types,
            "sparePartData": {
                "categories": categories,
                "system": systems,
                "counter": counters
            }
        }

    except Exception as e:
        print(f"[备件统计错误] {str(e)}")
        import traceback
        traceback.print_exc()
        return {
            "success": False,
            "sparePartData": {
                "categories": [],
                "system": [],
                "counter": []
            }
        }


@tool
async def spare_parts_statistics_tool(
    ship_number: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    top_n: Optional[int] = 5
) -> Dict[str, Any]:
    """
    备件消耗统计工具（供工作流调用）
    统计备件消耗情况

    Args:
        ship_number: 舷号过滤（可选）
        start_date: 开始日期（格式：YYYY-MM-DD，可选）
        end_date: 结束日期（格式：YYYY-MM-DD，可选）
        top_n: 返回前 N 个备件（默认为 5）

    Returns:
        统计结果，包含 success 和 sparePartData 字段
    """
    result = await statistics_spare_parts(
        ship_number_filter=ship_number,
        start_date=start_date,
        end_date=end_date,
        top_n=top_n or 5
    )

    return result


async def extract_device_from_text(text: str) -> Optional[str]:
    """
    从文本中提取设备名称（使用大模型）
    """
    if not text or not text.strip():
        return None

    prompt = f"""从以下文本中提取设备名称：

文本内容：
{text}

请识别文本中提到的具体设备名称，如：发动机、压缩机、水泵、发电机、空调机组、液压泵等。

请以JSON格式返回：
{{"device": "设备名称"}}

如果文本中没有提到任何设备，请返回 {{"device": null}}
只返回JSON，不要有其他内容。"""

    try:
        from modelsAPI.model_api import OpenaiAPI
        result_text = await OpenaiAPI.open_api_chat_without_thinking(
            query=prompt,
            json_output=True
        )

        result_text = result_text.strip()
        result_text = re.sub(r'^```json\s*', '', result_text, flags=re.IGNORECASE)
        result_text = re.sub(r'^```\s*', '', result_text)
        result_text = re.sub(r'```$', '', result_text)

        json_match = re.search(r'\{.*\}', result_text, re.DOTALL)
        if json_match:
            result = json.loads(json_match.group(0))
            device = result.get("device")
            if device and device != "null":
                return str(device).strip()

        return None

    except Exception as e:
        print(f"大模型提取设备名称失败: {str(e)}")
        return None


async def classify_feedback_content(text: str) -> str:
    """
    对反馈内容进行分类（使用大模型）
    """
    if not text or not text.strip():
        return "其他"

    prompt = f"""请对以下反馈内容进行分类。

反馈内容：
{text}

分类类别（单选，选择最匹配的一个）：
1. 信息过时 - 反映文档或手册中的信息已经过时，不再适用
2. 步骤错误 - 反映操作步骤或流程存在错误
3. 步骤缺失 - 反映缺少必要的操作步骤或流程说明
4. 备件信息有误 - 反映备件型号、规格、数量等信息有误
5. 安全提示不足 - 反映缺少必要的安全警示或注意事项
6. 图示不清 - 反映图片、示意图不清晰或难以理解

请分析反馈内容，判断属于哪个类别，以JSON格式返回：
{{"category": "类别名称"}}

如果反馈内容不属于以上任何类别，请返回 {{"category": "其他"}}
只返回JSON，不要有其他内容。"""

    try:
        from modelsAPI.model_api import OpenaiAPI
        result_text = await OpenaiAPI.open_api_chat_without_thinking(
            query=prompt,
            json_output=True
        )

        result_text = result_text.strip()
        result_text = re.sub(r'^```json\s*', '', result_text, flags=re.IGNORECASE)
        result_text = re.sub(r'^```\s*', '', result_text)
        result_text = re.sub(r'```$', '', result_text)

        json_match = re.search(r'\{.*\}', result_text, re.DOTALL)
        if json_match:
            result = json.loads(json_match.group(0))
            category = result.get("category")
            valid_categories = ["信息过时", "步骤错误", "步骤缺失", "备件信息有误", "安全提示不足", "图示不清", "其他"]
            if category in valid_categories:
                return category

        return "其他"

    except Exception as e:
        print(f"大模型分类反馈内容失败: {str(e)}")
        return "其他"


async def analyze_feedback_and_classify(feedback_text: str) -> Dict[str, Any]:
    """
    分析反馈内容并分类（主接口）
    """
    if not feedback_text or not feedback_text.strip():
        return {
            "success": False,
            "device": None,
            "system": None,
            "category": "其他",
            "error": "反馈内容为空"
        }

    try:
        device = await extract_device_from_text(feedback_text)

        system = "其他"
        if device:
            system = await get_device_system_from_neo4j(device)

        category = await classify_feedback_content(feedback_text)

        return {
            "success": True,
            "system": system,
            "category": category
        }

    except Exception as e:
        return {
            "success": False,
            "system": None,
            "category": "其他",
            "error": str(e)
        }


_feedback_token_cache = {"token": None, "expires_at": 0}


async def _get_feedback_api_token() -> Optional[str]:
    """
    获取维修反馈API的认证token（带缓存，避免每次请求都认证）
    """
    import time

    if _feedback_token_cache["token"] and time.time() < _feedback_token_cache["expires_at"]:
        return _feedback_token_cache["token"]

    base_url = REPAIR_FEEDBACK_CONFIG["url"]
    email = REPAIR_FEEDBACK_CONFIG.get("email", "")
    password = REPAIR_FEEDBACK_CONFIG.get("password", "")

    if not email or not password:
        print("[维修反馈认证错误] 未配置认证凭据")
        return None

    try:
        async with httpx.AsyncClient(timeout=30.0) as client:
            signin_resp = await client.post(
                f"{base_url}/api/v1/auths/signin",
                json={"email": email, "password": password}
            )

            if signin_resp.status_code != 200:
                print(f"[维修反馈认证错误] 登录失败，状态码: {signin_resp.status_code}")
                return None

            token = signin_resp.json().get("token", "")
            if not token:
                print("[维修反馈认证错误] 响应中未找到token")
                return None

            _feedback_token_cache["token"] = token
            _feedback_token_cache["expires_at"] = time.time() + 3600

            return token

    except Exception as e:
        print(f"[维修反馈认证错误] {str(e)}")
        return None


async def statistics_repair_feedbacks(
    source: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    top_n: int = 10
) -> Dict[str, Any]:
    """
    统计维修反馈数据（从外部API获取，带认证）

    Args:
        source: 来源筛选（好评/差评/反馈），可选
        start_date: 开始日期（格式：YYYY-MM-DD），可选
        end_date: 结束日期（格式：YYYY-MM-DD），可选
        top_n: 返回前 N 条记录（默认为 10）

    Returns:
        包含统计结果的字典
    """
    try:
        token = await _get_feedback_api_token()
        if not token:
            return {
                "success": False,
                "totalCount": 0,
                "feedbackData": [],
                "error": "API认证失败，无法获取token"
            }

        base_url = REPAIR_FEEDBACK_CONFIG["url"]
        endpoint = f"{base_url}/api/v1/repair-feedbacks/"

        params = {}
        if source and source.strip():
            params["source"] = source.strip()

        async with httpx.AsyncClient(timeout=30.0) as client:
            response = await client.get(
                endpoint,
                params=params,
                headers={
                    "Accept": "application/json",
                    "Content-Type": "application/json",
                    "Authorization": f"Bearer {token}"
                }
            )

            if response.status_code == 401 or response.status_code == 403:
                _feedback_token_cache["token"] = None
                _feedback_token_cache["expires_at"] = 0

                token = await _get_feedback_api_token()
                if token:
                    response = await client.get(
                        endpoint,
                        params=params,
                        headers={
                            "Accept": "application/json",
                            "Content-Type": "application/json",
                            "Authorization": f"Bearer {token}"
                        }
                    )

            if response.status_code != 200:
                print(f"[维修反馈统计错误] API返回状态码: {response.status_code}")
                return {
                    "success": False,
                    "totalCount": 0,
                    "feedbackData": [],
                    "error": f"API请求失败，状态码: {response.status_code}"
                }

            result_json = response.json()

            if isinstance(result_json, list):
                feedback_list = result_json
            elif isinstance(result_json, dict):
                feedback_list = result_json.get("results", result_json.get("data", []))
            else:
                feedback_list = []

            if not feedback_list:
                return {
                    "success": True,
                    "totalCount": 0,
                    "totalTypes": 0,
                    "feedbackData": [],
                    "sourceDistribution": {}
                }

            start_dt = None
            end_dt = None
            if start_date:
                try:
                    start_dt = datetime.strptime(start_date, "%Y-%m-%d")
                except ValueError:
                    pass
            if end_date:
                try:
                    end_dt = datetime.strptime(end_date, "%Y-%m-%d") + timedelta(days=1) - timedelta(seconds=1)
                except ValueError:
                    pass

            if start_dt or end_dt:
                filtered_list = []
                for item in feedback_list:
                    if not isinstance(item, dict):
                        continue
                    raw_created_at = item.get("created_at", "")
                    if not raw_created_at:
                        continue
                    try:
                        item_dt = datetime.fromtimestamp(int(raw_created_at))
                        if start_dt and item_dt < start_dt:
                            continue
                        if end_dt and item_dt > end_dt:
                            continue
                        filtered_list.append(item)
                    except (ValueError, TypeError, OSError):
                        continue
                feedback_list = filtered_list

            total_count = len(feedback_list)

            processed_data = []
            for idx, item in enumerate(feedback_list[:top_n], start=1):
                if isinstance(item, dict):
                    raw_title = item.get("title", "")
                    raw_content = item.get("content", "")
                    raw_source = item.get("source", source or "")
                    raw_created_at = item.get("created_at", "")
                    raw_user_name = item.get("user_name", "")

                    created_at_str = ""
                    if raw_created_at:
                        try:
                            ts = int(raw_created_at)
                            created_at_str = datetime.fromtimestamp(ts).strftime("%Y-%m-%d %H:%M")
                        except (ValueError, TypeError, OSError):
                            created_at_str = str(raw_created_at)

                    processed_item = {
                        "rank": idx,
                        "title": str(raw_title) if raw_title else "",
                        "content": str(raw_content)[:200] if raw_content else "",
                        "source": str(raw_source) if raw_source else "未知",
                        "created_at": created_at_str,
                        "user_name": str(raw_user_name) if raw_user_name else ""
                    }
                    processed_data.append(processed_item)

            source_counter = {}
            for item in processed_data:
                s = item.get("source", "未知")
                source_counter[s] = source_counter.get(s, 0) + 1

            return {
                "success": True,
                "totalCount": total_count,
                "totalTypes": len(feedback_list),
                "sourceDistribution": source_counter,
                "feedbackData": processed_data
            }

    except Exception as e:
        print(f"[维修反馈统计错误] {str(e)}")
        import traceback
        traceback.print_exc()
        return {
            "success": False,
            "totalCount": 0,
            "feedbackData": [],
            "error": str(e)
        }


@tool
async def repair_feedback_statistics_tool(
    source: Optional[str] = None,
    start_date: Optional[str] = None,
    end_date: Optional[str] = None,
    top_n: Optional[int] = 10
) -> Dict[str, Any]:
    """
    维修反馈统计工具（供工作流调用）
    统计维修反馈情况，支持按来源和时间筛选

    Args:
        source: 来源筛选（可选），如：好评、差评、反馈
        start_date: 开始日期（格式：YYYY-MM-DD），可选
        end_date: 结束日期（格式：YYYY-MM-DD），可选
        top_n: 返回前 N 条记录（默认为 10）

    Returns:
        统计结果，包含 success 和 feedbackData 字段
    """
    result = await statistics_repair_feedbacks(
        source=source,
        start_date=start_date,
        end_date=end_date,
        top_n=top_n or 10
    )

    return result
