"""CLI entry point for ping-rss."""

from __future__ import annotations

import argparse
import sys
import time

from ping_rss import __version__
from ping_rss.config import ConfigError, find_config, load_config
from ping_rss.runner import ALL_SERVICES, print_results, run


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(
        prog="ping-rss",
        description="Multi-site RSS feed ping tool for accelerated indexation",
    )
    parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
    parser.add_argument("-c", "--config", help="Path to sites.yaml config file")

    sub = parser.add_subparsers(dest="command")

    # Shared parent for verbose flag on subcommands
    common = argparse.ArgumentParser(add_help=False)
    common.add_argument("-v", "--verbose", action="store_true", help="Verbose output")

    # ping subcommand
    ping_parser = sub.add_parser("ping", help="Ping services for a site", parents=[common])
    ping_parser.add_argument("site", nargs="?", help="Site slug from config")
    ping_parser.add_argument("--all", action="store_true", help="Ping all configured sites")
    ping_parser.add_argument(
        "--only",
        help="Comma-separated list of services: xmlrpc,pubsub,indexnow,gsc",
    )
    ping_parser.add_argument(
        "--urls",
        nargs="+",
        help="Specific URLs to submit (for IndexNow and GSC)",
    )
    ping_parser.add_argument("--dry-run", action="store_true", help="Show what would be done")
    ping_parser.add_argument(
        "--delay",
        type=int,
        default=300,
        metavar="SEC",
        help="Delay in seconds between sites with --all (default: 300)",
    )

    # sites subcommand
    sub.add_parser("sites", help="List configured sites", parents=[common])

    # check subcommand
    sub.add_parser("check", help="Validate config file", parents=[common])

    args = parser.parse_args(argv)

    if not args.command:
        parser.print_help()
        return 0

    # Load config
    try:
        config_path = args.config or find_config()
        config = load_config(config_path)
    except ConfigError as e:
        print(f"Config error: {e}", file=sys.stderr)
        return 2

    if args.command == "check":
        return _cmd_check(config, config_path)
    elif args.command == "sites":
        return _cmd_sites(config)
    elif args.command == "ping":
        return _cmd_ping(args, config)

    return 0


def _cmd_check(config, config_path) -> int:
    print(f"Config: {config_path}")
    print(f"Sites: {len(config.sites)}")
    for slug, site in config.sites.items():
        issues = []
        if not site.indexnow_key:
            issues.append("no indexnow_key")
        if not config.google.service_account_json:
            issues.append("no GSC service account")
        status = f" (warnings: {', '.join(issues)})" if issues else ""
        print(f"  [{slug}] {site.name}{status}")
    print("\nConfig is valid.")
    return 0


def _cmd_sites(config) -> int:
    for slug, site in config.sites.items():
        features = []
        features.append(f"xmlrpc({len(site.ping_services)})")
        features.append("pubsub")
        if site.indexnow_key:
            features.append("indexnow")
        if config.google.service_account_json:
            features.append("gsc")
        print(f"  {slug:20s} {site.name:30s} [{', '.join(features)}]")
    return 0


def _cmd_ping(args, config) -> int:
    # Determine which services to use
    only = None
    if args.only:
        only = set(args.only.split(","))
        invalid = only - ALL_SERVICES
        if invalid:
            print(f"Unknown services: {', '.join(invalid)}", file=sys.stderr)
            print(f"Valid services: {', '.join(sorted(ALL_SERVICES))}", file=sys.stderr)
            return 2

    # Determine which sites to ping
    if args.all:
        sites = config.all_sites()
    elif args.site:
        try:
            sites = [config.get_site(args.site)]
        except ConfigError as e:
            print(f"Error: {e}", file=sys.stderr)
            return 2
    else:
        print("Error: specify a site slug or --all", file=sys.stderr)
        return 2

    # Run
    has_failure = False
    for i, site in enumerate(sites):
        if i > 0 and not args.dry_run and args.delay > 0:
            print(f"  Waiting {args.delay}s before next site (rate limit protection)...")
            time.sleep(args.delay)

        result = run(
            config=config,
            site=site,
            only=only,
            urls=args.urls,
            dry_run=args.dry_run,
        )
        if not args.dry_run:
            print_results(result, verbose=args.verbose)
        if not result.all_ok:
            has_failure = True

    return 1 if has_failure else 0


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