#!/usr/bin/env python3
"""补跑 430 query 采集结果的创作知识判断。

示例：
  CK_ENV_FILE=.env PYTHONPATH=. .venv/bin/python scripts/classify_creation_items.py \
    --run-id creation-search-full-20260629 --platform xiaohongshu,weixin --workers 4

  CK_ENV_FILE=.env PYTHONPATH=. .venv/bin/python scripts/classify_creation_items.py \
    --run-id creation-search-full-20260629 --platform xiaohongshu --provider qwen --model qwen3.7-plus --workers 4

  CK_ENV_FILE=.env PYTHONPATH=. .venv/bin/python scripts/classify_creation_items.py \
    --run-id creation-search-full-20260629 --platform weixin --provider ark --model ep-20260506151915-jqvw7 --workers 4
"""
from __future__ import annotations

import argparse
import concurrent.futures as cf
import os
import sys
import time
from pathlib import Path

ROOT = Path(__file__).resolve().parent.parent
if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

from acquisition import store
from acquisition.classify import classify_imgtext, classify_video
from acquisition.creation_search import PLATFORMS, prompt_version
from core.config import Settings


def _parse_platforms(value: str | None) -> list[str] | None:
    if not value:
        return None
    out = [p.strip() for p in value.split(",") if p.strip()]
    bad = [p for p in out if p not in PLATFORMS]
    if bad:
        raise SystemExit(f"unsupported platform(s): {', '.join(bad)}")
    return out


def _classify_one(item: dict, settings: Settings) -> tuple[int, int | None, str, str, str, str]:
    platform = item["platform"]
    if platform == "douyin":
        version = prompt_version("classify_video")
        is_creation, reason, knowledge, _points = classify_video(
            {
                "platform": platform,
                "title": item.get("title") or "",
                "body_text": item.get("body_text") or "",
                "video": item.get("video_url") or "",
            },
            settings,
        )
    else:
        version = prompt_version("classify_imgtext")
        is_creation, reason, knowledge, _points = classify_imgtext(
            {
                "platform": platform,
                "title": item.get("title") or "",
                "body_text": item.get("body_text") or "",
                "images": item.get("image_urls") or [],
            },
            settings,
        )
    return item["id"], is_creation, reason, knowledge, version, reason if is_creation is None else ""


def main() -> None:
    ap = argparse.ArgumentParser()
    ap.add_argument("--run-id", help="默认使用最新 creation_search_run")
    ap.add_argument("--platform", help="平台，多个用逗号分隔；默认全部")
    ap.add_argument("--limit", type=int, default=0, help="最多补判多少条；0=不限制")
    ap.add_argument("--workers", type=int, default=3)
    ap.add_argument("--only-missing", action="store_true", help="只补完全未分类，不重试失败分类")
    ap.add_argument("--provider", choices=["auto", "openrouter", "ark", "qwen", "bailian"], help="本次补判使用的模型通道")
    ap.add_argument("--model", help="本次补判使用的模型名/方舟接入点，如 qwen3.7-plus 或 ep-...")
    args = ap.parse_args()

    if args.provider:
        os.environ["CLASSIFY_PROVIDER"] = args.provider
    if args.model:
        os.environ["CLASSIFY_MODEL"] = args.model

    settings = Settings.from_env(os.getenv("CK_ENV_FILE", ".env"))
    platforms = _parse_platforms(args.platform)
    conn = store.connect()
    rows = store.creation_items_to_classify(
        conn,
        run_id=args.run_id,
        platforms=platforms,
        retry_failed=not args.only_missing,
        limit=args.limit if args.limit > 0 else None,
    )
    print(f"待补判 {len(rows)} 条 platforms={','.join(platforms or PLATFORMS)} workers={args.workers}")
    if not rows:
        conn.close()
        return

    done = fail = 0
    with cf.ThreadPoolExecutor(max_workers=max(1, args.workers)) as ex:
        futs = {ex.submit(_classify_one, item, settings): item for item in rows}
        for fut in cf.as_completed(futs):
            item = futs[fut]
            try:
                item_id, is_creation, reason, knowledge, version, error = fut.result()
            except Exception as exc:
                item_id = item["id"]
                is_creation = None
                reason = f"判定失败: {str(exc)[:80]}"
                knowledge = ""
                version = ""
                error = reason
            store.upsert_creation_classification(
                conn,
                item_id,
                is_creation,
                reason=reason,
                knowledge=knowledge,
                prompt_version=version,
                error=error,
                ts=int(time.time()),
            )
            done += 1
            if is_creation is None:
                fail += 1
            if done % 20 == 0 or done == len(rows):
                print(f"  {done}/{len(rows)} done failed={fail}", flush=True)
    conn.close()
    print(f"完成：{done} 条，失败 {fail} 条")


if __name__ == "__main__":
    main()
