#!/usr/bin/env python3
"""wx-quote-assistant — 质检规则引擎

加载质检清单（YAML），读取报价书内容，输出结构化检查报告。
确定性检查项由脚本自动判断，LLM 辅助检查项标记待 AI 处理。

CLI 用法:
  python3 quality_checker.py check \
    --checklist <yaml_path> \
    --draft <md_path> \
    --priced <json_path> \
    --output <json_path>
"""

import argparse
import json
import os
import re
import sys


def load_yaml_checklist(path: str) -> dict:
    """加载质检清单 YAML 文件。用简单解析器处理（避免引入 PyYAML 依赖）。"""
    if not os.path.exists(path):
        return _default_checklist()

    # 简单的 YAML 解析 — 仅支持本技能的清单格式
    roles = {}
    current_role = None
    current_check = None

    with open(path, "r", encoding="utf-8") as f:
        for line in f:
            line = line.rstrip()
            if not line or line.startswith("#"):
                continue

            # Role header: "  sales_director:"
            if line.startswith("  ") and line.strip().endswith(":") and not line.strip().startswith("-"):
                key = line.strip().rstrip(":")
                if key not in ("name", "checks", "type", "id", "question"):
                    current_role = key
                    roles[current_role] = {"name": key, "checks": []}
                continue

            if current_role:
                stripped = line.strip()
                # name: 行
                if stripped.startswith("name:"):
                    roles[current_role]["name"] = stripped.split(":", 1)[1].strip()
                # check 项
                elif stripped.startswith("- id:"):
                    current_check = {"id": stripped.split(":", 1)[1].strip()}
                    roles[current_role]["checks"].append(current_check)
                elif current_check is not None and stripped.startswith("question:"):
                    current_check["question"] = stripped.split(":", 1)[1].strip()
                elif current_check is not None and stripped.startswith("type:"):
                    current_check["type"] = stripped.split(":", 1)[1].strip()

    return roles if roles else _default_checklist()


def _default_checklist() -> dict:
    """内置最小默认清单。"""
    return {
        "sales_director": {
            "name": "销售总监",
            "checks": [
                {"id": "SD-01", "question": "报价方案是否匹配客户的原始需求？", "type": "llm_assisted"},
                {"id": "SD-02", "question": "交期是否在可承诺范围内？", "type": "auto"},
            ],
        },
        "delivery_manager": {
            "name": "交付负责人",
            "checks": [
                {"id": "DM-01", "question": "交期是否合理？", "type": "auto"},
                {"id": "DM-02", "question": "产品规格描述是否准确？", "type": "auto"},
            ],
        },
        "finance_manager": {
            "name": "财务负责人",
            "checks": [
                {"id": "FM-01", "question": "单价是否在授权范围内？", "type": "auto"},
                {"id": "FM-02", "question": "税费计算是否正确？", "type": "auto"},
                {"id": "FM-03", "question": "付款条件是否合规？", "type": "auto"},
            ],
        },
    }


def auto_check(check_item: dict, draft_text: str, priced: dict) -> dict:
    """执行确定性检查。"""
    q = check_item["question"]
    status = "pass"   # ✅
    note = "自动检查通过"

    # 交期合理性检查
    if "交期" in q and ("合理" in q or "承诺" in q):
        delivery = priced.get("delivery_date", "")
        if not delivery:
            status, note = "warn", "交期尚未填写"

    # 税费计算检查
    if "税费" in q and "计算" in q:
        discounted = priced.get("discounted_total", 0)
        tax_rate = priced.get("tax_rate", 0.13)
        expected_tax = round(discounted * tax_rate, 2)
        actual_tax = priced.get("tax_amount", 0)
        if abs(expected_tax - actual_tax) > 0.02:
            status, note = "warn", f"税费可能有误：期望 {expected_tax}，实际 {actual_tax}"

    # 付款条件检查
    if "付款" in q and "合规" in q:
        payment = priced.get("payment_terms", "")
        if not payment:
            status, note = "warn", "付款条件尚未填写"

    # 单价授权检查
    if "单价" in q and "授权" in q:
        products = priced.get("products", [])
        high_price_items = [p for p in products if p.get("unit_price", 0) > 100000]
        if high_price_items:
            items_str = ", ".join(p.get("name", "?") for p in high_price_items)
            status, note = "warn", f"存在高价产品需确认授权：{items_str}"

    # 产品规格检查
    if "规格" in q and "准确" in q:
        products = priced.get("products", [])
        missing_spec = [p.get("name", "?") for p in products if not p.get("spec")]
        if missing_spec:
            status, note = "warn", f"以下产品缺少规格说明：{', '.join(missing_spec)}"

    return {"status": status, "note": note}


