"""Safety CLI commands for OCLAWMA.

This module provides commands for:
- Viewing and managing audit logs
- Checking command safety
- Configuring safety settings
"""

from typing import Optional

import click

from oclawma.cli_ui import (
    accent,
    bullet,
    error,
    header,
    highlight,
    info,
    key_value,
    muted,
    print_error,
    print_info,
    print_success,
    progress_spinner,
    subheader,
    success,
    warning,
)
from oclawma.safety import RiskLevel, SafetyGuard


@click.group(name="safety")
def safety_cli() -> None:
    """Manage safety settings and audit logs."""
    pass


@safety_cli.command(name="audit")
@click.option(
    "--limit",
    type=int,
    default=50,
    help="Maximum number of entries to show",
    show_default=True,
)
@click.option(
    "--session",
    help="Filter by session ID",
)
@click.option(
    "--tool",
    help="Filter by tool name",
)
@click.option(
    "--risk",
    type=click.Choice(["low", "medium", "high", "critical"], case_sensitive=False),
    help="Filter by minimum risk level",
)
def audit_log(
    limit: int,
    session: Optional[str],
    tool: Optional[str],
    risk: Optional[str],
) -> None:
    """View the safety audit log."""
    guard = SafetyGuard()

    with progress_spinner("Loading audit log..."):
        entries = guard.get_audit_log(limit=limit * 2)  # Get extra for filtering

    # Apply filters
    if session:
        entries = [e for e in entries if e.session_id and e.session_id.startswith(session)]
    if tool:
        entries = [e for e in entries if e.tool_name.lower() == tool.lower()]
    if risk:
        min_level = RiskLevel(risk.lower())
        level_priority = {
            RiskLevel.CRITICAL: 4,
            RiskLevel.HIGH: 3,
            RiskLevel.MEDIUM: 2,
            RiskLevel.LOW: 1,
        }
        min_priority = level_priority.get(min_level, 0)
        entries = [e for e in entries if level_priority.get(e.risk_level, 0) >= min_priority]

    # Limit after filtering
    entries = entries[:limit]

    if not entries:
        print_info("No audit entries found.")
        return

    click.echo(header("SAFETY AUDIT LOG", width=58))
    click.echo()

    for entry in entries:
        # Format timestamp
        ts = entry.timestamp.strftime("%Y-%m-%d %H:%M:%S")

        # Risk level indicator
        risk_emoji = {
            RiskLevel.LOW: success("🟢"),
            RiskLevel.MEDIUM: warning("🟡"),
            RiskLevel.HIGH: error("🟠"),
            RiskLevel.CRITICAL: error("🔴"),
        }.get(entry.risk_level, "⚪")

        # Status indicators
        status = []
        if entry.was_dry_run:
            status.append(accent("[DRY-RUN]"))
        if entry.was_blocked:
            status.append(error("[BLOCKED]"))
        if entry.user_confirmed is not None:
            status.append(success("[CONFIRMED]") if entry.user_confirmed else error("[DENIED]"))

        status_str = " ".join(status) if status else ""

        click.echo(f"{risk_emoji} {muted(ts)} | {highlight(entry.tool_name)} | {entry.operation}")
        if status_str:
            click.echo(f"   Status: {status_str}")
        if entry.session_id:
            click.echo(f"   {muted('Session:')} {entry.session_id[:16]}...")
        click.echo()

    click.echo(muted(f"Showing {len(entries)} entries"))
    click.echo(muted(f"Audit log location: {guard.audit_log_path}"))


@safety_cli.command(name="clear-audit")
@click.confirmation_option(
    prompt=click.style("Are you sure you want to clear the audit log?", fg="yellow"),
)
def clear_audit() -> None:
    """Clear the safety audit log."""
    guard = SafetyGuard()

    with progress_spinner("Clearing audit log..."):
        if guard.clear_audit_log():
            print_success("Audit log cleared successfully.")
        else:
            print_error("Failed to clear audit log.")


