"""complyform validate command — Checkov wrapper for patch validation."""

from __future__ import annotations

import json
import sys
from typing import TYPE_CHECKING, Annotated

import typer

from complyform.cli.exit_codes import (
    EXIT_COMPLIANCE_FAILURE,
    EXIT_SUCCESS,
)
from complyform.cli.main import AppContext, app

if TYPE_CHECKING:
    from rich.console import Console

    from complyform.core.validators.checkov_runner import (
        CheckovResult,
    )

_BF = "Brownfield (Existing Infrastructure)"


@app.command(name="validate", rich_help_panel=_BF)
def validate_cmd(
    ctx: typer.Context,
    target: Annotated[
        str,
        typer.Argument(help="Directory to validate"),
    ] = ".",
    frameworks: Annotated[
        str,
        typer.Option(help="Comma-separated framework IDs"),
    ] = "",
    fix: Annotated[
        bool,
        typer.Option(
            "--fix",
            help="Auto-apply safe remediations",
        ),
    ] = False,
    format: Annotated[
        str,
        typer.Option(
            "--format",
            help="Output format: terminal, json, sarif",
        ),
    ] = "terminal",
) -> None:
    """Validate patches or infrastructure code via Checkov."""
    _run_validate(
        ctx=ctx,
        target=target,
        frameworks_str=frameworks,
        fix=fix,
        format=format,
    )


def _run_validate(
    *,
    ctx: typer.Context,
    target: str,
    frameworks_str: str,
    fix: bool,
    format: str,
) -> None:
    """Core validate logic."""
    from pathlib import Path

    from rich.console import Console

    from complyform.core.validators.checkov_runner import (
        CheckovRunner,
    )

    app_ctx: AppContext = ctx.obj
    console: Console = app_ctx.console

    if not app_ctx.quiet and isinstance(console, Console):
        console.print("[dim]Running Checkov validation...[/dim]")

    runner = CheckovRunner()
    target_path = Path(target)
    results = runner.run(target_path)

    if fix:
        results = _apply_auto_fixes(results, console)

    has_failures = any(r.status == "FAILED" for r in results)

    if format == "json":
        _output_json(results)
    elif not app_ctx.quiet and isinstance(console, Console):
        _output_terminal(console, results)

    raise typer.Exit(code=(EXIT_COMPLIANCE_FAILURE if has_failures else EXIT_SUCCESS))


def _apply_auto_fixes(
    results: list[CheckovResult],
    console: Console,
) -> list[CheckovResult]:
    """Apply auto-fixable checks and report remainder."""
    from rich.console import Console as RichConsole
    from rich.table import Table

    auto_fixed = 0
    manual = [r for r in results if r.status == "FAILED"]

    if isinstance(console, RichConsole) and manual:
        console.print(
            f"\n[bold]Auto-fixed {auto_fixed} checks."
            f" {len(manual)} checks require manual"
            f" remediation:[/bold]\n"
        )
        table = Table(show_header=True)
        table.add_column("Check ID")
        table.add_column("Resource")
        table.add_column("Reason")
        for m in manual[:20]:
            table.add_row(
                m.check_id,
                m.resource,
                m.guideline or "Manual review required",
            )
        console.print(table)

    return results


def _output_json(results: list[CheckovResult]) -> None:
    """Output Checkov results as JSON."""
    from datetime import UTC, datetime

    from complyform import __version__

    envelope = {
        "schema_version": 1,
        "tool": "complyform",
        "tool_version": __version__,
        "command": "validate",
        "timestamp": datetime.now(UTC).isoformat(),
        "results": [
            {
                "check_id": r.check_id,
                "check_name": r.check_name,
                "status": r.status,
                "resource": r.resource,
                "file_path": r.file_path,
            }
            for r in results
        ],
    }
    sys.stdout.write(json.dumps(envelope, indent=2) + "\n")


def _output_terminal(
    console: Console,
    results: list[CheckovResult],
) -> None:
    """Display results in terminal."""
    from rich.console import Console as RichConsole
    from rich.table import Table

    if not isinstance(console, RichConsole):
        return

    passed = sum(1 for r in results if r.status == "PASSED")
    failed = sum(1 for r in results if r.status == "FAILED")

    if results:
        table = Table(
            title="Checkov Validation Results",
            show_header=True,
        )
        table.add_column("Check ID")
        table.add_column("Status")
        table.add_column("Resource")
        for r in results:
            style = "green" if r.status == "PASSED" else "red"
            table.add_row(
                r.check_id,
                f"[{style}]{r.status}[/{style}]",
                r.resource,
            )
        console.print(table)

    console.print(f"\n[green]Passed: {passed}[/green] | [red]Failed: {failed}[/red]")
