#!/usr/bin/env python
"""POD 热点抓取 Agent —— LangGraph 工程化版命令行入口。

用法示例：
  # 跑全部国家（默认 US GB JP AU）
  python cli.py

  # 只跑英国，使用 Mock 兜底 LLM
  python cli.py -c GB --provider mock

  # 跑美国并用真实 LLM（provider 在 config.llm_screen 已配好时也可不传）
  python cli.py -c US

  # 提供平铺衣服底图，把设计印上去（需 config.compose.backend + api_key）
  python cli.py -c US --base path/to/flatlay.png

产物按国家落在 output/<country>/（design_briefs.json/md、composite_prompts.json/md、report.md）。
每个国家的提示词规则在 prompts/<country>/（system_prompt.md + aesthetics.yaml）。
"""
import argparse
import sys
from pathlib import Path

# 把项目根加入 sys.path，确保 `import graph` 可用
ROOT = Path(__file__).resolve().parent
sys.path.insert(0, str(ROOT))

import yaml  # noqa: E402

from graph.agent import run_country  # noqa: E402


def main():
    parser = argparse.ArgumentParser(description="POD 热点抓取 Agent (LangGraph)")
    parser.add_argument("-c", "--countries", nargs="*", default=None,
                        help="国家代码（US GB JP AU），可多个；默认取 config.countries")
    parser.add_argument("--provider", default=None,
                        help="覆盖 LLM 后端：mock / openai_compat / openai / deepseek / qwen / moonshot")
    parser.add_argument("--base", default=None,
                        help="平铺衣服底图路径；提供则尝试印图（需 config.compose 配置图像后端）")
    parser.add_argument("--config", default="config.yaml", help="全局配置文件路径")
    # —— 产品图生成（product 节点）——
    parser.add_argument("--spu", default=None, help="选品款号（如 DG004；留空自动选第一个有底图的）")
    parser.add_argument("--sku", default=None, help="颜色编码（如 DG004-BL01；多个用逗号分隔，如 DG015-VT01,DG015-DARK HEATHER；留空自动选）")
    parser.add_argument("--single-spu", action="store_true", help="模板导出：单 SPU 下挂多颜色变体（默认每颜色一个 SPU 块）")
    parser.add_argument("--product-backend", default=None, help="产品图像后端：openai / mock")
    parser.add_argument("--list-spus", action="store_true", help="列出 db 可选 SPU 并退出")
    parser.add_argument("--list-colors", default=None, metavar="SPU", help="列出某款号颜色并退出")
    args = parser.parse_args()

    cfg_path = ROOT / args.config
    if not cfg_path.exists():
        print(f"配置文件不存在: {cfg_path}")
        sys.exit(1)
    cfg = yaml.safe_load(cfg_path.read_text(encoding="utf-8")) or {}

    # 产品选品查询（--list-spus / --list-colors）
    pcfg0 = cfg.get("product") or {}
    dbp = Path(pcfg0.get("db_path", "db/spu_sku.db"))
    if not dbp.is_absolute():
        dbp = ROOT / dbp
    if args.list_spus:
        from graph.product import list_spus
        print("=== db 可选 SPU（款号 / 品类 / 印花类型 / 国家）===")
        for s in list_spus(dbp):
            print(f"  {s['code']:10s} {s.get('style') or '':8s} {s.get('printing_type') or '':12s} {s.get('country') or ''}")
        sys.exit(0)
    if args.list_colors:
        from graph.product import list_colors
        print(f"=== {args.list_colors} 可选颜色（SKU.code / 色名）===")
        for c in list_colors(dbp, args.list_colors):
            print(f"  {c['sku_code']:16s} {c['color']}")
        sys.exit(0)

    if args.provider:
        cfg.setdefault("llm_screen", {})["provider"] = args.provider
    if args.spu or args.sku or args.product_backend or args.single_spu:
        p = cfg.setdefault("product", {})
        if args.spu:
            p["spu_code"] = args.spu
        if args.sku:
            p["sku_code"] = args.sku
        if args.product_backend:
            p["backend"] = args.product_backend
        if args.single_spu:
            p["spu_per_color"] = False

    countries = args.countries or cfg.get("countries", ["US", "GB", "JP", "AU"])
    base_image = args.base

    overall_errors = 0
    for c in countries:
        print(f"\n===== 开始处理 {c} =====")
        try:
            res = run_country(c, cfg, ROOT, base_image=base_image)
        except Exception as e:  # noqa: BLE001
            print(f"[{c}] 运行失败: {e}")
            overall_errors += 1
            continue

        stats = res.get("stats", {})
        f = stats.get("fetch", {})
        fl = stats.get("filter", {})
        sc = stats.get("screen", {})
        pr = stats.get("prompt", {})
        print(f"[{c}] 抓取原始 {f.get('raw_rows')} 行 | 过滤后保留 {fl.get('kept')} | "
              f"筛选保留 {sc.get('kept')} | 设计简报 {pr.get('briefs')} 条")
        errs = res.get("errors") or []
        if errs:
            overall_errors += len(errs)
            print(f"[{c}] 节点兜底捕获 {len(errs)} 条错误：")
            for e in errs:
                print(f"   - [{e.get('node')}] {e.get('type')}: {e.get('message')}")
        print(f"[{c}] 产物目录: output/{c}/")

    print(f"\n全部完成。累计兜底错误 {overall_errors} 条（不影响产出）。")


if __name__ == "__main__":
    main()
