"""License management commands."""

from datetime import datetime

import typer
from rich.console import Console
from rich.panel import Panel
from rich.table import Table

from apiposture_pro.licensing.manager import ProLicenseManager
from apiposture_pro.licensing.models import (
    LicenseErrorCode,
    LicenseFeature,
    LicenseType,
)

app = typer.Typer(help="License management commands")
console = Console()

# Feature descriptions for the status display
_FEATURE_DESCRIPTIONS = {
    LicenseFeature.DIFF: "Compare scan results across runs",
    LicenseFeature.HISTORY: "Track scan history over time",
    LicenseFeature.RISK_SCORING: "Calculate composite risk scores",
    LicenseFeature.OWASP_RULES: "OWASP Top 10 security rules",
    LicenseFeature.SECRETS: "Secret & credential detection",
}


@app.command("activate")
def activate(license_key: str) -> None:
    """
    Activate Pro license.

    Args:
        license_key: Your Pro license key
    """
    manager = ProLicenseManager()

    try:
        console.print("[dim]Activating license...[/dim]")
        context = manager.activate(license_key)

        console.print("[green]✓[/green] License activated successfully!")
        console.print(f"\n[bold]Customer:[/bold] {context.customer_name}")
        console.print(f"[bold]Email:[/bold] {context.customer_email}")
        console.print(f"[bold]Tier:[/bold] {context.tier}")
        console.print(f"[bold]Expires:[/bold] {context.expires_at.strftime('%Y-%m-%d')}")

    except Exception as e:
        console.print(f"[red]✗[/red] Activation failed: {e}")
        raise typer.Exit(1) from e


@app.command("deactivate")
def deactivate() -> None:
    """Deactivate current license."""
    manager = ProLicenseManager()

    if not manager.is_valid():
        console.print("[yellow]![/yellow] No active license to deactivate")
        raise typer.Exit(1)

    manager.deactivate()
    console.print("[green]✓[/green] License deactivated successfully")


@app.command("status")
def status() -> None:
    """Show current license status with detailed diagnostics."""
    manager = ProLicenseManager()
    result = manager.validate()

    if not result.is_valid:
        _show_invalid_status(manager, result)
        raise typer.Exit(1)

    context = result.context
    if not context:
        console.print("[red]✗[/red] License context not available")
        raise typer.Exit(1)

    stored = manager.get_stored_license()

    # Status table
    table = Table(title="License Status", show_header=True)
    table.add_column("Property", style="cyan")
    table.add_column("Value", style="white")

    # Status line with grace period warning
    if result.is_in_grace_period:
        table.add_row(
            "Status",
            f"[yellow]Grace Period ({result.grace_period_days_remaining}d remaining)[/yellow]",
        )
    else:
        table.add_row("Status", "[green]Active[/green]")

    table.add_row("Customer", context.customer_name)
    table.add_row("Email", context.customer_email)
    table.add_row("Tier", context.tier.upper())

    # License type
    type_label = "CI/CD" if context.license_type == LicenseType.CI else "Developer"
    table.add_row("License Type", type_label)

    # Organization & seats
    if context.organization:
        table.add_row("Organization", context.organization)
    if context.seats is not None:
        table.add_row("Seats", str(context.seats))

    # Expiration with color coding
    now = datetime.utcnow()
    days_remaining = (context.expires_at - now).days
    expires_str = context.expires_at.strftime("%Y-%m-%d %H:%M:%S UTC")
    if days_remaining > 30:
        expires_display = f"[green]{expires_str} ({days_remaining}d remaining)[/green]"
    elif days_remaining > 7:
        expires_display = f"[yellow]{expires_str} ({days_remaining}d remaining)[/yellow]"
    else:
        expires_display = f"[red]{expires_str} ({days_remaining}d remaining)[/red]"
    table.add_row("Expires", expires_display)

    # Activation & validation times from stored license
    if stored:
        table.add_row("Activated", stored.activated_at.strftime("%Y-%m-%d %H:%M:%S UTC"))
        table.add_row("Last Validated", stored.last_validated_at.strftime("%Y-%m-%d %H:%M:%S UTC"))

    # License source
    import os
    source = "Environment variable" if os.getenv("APIPOSTURE_LICENSE_KEY") else f"File ({manager.LICENSE_FILE})"
    table.add_row("Source", source)

    if context.machine_id:
        table.add_row("Machine ID", context.machine_id[:16] + "...")

    console.print(table)

    # Features panel
    if context.features:
        has_all = "all" in context.features
        feature_lines = []
        for feat in LicenseFeature:
            if has_all or feat.value in context.features:
                desc = _FEATURE_DESCRIPTIONS.get(feat, feat.value)
                feature_lines.append(f"  [green]✓[/green] {feat.value:<15} {desc}")
            else:
                desc = _FEATURE_DESCRIPTIONS.get(feat, feat.value)
                feature_lines.append(f"  [dim]✗ {feat.value:<15} {desc}[/dim]")

        console.print(Panel("\n".join(feature_lines), title="Features", border_style="blue"))


def _show_invalid_status(manager: ProLicenseManager, result) -> None:
    """Show detailed diagnostics for an invalid license."""
    # Error-code-specific messages
    messages = {
        LicenseErrorCode.EXPIRED: f"[red]✗[/red] Your license has expired. {result.error_message}",
        LicenseErrorCode.MACHINE_MISMATCH: "[red]✗[/red] License is bound to a different machine. Re-activate or contact support.",
        LicenseErrorCode.REVOKED: "[red]✗[/red] Your license has been revoked. Contact support for assistance.",
        LicenseErrorCode.TOO_MANY_ACTIVATIONS: "[red]✗[/red] Too many activations for this license key.",
        LicenseErrorCode.NETWORK_ERROR: "[red]✗[/red] License could not be validated offline. Connect to the internet to re-validate.",
        LicenseErrorCode.GRACE_PERIOD_EXPIRED: "[red]✗[/red] License expired and grace period has ended. Renew your license.",
        LicenseErrorCode.INVALID_SIGNATURE: "[red]✗[/red] License key has an invalid signature.",
    }

    msg = messages.get(result.error_code, f"[red]✗[/red] No valid license found. {result.error_message}")
    console.print(msg)

    # Diagnostics panel
    diag_lines = [
        f"Error Code: {result.error_code.value}",
        f"License File: {manager.LICENSE_FILE}",
        f"File Exists: {manager.LICENSE_FILE.exists()}",
    ]
    if manager.LICENSE_FILE.exists():
        stat = manager.LICENSE_FILE.stat()
        diag_lines.append(f"File Size: {stat.st_size} bytes")
        diag_lines.append(f"Permissions: {oct(stat.st_mode)[-3:]}")

    import os
    diag_lines.append(f"Env Var Set: {'Yes' if os.getenv('APIPOSTURE_LICENSE_KEY') else 'No'}")

    console.print(Panel("\n".join(diag_lines), title="Diagnostics", border_style="red"))
    console.print("\nActivate with: apiposture-pro activate <license-key>")
