import json
import sys

import click
from rich.console import Console

from abip import __version__
from abip import api, ui

console = Console()

json_output = False


@click.group()
@click.option("--json", "-j", "json_flag", is_flag=True, help="Output as JSON")
@click.version_option(version=__version__)
def main(json_flag: bool):
    """AbuseIPDB CLI - Check and report malicious IP addresses."""
    global json_output
    json_output = json_flag


@main.command()
@click.argument("ip_address")
@click.option("--days", "-d", default=30, help="Max age in days (default: 30)")
@click.option("--verbose", "-v", is_flag=True, help="Show detailed reports")
def check(ip_address: str, days: int, verbose: bool):
    """Check an IP address reputation."""
    try:
        with api.AbuseIPDBClient() as client:
            data = client.check_ip(ip_address, max_age_days=days, verbose=verbose)
            if json_output:
                print(json.dumps(data, indent=2))
            else:
                console.print(f"[cyan]Checking IP:[/cyan] {ip_address}")
                ui.print_ip_details(data)
    except api.AbuseIPDBError as e:
        ui.print_error(e.message)
        sys.exit(1)
    except Exception as e:
        ui.print_error(str(e))
        sys.exit(1)


@main.command()
@click.argument("network")
@click.option("--days", "-d", default=30, help="Max age in days (default: 30)")
def block(network: str, days: int):
    """Check a CIDR block for malicious IPs."""
    try:
        with api.AbuseIPDBClient() as client:
            data = client.check_block(network, max_age_days=days)
            if json_output:
                print(json.dumps(data, indent=2))
            else:
                console.print(f"[cyan]Checking block:[/cyan] {network}")
                ui.print_block_details(data)
    except api.AbuseIPDBError as e:
        ui.print_error(e.message)
        sys.exit(1)
    except Exception as e:
        ui.print_error(str(e))
        sys.exit(1)


@main.command()
@click.argument("ip_address")
@click.option(
    "--categories",
    "-c",
    required=True,
    help="Comma-separated category IDs (e.g., 18,22)",
)
@click.option(
    "--comment", "-m", required=True, help="Description of malicious activity"
)
@click.option("--timestamp", "-t", help="ISO 8601 timestamp (optional)")
def report(ip_address: str, categories: str, comment: str, timestamp: str | None):
    """Report a malicious IP address."""
    try:
        with api.AbuseIPDBClient() as client:
            data = client.report_ip(ip_address, categories, comment, timestamp)
            if json_output:
                print(json.dumps(data, indent=2))
            else:
                console.print(f"[cyan]Reporting IP:[/cyan] {ip_address}")
                ui.print_report_result(data)
    except api.AbuseIPDBError as e:
        ui.print_error(e.message)
        sys.exit(1)
    except Exception as e:
        ui.print_error(str(e))
        sys.exit(1)


@main.command()
@click.option(
    "--min-confidence", "-m", default=25, help="Minimum confidence score (default: 25)"
)
@click.option("--limit", "-l", default=100, help="Number of results (default: 100)")
@click.option(
    "--ip-version", "-4", "-6", type=int, help="Filter by IP version (4 or 6)"
)
@click.option("--countries", "-c", help="Comma-separated country codes (e.g., US,CN)")
def blacklist(
    min_confidence: int, limit: int, ip_version: int | None, countries: str | None
):
    """Get blacklisted IP addresses."""
    try:
        with api.AbuseIPDBClient() as client:
            data = client.blacklist(
                confidence_minimum=min_confidence,
                limit=limit,
                ip_version=ip_version,
                only_countries=countries,
            )
            if json_output:
                print(json.dumps(data, indent=2))
            else:
                console.print(
                    f"[cyan]Fetching blacklist (min confidence: {min_confidence}%)[/cyan]"
                )
                ui.print_blacklist(data)
    except api.AbuseIPDBError as e:
        ui.print_error(e.message)
        sys.exit(1)
    except Exception as e:
        ui.print_error(str(e))
        sys.exit(1)


if __name__ == "__main__":
    main()
