"""obol admin - admin operations for Obol operators.

Subcommands:
    obol admin monitor       24/7 dashboard: VPS health, API metrics, alerts, events
    obol admin stats         Quick system stats
    obol admin add-yubikey   Register a YubiKey for admin authentication
    obol admin remove-yubikey  Remove a registered YubiKey
    obol admin list-yubikeys List registered YubiKeys
"""
import argparse


def setup_parser(subparsers):
    """Add admin subparser with subcommands."""
    admin_parser = subparsers.add_parser(
        "admin",
        help="Admin operations (GOR operators only)",
        description="Admin operations for Obol operators. Requires admin API key.",
    )
    admin_subs = admin_parser.add_subparsers(dest="admin_command")

    # monitor subcommand
    from obol.cli.admin_monitor import setup_parser as monitor_setup
    monitor_setup(admin_subs)

    # stats subcommand (quick view)
    stats_parser = admin_subs.add_parser("stats", help="Quick system stats")
    stats_parser.set_defaults(func=cmd_stats)

    # YubiKey management subcommands
    add_yubikey_parser = admin_subs.add_parser(
        "add-yubikey",
        help="Register a YubiKey for admin authentication",
    )
    add_yubikey_parser.set_defaults(func=cmd_add_yubikey)

    remove_yubikey_parser = admin_subs.add_parser(
        "remove-yubikey",
        help="Remove a registered YubiKey",
    )
    remove_yubikey_parser.add_argument(
        "public_id",
        nargs="?",
        help="YubiKey public ID to remove (12 chars)",
    )
    remove_yubikey_parser.set_defaults(func=cmd_remove_yubikey)

    list_yubikeys_parser = admin_subs.add_parser(
        "list-yubikeys",
        help="List registered YubiKeys",
    )
    list_yubikeys_parser.set_defaults(func=cmd_list_yubikeys)

    admin_parser.set_defaults(func=lambda args: admin_parser.print_help())


def cmd_stats(args):
    """Quick stats dump."""
    from obol.cli._base import get_api, error, output
    from obol.cli.yubikey import require_yubikey, prompt_and_verify_yubikey
    import sys

    # YubiKey authentication (if configured)
    if require_yubikey():
        if not prompt_and_verify_yubikey():
            sys.exit(1)

    try:
        api = get_api()
    except SystemExit:
        error("No API key configured. Run: obol setup <key>")

    # Check if we have admin access by trying the admin endpoint
    import os
    admin_secret = os.environ.get("OBOL_ADMIN_SECRET", "")
    if not admin_secret:
        config_path = os.path.expanduser("~/.obol/config.json")
        if os.path.exists(config_path):
            import json
            with open(config_path) as f:
                config = json.load(f)
                admin_secret = config.get("admin_secret", "")

    if not admin_secret:
        error("Admin secret required. Set OBOL_ADMIN_SECRET or obol config set admin_secret <secret>")

    try:
        # Make request with admin secret header
        import urllib.request
        import json as json_module

        base_url = api.base_url.rstrip("/")
        req = urllib.request.Request(
            f"{base_url}/admin/stats/summary",
            headers={
                "Authorization": f"Bearer {api.api_key}",
                "X-Admin-Secret": admin_secret,
                "User-Agent": "obol-sdk/0.1.0",
            },
        )
        with urllib.request.urlopen(req, timeout=30) as resp:
            data = json_module.loads(resp.read().decode())

        # Pretty print
        fmt = getattr(args, "format", "text")
        if fmt == "json":
            output(data, "json")
        else:
            print("OBOL ADMIN STATS")
            print("=" * 40)
            print(f"Orgs:      {data['orgs_total']:,} total (+{data['orgs_today']} today)")
            print(f"Agents:    {data['agents_total']:,} total, {data['agents_active']} active")
            print(f"Events:    {data['events_today']:,} today ({data['events_rate_per_min']}/min)")
            print(f"Anomalies: {data['anomalies_today']} ({data['anomaly_rate_pct']}%)")
            print(f"Alerts:    {data['alerts_open']} open ({data['alerts_critical']} crit, {data['alerts_high']} high)")
            print(f"Signups:   {data['signups_today']} today, {data['signups_week']} this week")

    except urllib.error.HTTPError as e:
        if e.code == 403:
            error("Access denied. Check admin credentials.")
        error(f"API error: {e.code}")
    except Exception as e:
        error(str(e))


