"""Environment variable management command."""

from __future__ import annotations

import logging
import os
import shutil

import click

from ..utils.console import get_console
from ..utils.env_detector import ASCEND_CRITICAL_VARS, EnvInitializer, check_ascend_env_parity

logger = logging.getLogger(__name__)


@click.group(hidden=True)
def env() -> None:
    """Manage sageLLM environment variables.

    \b
    Examples:
        sagellm env show               # Show current environment variables
        sagellm env export             # Export as shell commands
        sagellm env check-ascend       # Audit Ascend env parity with set_env.sh
        eval "$(sagellm env export)"   # Apply to current shell session
    """
    pass


@env.command()
def show() -> None:
    """Show current sageLLM environment variables."""
    console = get_console()
    env_info = EnvInitializer.get_env_info()

    console.print("[bold]📋 sageLLM 环境变量[/bold]\n")

    for category, vars_dict in env_info.items():
        console.print(f"[bold cyan]{category}[/bold cyan]:")
        for var_name, var_value in vars_dict.items():
            console.print(f"  {var_name}={var_value}")
        console.print()


@env.command()
def export() -> None:
    """Export environment variables as shell commands.

    Output can be sourced in a shell:
        eval "$(sagellm env export)"
    """
    env_info = EnvInitializer.get_env_info()

    # Flatten the nested dict
    all_vars = {}
    for _category, vars_dict in env_info.items():
        all_vars.update(vars_dict)

    # Output as shell export commands (without color codes)
    # This is meant to be sourced, so we output raw text
    for var_name, var_value in sorted(all_vars.items()):
        if var_value and var_value != "Not set":
            # Properly escape for shell
            escaped_value = var_value.replace('"', '\\"')
            print(f'export {var_name}="{escaped_value}"')


@env.command()
def init() -> None:
    """Explicitly initialize all environment variables with network detection.

    This performs actual network connectivity tests to determine the best
    HuggingFace endpoint. Use this when you want to refresh the configuration.
    """
    console = get_console()

    console.print("[cyan]🔄 正在检测环境变量...[/cyan]")
    console.print()

    # Show network detection process
    from ..utils.env_detector import NetworkDetector

    console.print(
        f"[cyan]🔍 检测 HuggingFace 官方端点 (超时: {NetworkDetector.TIMEOUT}s)...[/cyan]"
    )
    official_ok = NetworkDetector.check_connectivity(
        NetworkDetector.HF_OFFICIAL, timeout=NetworkDetector.TIMEOUT
    )
    if official_ok:
        console.print(f"✅ 官方端点可达: {NetworkDetector.HF_OFFICIAL}")
        os.environ["HF_ENDPOINT"] = NetworkDetector.HF_OFFICIAL
    else:
        console.print("⚠️  官方端点不可达，使用镜像")
        console.print(f"🪞 镜像: {NetworkDetector.HF_MIRROR}")
        os.environ["HF_ENDPOINT"] = NetworkDetector.HF_MIRROR

    # Initialize other env vars (no network needed)
    EnvInitializer.init_hf_cache_dir()
    EnvInitializer.init_model_cache_dir()
    EnvInitializer.init_logging_level()

    # Save to profile
    EnvInitializer.save_env_profile()

    console.print()
    console.print("[green]✅ 环境变量已检测并保存[/green]")
    console.print()

    # Show the snapshot
    env_info = EnvInitializer.get_env_info()
    for _category, vars_dict in env_info.items():
        for var_name, var_value in vars_dict.items():
            console.print(f"  [cyan]{var_name}[/cyan] = [green]{var_value}[/green]")

    console.print()
    console.print("[dim]💡 提示：运行以下命令将环境变量导入到当前 shell：[/dim]")
    console.print('  [cyan]eval "$(sagellm env export)"[/cyan]')


# ---------------------------------------------------------------------------
# env check-ascend
# ---------------------------------------------------------------------------

_STATUS_ICON: dict[str, str] = {
    "ok": "✅ OK          ",
    "missing": "❌ MISSING     ",
    "abnormal": "⚠️  ABNORMAL    ",
    "optional-absent": "➖ ABSENT(opt) ",
    "no-toolkit": "❌ NO-TOOLKIT  ",
}

_STATUS_COLOR: dict[str, str] = {
    "ok": "green",
    "missing": "red",
    "abnormal": "yellow",
    "optional-absent": "dim",
    "no-toolkit": "red",
}


@env.command("check-ascend")
def check_ascend() -> None:
    """Audit Ascend env variable parity with the set_env.sh baseline.

    \b
    Checks the critical Ascend variables:
        ASCEND_HOME, ASCEND_TOOLKIT_HOME, ASCEND_RUNTIME_PATH,
        ASCEND_OPP_PATH, ASCEND_AICPU_PATH, ASCEND_PLUGIN_HOME,
        PYTHONPATH, LD_LIBRARY_PATH

    Each variable is reported as OK / MISSING / ABNORMAL with a suggested
    repair command where applicable.  Exits with code 1 when any mandatory
    variable is unhealthy; exits 0 when all are healthy.

    \b
    Examples:
        sagellm env check-ascend
        sagellm ascend fix        # auto-repair after reviewing suggestions
        sagellm ascend doctor     # generate a complete sudo repair script
    """
    console = get_console()

    if shutil.which("npu-smi") is None:
        console.print(
            "[yellow]⚠️  npu-smi not found — not an Ascend machine "
            "or NPU driver not installed.[/yellow]"
        )
        console.print("[dim]Skipping Ascend env parity check.[/dim]")
        return

    console.print("\n[bold blue]🔍 Ascend Environment Parity Check[/bold blue]")
    console.print(
        "[dim]Comparing live environment against set_env.sh baseline "
        f"({len(ASCEND_CRITICAL_VARS)} variables)...[/dim]\n"
    )

    checks = check_ascend_env_parity()

    issues = []
    for chk in checks:
        icon = _STATUS_ICON.get(chk.status, chk.status)
        color = _STATUS_COLOR.get(chk.status, "white")
        console.print(f"  [{color}]{icon}[/{color}] [bold]{chk.name}[/bold]")

        if chk.status == "ok":
            val = (chk.current or "")[:100]
            console.print(f"             [dim]{val}[/dim]")
        else:
            if chk.current is not None:
                console.print(f"             current:  [dim]{chk.current[:100]}[/dim]")
            if chk.expected is not None:
                console.print(f"             expected: [cyan]{chk.expected[:100]}[/cyan]")
            if chk.status in ("missing", "abnormal", "no-toolkit"):
                issues.append(chk)

    mandatory_issues = [c for c in issues if c.status in ("missing", "abnormal", "no-toolkit")]

    if not mandatory_issues:
        console.print("\n[green]✅ All critical Ascend env variables are healthy.[/green]")
        return

    console.print(f"\n[red]❌ {len(mandatory_issues)} variable(s) need repair:[/red]\n")
    for chk in mandatory_issues:
        console.print(
            f"  [bold]{chk.name}[/bold]  [{_STATUS_COLOR[chk.status]}]({chk.status})[/{_STATUS_COLOR[chk.status]}]"
        )
        if chk.repair:
            console.print(f"    [cyan]{chk.repair}[/cyan]")
        else:
            console.print("    [dim]No automatic repair — check Ascend toolkit installation.[/dim]")

    console.print()
    console.print("[dim]💡 Repair options:[/dim]")
    console.print("  [cyan]sagellm ascend fix[/cyan]        # auto-repair env + symlinks")
    console.print("  [cyan]sagellm ascend doctor[/cyan]     # generate a full sudo repair script")
    raise SystemExit(1)
