#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
search_kb_advice.py
综合查询处置建议：
1. 从数据库 tb_battery_fault_strategy 获取基础策略
2. 从本地知识库全文检索详细预案
"""

import argparse
import json
import os
import urllib.request

DB_API_URL = "http://47.97.121.32:8080/VOLERTECH/app/api/oauth/getmysql"
DB_JDBC    = "snowy_cloud_mysql_copy"

KB_DIRS = {
    "personal": "/home/admin/.openclaw/workspace-agent-200/Document/PersonalDocuments",
    "public":   "/home/admin/.openclaw/workspace-agent-200/Document/PublicDocuments",
}
TEXT_EXTENSIONS = {".md", ".txt"}

def execute_sql(sql: str) -> list:
    payload = json.dumps({"basejdbc": DB_JDBC, "sql": sql}).encode("utf-8")
    req = urllib.request.Request(DB_API_URL, data=payload, headers={"Content-Type": "application/json"}, method="POST")
    try:
        with urllib.request.urlopen(req, timeout=10) as resp:
            result = json.loads(resp.read().decode("utf-8"))
            if isinstance(result, list): return result
            if isinstance(result, dict):
                for key in ("data", "rows", "result", "records"):
                    if key in result and isinstance(result[key], list): return result[key]
            return []
    except Exception:
        return []

def get_db_strategy(fault_code: str) -> str:
    if not fault_code: return ""
    rows = execute_sql(f"SELECT action_advice FROM tb_battery_fault_strategy WHERE fault_code = '{fault_code}' LIMIT 1")
    if rows and rows[0].get("action_advice"):
        return rows[0]["action_advice"]
    return ""

def build_rel_path(abs_path: str) -> str:
    marker = "workspace-agent-200"
    idx = abs_path.find(marker)
    if idx != -1: return abs_path[idx + len(marker):]
    return abs_path

def search_kb(keyword: str) -> list:
    if not keyword: return []
    keywords = [k.lower() for k in keyword.strip().split() if k.strip()]
    matches = []
    
    for kb_type, kb_dir in KB_DIRS.items():
        if not os.path.isdir(kb_dir): continue
        for root, _, files in os.walk(kb_dir):
            for fname in files:
                ext = os.path.splitext(fname)[1].lower()
                abs_path = os.path.join(root, fname)
                
                if ext not in TEXT_EXTENSIONS:
                    if any(k in fname.lower() for k in keywords):
                        matches.append({"file": build_rel_path(abs_path), "snippets": [], "note": "非纯文本文件，建议原生工具读取"})
                    continue
                
                try:
                    with open(abs_path, "r", encoding="utf-8") as f:
                        content = f.read()
                        content_lower = content.lower()
                        if all(k in content_lower for k in keywords):
                            idx = content_lower.find(keywords[0])
                            start = max(0, idx - 150)
                            end = min(len(content), idx + 300)
                            snippet = content[start:end].strip().replace("\n", " ")
                            matches.append({"file": build_rel_path(abs_path), "snippets": [snippet]})
                except Exception:
                    pass
    return matches

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--fault_code", default="", help="故障代码，如 CELL_OV")
    parser.add_argument("--keyword", default="", help="知识库搜索关键词，如 '电芯过压 P1154'")
    args = parser.parse_args()

    db_advice = get_db_strategy(args.fault_code)
    kb_matches = search_kb(args.keyword)

    result = {
        "status": "success",
        "fault_code": args.fault_code,
        "keyword": args.keyword,
        "db_strategy_advice": db_advice or "无内置策略",
        "kb_matches": kb_matches,
        "hint": "请综合上述建议向用户汇报。若引用了知识库文件，请务必在末尾追加 &%%& 来源标记。"
    }
    print(json.dumps(result, ensure_ascii=False, indent=2))

if __name__ == "__main__":
    main()