def cmd_add_yubikey(args):
    """Add a YubiKey for admin authentication."""
    from obol.cli._base import error
    from obol.cli.yubikey import (
        validate_otp,
        extract_public_id,
        save_yubikey_id,
        load_allowed_yubikeys,
    )

    print("Register a YubiKey for admin CLI authentication.")
    print()
    print("This will add hardware 2FA to admin operations like 'obol admin monitor'.")
    print("Once configured, you must touch your YubiKey to access admin features.")
    print()

    try:
        otp = input("Touch your YubiKey now: ").strip()
    except (KeyboardInterrupt, EOFError):
        print("\nCancelled.")
        return

    if not otp:
        error("No OTP provided.")

    # Extract and validate
    public_id = extract_public_id(otp)
    if not public_id:
        error("Invalid OTP format.")

    # Check if already registered
    existing = load_allowed_yubikeys()
    if public_id in existing:
        print(f"YubiKey {public_id} is already registered.")
        return

    # Validate the OTP with Yubico
    print(f"Validating YubiKey {public_id}...")
    is_valid, message = validate_otp(otp)

    if not is_valid:
        error(f"Validation failed: {message}")

    # Save the public ID
    if save_yubikey_id(public_id):
        print(f"YubiKey {public_id} registered successfully.")
        print()
        print("Admin operations now require YubiKey authentication.")
    else:
        error("Failed to save YubiKey configuration.")


def cmd_remove_yubikey(args):
    """Remove a registered YubiKey."""
    from obol.cli._base import error
    from obol.cli.yubikey import (
        load_allowed_yubikeys,
        remove_yubikey_id,
    )

    existing = load_allowed_yubikeys()

    if not existing:
        print("No YubiKeys are currently registered.")
        return

    public_id = getattr(args, "public_id", None)

    if not public_id:
        # Interactive selection
        print("Registered YubiKeys:")
        for i, key_id in enumerate(existing, 1):
            print(f"  {i}) {key_id}")
        print()

        try:
            choice = input("Enter number to remove (or 'all' to remove all): ").strip()
        except (KeyboardInterrupt, EOFError):
            print("\nCancelled.")
            return

        if choice.lower() == "all":
            for key_id in existing:
                remove_yubikey_id(key_id)
            print("All YubiKeys removed. Admin operations no longer require 2FA.")
            return

        try:
            idx = int(choice) - 1
            if 0 <= idx < len(existing):
                public_id = existing[idx]
            else:
                error("Invalid selection.")
        except ValueError:
            error("Invalid input.")

    # Remove the specified key
    public_id = public_id.lower().strip()

    if public_id not in existing:
        error(f"YubiKey {public_id} is not registered.")

    if remove_yubikey_id(public_id):
        print(f"YubiKey {public_id} removed.")
        remaining = load_allowed_yubikeys()
        if not remaining:
            print("No YubiKeys remaining. Admin operations no longer require 2FA.")
    else:
        error("Failed to remove YubiKey.")


def cmd_list_yubikeys(args):
    """List registered YubiKeys."""
    from obol.cli.yubikey import load_allowed_yubikeys

    existing = load_allowed_yubikeys()

    if not existing:
        print("No YubiKeys registered.")
        print()
        print("To add a YubiKey: obol admin add-yubikey")
        return

    print("Registered YubiKeys:")
    for key_id in existing:
        print(f"  {key_id}")
    print()
    print(f"Total: {len(existing)} key(s)")
    print()
    print("Admin operations (monitor, etc.) require YubiKey authentication.")
