"""Environment diagnostic command (``hla-compass doctor``)."""

from __future__ import annotations

import json
import subprocess
import sys
from pathlib import Path

import click
from rich.table import Table

from ..auth import Auth
from ..config import Config
from ..signing import ModuleSigner
from .utils import _ensure_verbose, console, verbose_option


def _check_python_version() -> tuple[str, str]:
    v = sys.version_info
    version_str = f"{v.major}.{v.minor}.{v.micro}"
    if v >= (3, 11):
        return "ok", f"Python {version_str}"
    return "fail", f"Python {version_str} (3.11+ required)"


def _check_docker() -> tuple[str, str]:
    try:
        result = subprocess.run(
            ["docker", "version", "--format", "{{.Server.Version}}"],
            capture_output=True,
            text=True,
            timeout=10,
        )
        if result.returncode == 0:
            version = result.stdout.strip()
            return "ok", f"Docker {version}"
        return "warn", "Docker daemon not running"
    except FileNotFoundError:
        return "warn", "Docker not installed (required for build/test)"
    except Exception as exc:
        return "warn", f"Docker check failed: {exc}"


def _check_sdk_version() -> tuple[str, str]:
    from .._version import __version__

    return "ok", f"hla-compass {__version__}"


def _check_auth() -> tuple[str, str]:
    try:
        auth = Auth()
        has_token = auth.is_authenticated()
        api_key = bool(Config.get_api_key())

        if has_token and api_key:
            return "ok", "Authenticated (token + API key)"
        if has_token:
            return "ok", "Authenticated (token)"
        if api_key:
            return "ok", "Authenticated (API key)"
        return "warn", "Not authenticated — run: hla-compass auth login"
    except Exception as exc:
        return "warn", f"Auth check failed: {exc}"


def _check_signing_keys() -> tuple[str, str]:
    try:
        signer = ModuleSigner()
        fp = signer.get_key_fingerprint()
        return "ok", f"Signing keys found ({fp[:16]}...)"
    except FileNotFoundError:
        return "warn", "No signing keys — run: hla-compass keys init"
    except Exception as exc:
        return "warn", f"Key check failed: {exc}"


def _check_manifest() -> tuple[str, str]:
    manifest_path = Path.cwd() / "manifest.json"
    if not manifest_path.exists():
        return "info", "No manifest.json in current directory"
    try:
        manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
        name = manifest.get("name", "?")
        version = manifest.get("version", "?")
        return "ok", f"manifest.json: {name} v{version}"
    except json.JSONDecodeError:
        return "fail", "manifest.json is not valid JSON"
    except Exception as exc:
        return "fail", f"manifest.json error: {exc}"


def _check_environment() -> tuple[str, str]:
    env = Config.get_environment()
    endpoint = Config.get_api_endpoint()
    return "ok", f"Environment: {env} ({endpoint})"


_STATUS_STYLE = {
    "ok": "[green]ok[/green]",
    "warn": "[yellow]warn[/yellow]",
    "fail": "[red]FAIL[/red]",
    "info": "[dim]info[/dim]",
}


@click.command()
@verbose_option
@click.pass_context
def doctor(ctx):
    """Check your development environment for common issues."""
    _ensure_verbose(ctx)

    checks = [
        ("Python", _check_python_version),
        ("Docker", _check_docker),
        ("SDK version", _check_sdk_version),
        ("Environment", _check_environment),
        ("Authentication", _check_auth),
        ("Signing keys", _check_signing_keys),
        ("Manifest", _check_manifest),
    ]

    table = Table(title="HLA-Compass Doctor", show_lines=False)
    table.add_column("Check", style="cyan", no_wrap=True)
    table.add_column("Status", no_wrap=True)
    table.add_column("Details")

    has_failures = False
    has_warnings = False
    for label, check_fn in checks:
        status, detail = check_fn()
        table.add_row(label, _STATUS_STYLE.get(status, status), detail)
        if status == "fail":
            has_failures = True
        elif status == "warn":
            has_warnings = True

    console.print(table)

    if has_failures:
        console.print("\n[red]Some checks failed. Fix the issues above and re-run.[/red]")
        raise SystemExit(1)
    if has_warnings:
        console.print("\n[yellow]Checks completed with warnings. Review the items above.[/yellow]")
    else:
        console.print("\n[green]All checks passed.[/green]")
