"""complyform frameworks command — list, inspect, and compare frameworks."""

from __future__ import annotations

from typing import TYPE_CHECKING, Annotated

import typer
from rich.table import Table

from complyform.core.profiles.registry import (
    get_framework,
    list_frameworks,
    search_frameworks,
)

if TYPE_CHECKING:
    from complyform.cli.main import AppContext

frameworks_app = typer.Typer(
    name="frameworks",
    help="List supported compliance frameworks and controls.",
    rich_markup_mode="rich",
    no_args_is_help=True,
)


@frameworks_app.command(name="list")
def frameworks_list(
    ctx: typer.Context,
    tier: Annotated[
        str | None,
        typer.Option(help="Filter by tier: community, pro, team, agency, enterprise"),
    ] = None,
    cloud: Annotated[
        str | None,
        typer.Option(help="Filter by cloud: gcp, aws, azure"),
    ] = None,
    category: Annotated[
        str | None,
        typer.Option(help="Filter by category: global, regional, industry, cis"),
    ] = None,
    query: Annotated[
        str | None,
        typer.Option("--search", "-s", help="Search by name or ID"),
    ] = None,
    format: Annotated[
        str,
        typer.Option("--format", help="Output format: terminal, json"),
    ] = "terminal",
) -> None:
    """List all supported compliance frameworks."""
    app_ctx: AppContext = ctx.obj

    if query:
        fws = search_frameworks(query)
    else:
        fws = list_frameworks(tier=tier, cloud=cloud, category=category)

    if format == "json":
        import json
        import sys

        data = [f.model_dump(mode="json") for f in fws]
        sys.stdout.write(json.dumps(data, indent=2) + "\n")
        return

    console = app_ctx.console
    if app_ctx.quiet:
        return

    from rich.console import Console

    if not isinstance(console, Console):
        return

    table = Table(title="Compliance Frameworks", show_lines=False)
    table.add_column("ID", style="cyan", no_wrap=True)
    table.add_column("Name", style="white")
    table.add_column("Version", style="dim")
    table.add_column("Tier", style="green")
    table.add_column("Cloud", style="yellow")
    table.add_column("Controls", justify="right")

    for fw in fws:
        table.add_row(
            fw.id,
            fw.name,
            fw.version,
            fw.tier,
            fw.cloud,
            str(fw.control_count),
        )

    console.print(table)
    console.print(f"\n[bold]{len(fws)}[/bold] frameworks")


@frameworks_app.command(name="info")
def frameworks_info(
    ctx: typer.Context,
    framework_id: Annotated[
        str,
        typer.Argument(help="Framework ID (e.g. soc2, cis_gcp)"),
    ],
    format: Annotated[
        str,
        typer.Option("--format", help="Output format: terminal, json"),
    ] = "terminal",
) -> None:
    """Show detailed information about a framework."""
    app_ctx: AppContext = ctx.obj
    fw = get_framework(framework_id)

    if format == "json":
        import json
        import sys

        data = fw.model_dump(mode="json")

        try:
            from complyform.core.profiles.control_loader import load_controls

            cf = load_controls(framework_id)
            data["controls"] = [c.model_dump(mode="json") for c in cf.controls]
        except Exception:
            data["controls"] = []

        sys.stdout.write(json.dumps(data, indent=2) + "\n")
        return

    console = app_ctx.console
    if app_ctx.quiet:
        return

    from rich.console import Console
    from rich.panel import Panel

    if not isinstance(console, Console):
        return

    body = (
        f"[bold]{fw.name}[/bold]\n"
        f"Version: {fw.version}\n"
        f"Authority: {fw.authority}\n"
        f"Tier: {fw.tier}\n"
        f"Cloud: {fw.cloud}\n"
        f"Category: {fw.category}\n"
        f"Controls: {fw.control_count}\n"
    )
    if fw.description:
        body += f"\n{fw.description}"
    if fw.url:
        body += f"\n[dim]{fw.url}[/dim]"

    console.print(Panel(body, title=f"Framework: {fw.id}", style="cyan"))

    try:
        from complyform.core.profiles.control_loader import load_controls

        cf = load_controls(framework_id)
        sections: dict[str, int] = {}
        for c in cf.controls:
            key = c.section or c.family or "Other"
            sections[key] = sections.get(key, 0) + 1

        if sections:
            sec_table = Table(title="Sections", show_lines=False)
            sec_table.add_column("Section", style="cyan")
            sec_table.add_column("Controls", justify="right")
            for sec, count in sorted(sections.items()):
                sec_table.add_row(sec, str(count))
            console.print(sec_table)
    except Exception:
        console.print("[dim]Controls file not available.[/dim]")


@frameworks_app.command(name="diff")
def frameworks_diff(
    ctx: typer.Context,
    framework_a: Annotated[
        str,
        typer.Argument(help="First framework ID"),
    ],
    framework_b: Annotated[
        str,
        typer.Argument(help="Second framework ID"),
    ],
) -> None:
    """Compare two frameworks side-by-side."""
    app_ctx: AppContext = ctx.obj
    fw_a = get_framework(framework_a)
    fw_b = get_framework(framework_b)

    console = app_ctx.console

    from rich.console import Console
    from rich.table import Table as RichTable

    if not isinstance(console, Console):
        return

    table = RichTable(
        title=f"Comparison: {fw_a.id} vs {fw_b.id}",
        show_lines=True,
    )
    table.add_column("Attribute", style="cyan")
    table.add_column(fw_a.id, style="white")
    table.add_column(fw_b.id, style="white")

    fields = [
        ("Name", fw_a.name, fw_b.name),
        ("Version", fw_a.version, fw_b.version),
        ("Authority", fw_a.authority, fw_b.authority),
        ("Tier", fw_a.tier, fw_b.tier),
        ("Cloud", fw_a.cloud, fw_b.cloud),
        ("Category", fw_a.category, fw_b.category),
        ("Controls", str(fw_a.control_count), str(fw_b.control_count)),
    ]

    for label, val_a, val_b in fields:
        style_a = "green" if val_a == val_b else "yellow"
        style_b = "green" if val_a == val_b else "yellow"
        table.add_row(
            label,
            f"[{style_a}]{val_a}[/{style_a}]",
            f"[{style_b}]{val_b}[/{style_b}]",
        )

    console.print(table)

    from complyform.core.profiles.cross_mappings import get_all

    all_cross = get_all()
    relevant = [
        m
        for m in all_cross
        if (m.source_framework == framework_a and m.target_framework == framework_b)
        or (m.source_framework == framework_b and m.target_framework == framework_a)
    ]

    if relevant:
        console.print(
            f"\n[bold]{len(relevant)}[/bold] cross-mappings found"
            f" between {fw_a.id} and {fw_b.id}"
        )
