# Copyright (c) 2025 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com
#

"""
API schema utilities for generating Pydantic models from recorded API data
"""

import json

from rich.console import Console
from rich.json import JSON

from src.lib.api_recorder import recorder
from src.utils.console import eprint, print_info, print_success, print_warning

# Initialize console for full-width output
console = Console(width=None)


def print_recorded_endpoints(limit: int | None = None):
    """Print all recorded API endpoints.

    Args:
        limit: Maximum number of endpoints to display (None = unlimited)
    """
    all_records = recorder.get_all_records()

    if not all_records:
        print_warning("No API records found. Run some commands that use the V2 API first.")
        return

    print_info(f"\nFound {len(all_records)} recorded API endpoints:")

    endpoints = sorted(all_records.keys())

    # Apply limit if specified
    if limit and limit > 0:
        endpoints = endpoints[:limit]

    for endpoint in endpoints:
        count = len(all_records[endpoint])
        print_success(f"  - {endpoint} ({count} records)")


def get_endpoint_details(endpoint: str, show_all: bool = False):
    """
    Print detailed information about a specific endpoint.

    Args:
        endpoint: The endpoint to show details for
        show_all: If True, show all records instead of just the latest
    """
    records = recorder.get_records_for_endpoint(endpoint)

    if not records:
        print_warning(f"No records found for endpoint: {endpoint}")
        print_info("Use 'czops api-schemas list' to see available endpoints.")
        return

    print_info(f"\nDetails for endpoint: {endpoint}")
    print_info(f"Number of records: {len(records)}")

    if show_all:
        # Show all records with index numbers
        for i, record in enumerate(records):
            print_info(f"\n=== Record #{i + 1} of {len(records)} ===")
            _print_record_details(record)
    else:
        # Show only the latest record
        latest_record = records[-1]
        print_info("\nLatest Record:")
        _print_record_details(latest_record)


def _print_record_details(record):
    """Helper function to print details of a single record."""
    # Print timestamp if available
    if "recorded_at" in record:
        print_info(f"  Recorded at: {record['recorded_at']}")

    # Print request details
    print_info("\nRequest:")
    path = record["request"]["path"]
    method = record["request"]["method"]
    print_success(f"  Path: {path}")
    print_success(f"  Method: {method}")

    if record["request"]["payload"]:
        print_info("  Payload:")
        # Use soft_wrap=True to ensure JSON wraps properly based on terminal width
        console.print(JSON(json.dumps(record["request"]["payload"])), soft_wrap=True)

    if record["request"]["params"]:
        print_info("  Params:")
        console.print(JSON(json.dumps(record["request"]["params"])), soft_wrap=True)

    if record["request"].get("headers"):
        print_info("  Headers:")
        console.print(JSON(json.dumps(record["request"]["headers"])), soft_wrap=True)

    # Print response details
    print_info("\nResponse:")
    if isinstance(record["response"], dict) and "result" in record["response"]:
        # Just show the result part if it exists
        result = record["response"]["result"]
        if isinstance(result, list) and len(result) > 0:
            # Show first item as example
            console.print(JSON(json.dumps(result[0])), soft_wrap=True)
            print_info(f"  ... and {len(result) - 1} more items")
        else:
            console.print(JSON(json.dumps(result)), soft_wrap=True)
    else:
        console.print(JSON(json.dumps(record["response"])), soft_wrap=True)


def export_records(endpoint: str | None = None):
    """Export recorded data to a specific location."""
    if endpoint:
        records = recorder.get_records_for_endpoint(endpoint)
        if not records:
            print_warning(f"No records found for endpoint: {endpoint}")
            return

        # Export just one endpoint
        filename = f"{endpoint}_records.json"
        with open(filename, "w") as f:
            json.dump(records, f, indent=2, default=str)
        print_success(f"Exported records for {endpoint} to {filename}")
    else:
        # Export all endpoints
        all_records = recorder.get_all_records()
        if not all_records:
            print_warning("No API records found.")
            return

        filename = "all_api_records.json"
        with open(filename, "w") as f:
            json.dump(all_records, f, indent=2, default=str)
        print_success(f"Exported all API records to {filename}")


def purge_old_records(days: int):
    """
    Purge API records older than specified number of days.

    Args:
        days: Number of days to keep records for (older records are purged)
    """
    try:
        endpoints_affected, records_purged = recorder.purge_old_records(days)

        if records_purged > 0:
            print_success(f"Successfully purged {records_purged} records from {endpoints_affected} endpoints.")
        else:
            print_info("No records found older than the specified age.")

    except ValueError as e:
        eprint(f"Error: {str(e)}")
    except Exception as e:
        eprint(f"Unexpected error purging records: {str(e)}")


def handle_command(arguments):
    """Handle the api-schemas command."""
    if arguments.get("list"):
        limit = int(arguments.get("--limit")) if arguments.get("--limit") else None
        print_recorded_endpoints(limit=limit)
    elif arguments.get("show"):
        endpoint = arguments.get("<endpoint>")
        show_all = arguments.get("--all", False)
        get_endpoint_details(endpoint, show_all=show_all)
    elif arguments.get("export"):
        endpoint = arguments.get("<endpoint>")
        export_records(endpoint)
    elif arguments.get("purge"):
        days = arguments.get("--age")
        try:
            days_int = int(days)
            if days_int <= 0:
                eprint("Age must be a positive number of days.")
                return
            purge_old_records(days_int)
        except (ValueError, TypeError):
            eprint("Invalid age value. Please provide a positive integer for --age.")
    else:
        print_recorded_endpoints()