@safety_cli.command(name="check")
@click.argument("command")
def check_command(command: str) -> None:
    """Check if a command has safety risks.

    Example:
        oclawma safety check "rm -rf /tmp/test"
    """
    guard = SafetyGuard()

    with progress_spinner("Analyzing command..."):
        risks = guard.analyze_command(command)

    if not risks:
        print_success("No risks detected for this command.")
        return

    max_risk = guard.get_max_risk_level(risks)

    click.echo(header("SAFETY CHECK RESULTS", width=58))
    click.echo()
    click.echo(guard.format_risk_warning(risks, command))
    click.echo()

    risk_color = {
        RiskLevel.LOW: success,
        RiskLevel.MEDIUM: warning,
        RiskLevel.HIGH: error,
        RiskLevel.CRITICAL: error,
    }.get(max_risk, str)

    click.echo(key_value("Risk Level", risk_color(max_risk.value.upper())))
    click.echo(key_value("Risks Found", str(len(risks))))


@safety_cli.command(name="status")
def safety_status() -> None:
    """Show safety system status."""
    guard = SafetyGuard()

    click.echo(header("SAFETY SYSTEM STATUS", width=58))
    click.echo()

    # Audit log info
    click.echo(subheader("AUDIT LOG"))
    click.echo(key_value("Location", str(guard.audit_log_path)))

    # Count entries
    with progress_spinner("Counting entries..."):
        entries = guard.get_audit_log(limit=10000)

    click.echo(key_value("Total entries", str(len(entries))))

    # Count by risk level
    risk_counts = {"critical": 0, "high": 0, "medium": 0, "low": 0}
    for entry in entries:
        risk_counts[entry.risk_level.value] = risk_counts.get(entry.risk_level.value, 0) + 1

    click.echo()
    click.echo(subheader("RISK DISTRIBUTION"))
    click.echo(f"  {error('🔴 Critical:')} {risk_counts.get('critical', 0)}")
    click.echo(f"  {error('🟠 High:')} {risk_counts.get('high', 0)}")
    click.echo(f"  {warning('🟡 Medium:')} {risk_counts.get('medium', 0)}")
    click.echo(f"  {success('🟢 Low:')} {risk_counts.get('low', 0)}")
    click.echo()

    # Detected patterns
    click.echo(subheader("DETECTED RISK PATTERNS"))

    patterns = {
        "Critical": [
            "rm -rf / (system destruction)",
            "Direct disk writing (dd)",
            "Filesystem formatting (mkfs)",
            "Fork bombs",
        ],
        "High": [
            "rm -rf (recursive force delete)",
            "rm -f (force delete)",
            "Recursive chmod/chown",
            "find -delete/-exec rm",
            "Pipe to shell (curl|sh, etc.)",
        ],
        "Medium": [
            "rm -r (recursive delete)",
            "sudo rm/chmod/chown",
            "git clean -f / reset --hard",
            "git push --force",
            "docker rm -f / system prune",
            "kubectl delete",
        ],
    }

    for level, items in patterns.items():
        level_color = {
            "Critical": error,
            "High": warning,
            "Medium": info,
        }.get(level, str)
        click.echo(f"  {level_color(level)}:")
        for item in items:
            click.echo(f"    {bullet(item)}")
    click.echo()

    # Session info
    click.echo(subheader("SESSION"))
    click.echo(key_value("Session ID", guard.session_id))
    click.echo()

    # Tips
    click.echo(subheader("COMMANDS"))
    click.echo(f"  {highlight('oclawma safety audit')}       - View full audit log")
    click.echo(f"  {highlight('oclawma safety check CMD')}   - Check command safety")
    click.echo(f"  {highlight('oclawma safety clear-audit')} - Clear audit log")
    click.echo()
    click.echo(f"  {muted('oclawma run --dry-run')}      - Run in dry-run mode")
    click.echo(f"  {muted('oclawma run --no-safety-confirm')}  - Disable confirmations")
