"""Arch command - Architecture conformance check."""

from __future__ import annotations

import logging
import sys

import click

from ..utils.console import get_console

logger = logging.getLogger(__name__)


@click.command(hidden=True)
@click.option("--verbose", "-v", is_flag=True, help="Verbose output")
@click.option("--repo", type=str, multiple=True, help="Specific repo to check (repeatable)")
def arch(verbose: bool, repo: tuple[str, ...]) -> None:
    """Check architecture conformance across sageLLM packages.

    \b
    Examples:
    sagellm arch                      # Check all packages
    sagellm arch -v                   # Verbose output
    sagellm arch --repo isagellm-backend    # Check specific package

    \b
    This command verifies:
      1. Dependency hierarchy is correct
      2. No circular imports
      3. Component interfaces are complete
      4. Component trace is properly implemented
    """
    console = get_console()
    from rich.panel import Panel

    console.print()
    console.print(
        Panel.fit(
            "[bold blue]sageLLM Architecture Check[/bold blue]",
            border_style="blue",
        )
    )
    console.print()

    # Run architecture checks
    all_passed = True
    repos_to_check = list(repo) if repo else None

    # Check dependency hierarchy
    all_passed = _check_dependency_hierarchy(console, repos_to_check, verbose) and all_passed

    # Check component interfaces
    all_passed = _check_component_interfaces(console, verbose) and all_passed

    # Check component trace implementation
    all_passed = _check_component_trace(console, verbose) and all_passed

    # Summary
    console.print()
    if all_passed:
        console.print("[bold green]🎉 All architecture checks passed![/bold green]")
        console.print()
        console.print("[dim]Run integration tests for full verification:[/dim]")
        console.print("  [cyan]pytest tests/test_integration.py -v[/cyan]")
        console.print("  [cyan]pytest tests/test_architecture.py -v[/cyan]")
        console.print()
    else:
        console.print("[bold red]❌ Architecture violations found![/bold red]")
        console.print("[dim]Fix the issues above before committing.[/dim]")
        console.print()
        sys.exit(1)


def _check_dependency_hierarchy(console, repos: list[str] | None, verbose: bool) -> bool:
    """Check dependency hierarchy."""
    import importlib.metadata

    console.print("[bold cyan]📦 Checking dependency hierarchy...[/bold cyan]")

    # Define hierarchy
    hierarchy = {
        "isagellm-protocol": {
            "level": 0,
            "allowed": [],
        },
        "isagellm-backend": {
            "level": 1,
            "allowed": ["isagellm-protocol"],
        },
        "isagellm-core": {
            "level": 2,
            "allowed": ["isagellm-protocol", "isagellm-backend"],
        },
        "isagellm-control-plane": {
            "level": 3,
            "allowed": ["isagellm-protocol", "isagellm-core"],
        },
        "isagellm-gateway": {
            "level": 4,
            "allowed": ["isagellm-protocol", "isagellm-control-plane"],
        },
    }

    all_ok = True
    packages = repos if repos else list(hierarchy.keys())

    for pkg_name in packages:
        if pkg_name not in hierarchy:
            continue

        info = hierarchy[pkg_name]
        allowed = info["allowed"]

        try:
            dist = importlib.metadata.distribution(pkg_name)
            requires = dist.requires or []

            violations = []
            for req in requires:
                # Skip dev/test extras (they have ; extra == "dev" etc)
                if "; extra ==" in req or ";extra==" in req:
                    continue

                dep_name = req.split()[0].split(";")[0].split("[")[0]
                dep_name = dep_name.split(">")[0].split("<")[0].split("=")[0]

                if dep_name.startswith("isagellm") and dep_name not in allowed:
                    violations.append(dep_name)

            if violations:
                console.print(f"  [red]❌ {pkg_name} (level {info['level']})[/red]")
                for v in violations:
                    console.print(f"     [red]Invalid dep: {v}[/red]")
                all_ok = False
            else:
                console.print(f"  [green]✅ {pkg_name} (level {info['level']})[/green]")

        except importlib.metadata.PackageNotFoundError:
            if verbose:
                console.print(f"  [dim]○ {pkg_name} not installed[/dim]")

    return all_ok


def _check_component_interfaces(console, verbose: bool) -> bool:
    """Check component interfaces are complete."""
    console.print("[bold cyan]🔌 Checking component interfaces...[/bold cyan]")

    all_ok = True

    try:
        from sagellm_core import LLMEngine

        required_methods = ["start", "stop", "execute", "stream", "generate"]
        required_props = ["engine_id", "is_running"]

        for engine_cls in [LLMEngine]:
            missing = []
            for m in required_methods:
                if not hasattr(engine_cls, m):
                    missing.append(m)
            for p in required_props:
                if not hasattr(engine_cls, p):
                    missing.append(p)

            if missing:
                console.print(f"  [red]❌ {engine_cls.__name__}[/red]")
                console.print(f"     [red]Missing: {missing}[/red]")
                all_ok = False
            else:
                console.print(f"  [green]✅ {engine_cls.__name__} interface complete[/green]")

    except ImportError as e:
        if verbose:
            console.print(f"  [yellow]⚠️  Could not check engines: {e}[/yellow]")

    # Check backend registry
    try:
        from sagellm_backend.registry import get_available_backends

        backends = get_available_backends()

        if backends:
            console.print(f"  [green]✅ Available backends: {backends}[/green]")
        else:
            console.print("  [red]❌ No backends available[/red]")
            all_ok = False

    except Exception as e:
        if verbose:
            console.print(f"  [yellow]⚠️  Backend check failed: {e}[/yellow]")

    return all_ok


def _check_component_trace(console, verbose: bool) -> bool:
    """Check component trace implementation."""
    console.print("[bold cyan]📊 Checking component trace...[/bold cyan]")

    all_ok = True

    # Check Metrics has component_trace field
    try:
        from sagellm_protocol import Metrics

        if "component_trace" in Metrics.model_fields:
            console.print("  [green]✅ Metrics.component_trace field exists[/green]")
        else:
            console.print("  [red]❌ Metrics missing component_trace field[/red]")
            all_ok = False

    except ImportError as e:
        console.print(f"  [red]❌ Could not import Metrics: {e}[/red]")
        all_ok = False

    # Check LLMEngine works
    try:
        from sagellm_core.llm_engine import LLMEngine, LLMEngineConfig

        config = LLMEngineConfig(model_path="sshleifer/tiny-gpt2", backend_type="cpu")
        _ = LLMEngine(config)
        console.print("  [green]✅ LLMEngine can be instantiated[/green]")

    except ImportError as e:
        if verbose:
            console.print(f"  [yellow]⚠️  Could not check LLMEngine: {e}[/yellow]")

    return all_ok
