#!/usr/bin/env python3
"""Promote arXiv manifest records into paper item notes."""

from __future__ import annotations

import argparse
import json
from datetime import date
from pathlib import Path

from collect_arxiv import ROOT, existing_arxiv_ids, write_item


def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument("manifest", help="Path to an arXiv candidate manifest JSON file.")
    parser.add_argument("--min-score", type=int, default=13)
    parser.add_argument("--relevance", default="high")
    parser.add_argument("--max-items", type=int, default=0, help="0 means no cap.")
    parser.add_argument("--output-manifest", help="Optional JSON file for promoted records.")
    parser.add_argument("--dry-run", action="store_true")
    return parser.parse_args()


def normalize_record(record: dict) -> dict:
    arxiv_id = record.get("arxiv_id") or record["id"]
    return {
        "id": arxiv_id,
        "url": record.get("url") or f"https://arxiv.org/abs/{arxiv_id}",
        "title": record["title"],
        "published": record.get("published") or "",
        "updated": record.get("updated") or "",
        "authors": record.get("authors") or [],
        "categories": record.get("categories") or [],
    }


def main() -> int:
    args = parse_args()
    manifest_path = Path(args.manifest)
    if not manifest_path.is_absolute():
        manifest_path = ROOT / manifest_path

    records = json.loads(manifest_path.read_text(encoding="utf-8"))
    selected = [
        record
        for record in records
        if int(record.get("score") or 0) >= args.min_score
        and (not args.relevance or record.get("relevance") == args.relevance)
    ]
    selected.sort(key=lambda item: (int(item.get("score") or 0), item.get("published") or ""), reverse=True)
    if args.max_items:
        selected = selected[: args.max_items]

    existing = existing_arxiv_ids()
    today = date.today().isoformat()
    written = []
    skipped_existing = 0
    for record in selected:
        arxiv_id = record.get("arxiv_id") or record["id"]
        if arxiv_id in existing:
            skipped_existing += 1
            continue
        if not args.dry_run:
            path = write_item(
                normalize_record(record),
                record.get("topics") or ["agent"],
                int(record.get("score") or 0),
                record.get("relevance") or "unknown",
                set(record.get("matched_queries") or []),
                today,
            )
            written.append(str(path.relative_to(ROOT)))
            existing.add(arxiv_id)

    if args.output_manifest and not args.dry_run:
        output_path = Path(args.output_manifest)
        if not output_path.is_absolute():
            output_path = ROOT / output_path
        output_path.parent.mkdir(parents=True, exist_ok=True)
        output_path.write_text(json.dumps(selected, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")

    print(
        json.dumps(
            {
                "manifest": str(manifest_path.relative_to(ROOT)),
                "selected": len(selected),
                "written": len(written),
                "skipped_existing": skipped_existing,
                "output_manifest": args.output_manifest or "",
                "written_paths": written,
            },
            ensure_ascii=False,
            indent=2,
        )
    )
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