def run_checklist(checklist: dict, draft_text: str, priced: dict) -> dict:
    """遍历所有角色和检查项，执行检查。"""
    results = {}

    for role_key, role_data in checklist.items():
        role_results = []
        for check_item in role_data.get("checks", []):
            check_type = check_item.get("type", "auto")

            if check_type == "auto":
                result = auto_check(check_item, draft_text, priced)
            else:
                # LLM 辅助检查项：标记待 AI 处理
                result = {
                    "status": "pending_llm",
                    "note": "待 AI 辅助判断",
                }

            role_results.append({
                "id": check_item["id"],
                "question": check_item["question"],
                "type": check_type,
                "status": result["status"],
                "note": result["note"],
            })

        results[role_key] = {
            "name": role_data.get("name", role_key),
            "checks": role_results,
        }

    return results


def format_report(checks_result: dict) -> str:
    """将检查结果格式化为 Markdown 报告。"""
    lines = ["# 质检报告", "", f"**AI 辅助生成，请人工复核**", ""]

    for role_key, role_data in checks_result.items():
        lines.append(f"## {role_data['name']}")
        lines.append("")
        lines.append("| ID | 检查项 | 结果 | 说明 |")
        lines.append("|-----|--------|------|------|")

        for c in role_data["checks"]:
            status_map = {
                "pass": "✅ 符合",
                "warn": "⚠️ 建议",
                "fail": "❌ 不符合",
                "pending_llm": "❓ 待确认",
            }
            status_display = status_map.get(c["status"], c["status"])
            lines.append(f"| {c['id']} | {c['question']} | {status_display} | {c['note']} |")

        lines.append("")

    return "\n".join(lines)


def cmd_check(args) -> None:
    """执行质检。"""
    checklist = load_yaml_checklist(args.checklist)

    # 读取报价书草稿
    draft_text = ""
    if os.path.exists(args.draft):
        with open(args.draft, "r", encoding="utf-8") as f:
            draft_text = f.read()

    # 读取定价结果
    priced = {}
    if os.path.exists(args.priced):
        with open(args.priced, "r", encoding="utf-8") as f:
            priced = json.load(f)

    results = run_checklist(checklist, draft_text, priced)

    # 保存 JSON 结果
    os.makedirs(os.path.dirname(args.output) or ".", exist_ok=True)
    with open(args.output, "w", encoding="utf-8") as f:
        json.dump(results, f, ensure_ascii=False, indent=2)

    # 同时输出 Markdown 报告路径
    report_path = args.output.replace(".json", ".md")
    report = format_report(results)
    with open(report_path, "w", encoding="utf-8") as f:
        f.write(report)

    # 统计
    total = sum(len(rd["checks"]) for rd in results.values())
    auto_pass = sum(1 for rd in results.values() for c in rd["checks"] if c["status"] == "pass")
    auto_warn = sum(1 for rd in results.values() for c in rd["checks"] if c["status"] == "warn")
    llm_pending = sum(1 for rd in results.values() for c in rd["checks"] if c["status"] == "pending_llm")

    print(json.dumps({
        "ok": True,
        "output": args.output,
        "report": report_path,
        "summary": {
            "total_checks": total,
            "pass": auto_pass,
            "warn": auto_warn,
            "pending_llm": llm_pending,
        }
    }, ensure_ascii=False, indent=2))


def main():
    parser = argparse.ArgumentParser(description="wx-quote-assistant Quality Checker")
    sub = parser.add_subparsers(dest="command", required=True)

    p_check = sub.add_parser("check", help="Run quality checks")
    p_check.add_argument("--checklist", required=True, help="Quality checklist YAML file path")
    p_check.add_argument("--draft", required=True, help="Quote draft Markdown file path")
    p_check.add_argument("--priced", required=True, help="Priced result JSON file path")
    p_check.add_argument("--output", required=True, help="Output JSON path for QA results")
    p_check.set_defaults(func=cmd_check)

    args = parser.parse_args()
    args.func(args)


if __name__ == "__main__":
    main()
