"""CLI subcommands for the crawl surface (Stream B): `indexnow`.

Registered into `app.cli` like the quality commands (`register(sub)`), and
runnable on its own until that line lands:

    python -m app.cli_pages indexnow --hours 24 --dry-run
    python -m app.cli_pages indexnow --since 2026-09-05T13:20:00+00:00

Run it after a collection, from the container (it reads the database and
PUBLIC_BASE_URL / INDEXNOW_KEY from the app's environment). It is the one
outbound request this app makes that is not to a retailer: a POST to
api.indexnow.org listing our own changed pages.
"""

import argparse
import sys
from datetime import UTC, datetime, timedelta

from app.config import settings
from app.db import SessionLocal
from app.services import indexnow


def cmd_indexnow(args: argparse.Namespace) -> int:
    if args.since:
        since = datetime.fromisoformat(args.since)
        if since.tzinfo is None:
            since = since.replace(tzinfo=UTC)
    else:
        since = datetime.now(UTC) - timedelta(hours=args.hours)
    base = settings.public_base_url.rstrip("/")
    if not base:
        print("PUBLIC_BASE_URL is not set; nothing submitted", file=sys.stderr)
        return 2
    with SessionLocal() as db:
        urls = indexnow.changed_urls(db, since, base, line_pages=settings.line_pages)
    print(f"{len(urls)} page(s) changed since {since.isoformat(timespec='minutes')}")
    if args.dry_run or not urls:
        for url in urls[: args.show]:
            print(f"  {url}")
        if len(urls) > args.show:
            print(f"  ... and {len(urls) - args.show} more")
        return 0
    if not settings.has_indexnow:
        print("INDEXNOW_KEY is not set; nothing submitted (use --dry-run to list)", file=sys.stderr)
        return 2
    results = indexnow.submit(urls, base, settings.indexnow_key)
    for count, status in results:
        print(f"  submitted {count} -> HTTP {status}")
    return 0 if all(status in (200, 202) for _, status in results) else 1


def register(sub: argparse._SubParsersAction) -> None:
    cmd = sub.add_parser("indexnow", help="tell the IndexNow engines which pages changed")
    cmd.add_argument("--since", help="ISO timestamp; pages with observations after it are submitted")
    cmd.add_argument("--hours", type=float, default=24, help="or: pages changed in the last N hours (default 24)")
    cmd.add_argument("--dry-run", action="store_true", help="list the URLs, submit nothing")
    cmd.add_argument("--show", type=int, default=20, help="how many URLs a dry run prints")
    cmd.set_defaults(func=cmd_indexnow)


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(prog="app.cli_pages")
    register(parser.add_subparsers(dest="command", required=True))
    args = parser.parse_args(argv)
    return args.func(args)


if __name__ == "__main__":
    sys.exit(main())
