from __future__ import annotations

import argparse
import asyncio
import json
import sys
from pathlib import Path

ROOT = Path(__file__).resolve().parents[1]
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from app.orchestrator import Orchestrator
from app.rules import detect_intent, detect_order_status, has_map_or_political_risk, requests_external_contact
from app.state_machine import evolve_after_sales_state, migrate_state_schema

CASES_PATH = ROOT / "golden" / "golden_cases.jsonl"


def heuristic_decide(msg: str, goods_order: str) -> tuple[str, str, dict]:
    m = (msg or "")
    intent = detect_intent(m)
    order_status = detect_order_status(goods_order or "")

    if has_map_or_political_risk(m) or requests_external_contact(m):
        route, action = "risk", "transfer"
    elif "退款" in m:
        route, action = "after_sales", "reply"
    elif intent == "image":
        route, action = "quote", "quote"
    elif any(k in m for k in ["多少钱", "报价", "价格", "怎么收费"]):
        route, action = "quote", "reply"
    elif order_status == "paid":
        route, action = "after_sales", "reply"
    else:
        route, action = "pre_sales", "reply"

    state = migrate_state_schema({})
    state = evolve_after_sales_state(state, route=route, action=action, intent=intent, order_status=order_status, msg=m)
    return route, action, state


async def full_decide(orch: Orchestrator, cid: str, msg: str, goods_order: str) -> tuple[str, str, dict]:
    context = {
        "customer_key": f"demo_acc:{cid}",
        "acc_id": "demo_acc",
        "customer_id": cid,
        "goods_name": "demo_goods",
        "goods_order": goods_order,
        "msg": msg,
        "pending_images": 0,
        "auto_quote_trigger": False,
        "last_reply": "",
    }
    route, decision, state = await orch.decide(context)
    return route, decision.action, state


async def main() -> int:
    parser = argparse.ArgumentParser()
    parser.add_argument("--mode", choices=["heuristic", "full"], default="heuristic")
    parser.add_argument("--cases", default=str(CASES_PATH))
    args = parser.parse_args()

    p = Path(args.cases)
    if not p.exists():
        print(f"cases not found: {p}")
        return 2

    cases = [json.loads(line) for line in p.read_text(encoding="utf-8").splitlines() if line.strip()]

    orch = Orchestrator() if args.mode == "full" else None

    passed = 0
    failed = 0
    for i, c in enumerate(cases, 1):
        cid = f"case_{i}"
        if args.mode == "full":
            route, action, state = await full_decide(orch, cid, c.get("msg", ""), c.get("goods_order", ""))
        else:
            route, action, state = heuristic_decide(c.get("msg", ""), c.get("goods_order", ""))

        ok = route == c.get("expected_route") and action == c.get("expected_action")
        if ok and c.get("expected_stage"):
            ok = state.get("after_sales_stage") == c.get("expected_stage")

        if ok:
            passed += 1
            print(f"[PASS] {c.get('id')} route={route} action={action} stage={state.get('after_sales_stage')}")
        else:
            failed += 1
            print(
                f"[FAIL] {c.get('id')} expect=({c.get('expected_route')},{c.get('expected_action')},{c.get('expected_stage','-')}) "
                f"got=({route},{action},{state.get('after_sales_stage')})"
            )

    print(f"\nSummary: passed={passed} failed={failed} total={len(cases)} mode={args.mode}")
    return 1 if failed else 0


if __name__ == "__main__":
    raise SystemExit(asyncio.run(main()))
