"""Tool health-check endpoint and diagnostic helpers."""

import sys
import shutil
from typing import Any

import structlog
from fastapi import APIRouter

from proxym.tools import ToolRegistry

logger = structlog.get_logger()
router = APIRouter(tags=["tools"])


# ── Diagnostic helpers ────────────────────────────────────

from proxym.dashboard.tools.utils._aider_install_fix import _aider_install_fix


def _health_diag_base(tool, tool_providers: dict[str, str]) -> dict[str, Any]:
    return {
        "name": tool.name,
        "category": tool.category.value,
        "available": tool.is_available,
        "binary": tool.binary,
        "binary_found": bool(tool.binary and shutil.which(tool.binary)),
        "provider": tool_providers.get(tool.name, "openrouter"),
        "provider_configured": False,
        "api_key_present": False,
        "docker_instance": False,
        "kvm_instance": False,
        "vm_instance": False,
        "status": "unknown",
        "issues": [],
        "fixes": [],
    }


def _apply_provider_health(diag: dict[str, Any], configured_providers: dict[str, Any]) -> None:
    provider_name = diag["provider"]
    if diag["name"] == "human":
        diag["provider"] = "manual"
        diag["provider_configured"] = True
        diag["api_key_present"] = True
        return

    if provider_name in configured_providers:
        diag["provider_configured"] = True
        diag["api_key_present"] = True
        return

    if "openrouter" in configured_providers and provider_name != "ollama":
        diag["provider_configured"] = True
        diag["api_key_present"] = True
        diag["provider"] = f"{provider_name} (via openrouter)"
        return

    diag["issues"].append(f"Provider '{provider_name}' not configured — no API key")
    diag["fixes"].append({
        "action": "config",
        "label": f"Set {provider_name.upper()}_API_KEY",
        "command": f"export {provider_name.upper()}_API_KEY=<your-key>",
        "description": f"Add API key for {provider_name} in .env or environment",
    })


def _apply_runtime_health(diag: dict[str, Any], tool) -> None:
    if tool.name == "human":
        return

    if tool.binary and not diag["binary_found"]:
        if tool.name == "aider":
            diag["issues"].append(f"{tool.binary} binary not found on PATH")
            diag["fixes"].append(_aider_install_fix())
        elif tool.name == "claude-code":
            diag["issues"].append(f"{tool.binary} binary not found on PATH")
            diag["fixes"].append({
                "action": "install",
                "label": "Install claude-code",
                "command": "npm install -g @anthropic-ai/claude-code",
                "description": "Install Claude Code CLI tool",
            })
        elif tool.name in ("windsurf", "cursor"):
            diag["issues"].append(f"{tool.name} is a desktop IDE — not available in container")
            diag["fixes"].append({
                "action": "info",
                "label": f"{tool.name} runs on host only",
                "command": f"# Install from https://{tool.name}.com — dispatches via echo inside container",
                "description": "Desktop IDE tool — dispatch works but actual execution requires host",
            })

    for inst in tool.instances:
        if inst.kind == "docker" and inst.is_available:
            diag["docker_instance"] = True
            break
        if inst.kind == "kvm" and inst.is_available:
            diag["kvm_instance"] = True
            break
        if inst.kind == "vm" and inst.is_available:
            diag["vm_instance"] = True
            break

    # Check for KVM/VM-based tools that need VM access
    has_vm_instance = any(inst.kind in ("kvm", "vm") for inst in tool.instances)
    if has_vm_instance and not (diag["kvm_instance"] or diag["vm_instance"]):
        vm_inst = next((i for i in tool.instances if i.kind in ("kvm", "vm")), None)
        if vm_inst:
            if vm_inst.vm_name:
                diag["issues"].append(f"KVM VM '{vm_inst.vm_name}' not running")
                diag["fixes"].append({
                    "action": "start_vm",
                    "label": f"Start {vm_inst.vm_name} VM",
                    "command": f"virsh start {vm_inst.vm_name}" if shutil.which("virsh") else f"# Start VM {vm_inst.vm_name} via your hypervisor",
                    "description": f"Start the KVM virtual machine '{vm_inst.vm_name}' for {tool.name}",
                })
            elif vm_inst.vm_host:
                diag["issues"].append(f"VM at {vm_inst.vm_host} not reachable via SSH")
                diag["fixes"].append({
                    "action": "info",
                    "label": "Check VM SSH access",
                    "command": f"# Ensure VM at {vm_inst.vm_host} is running and accessible via SSH",
                    "description": f"VM host {vm_inst.vm_host} not reachable. Check VM status and SSH connectivity.",
                })

    if tool.name in ("vscode", "roo-code", "cline") and not diag["docker_instance"]:
        diag["issues"].append("Docker-backed VS Code container not running")
        diag["fixes"].append({
            "action": "start_container",
            "label": "Start VS Code container",
            "command": "docker compose --profile vscode up -d",
            "description": "Start the VS Code Web container used by roo-code, cline, and vscode tools",
        })

    if tool.name == "browser" and not diag["docker_instance"]:
        diag["issues"].append("Open WebUI container not running")
        diag["fixes"].append({
            "action": "start_container",
            "label": "Start Open WebUI",
            "command": "docker compose --profile webui up -d",
            "description": "Start the browser-based chat container",
        })


def _finalize_health_status(diag: dict[str, Any]) -> None:
    if not diag["issues"]:
        diag["status"] = "ok"
    elif diag["available"] or diag["provider_configured"]:
        diag["status"] = "degraded"
    else:
        diag["status"] = "unavailable"


# ── Endpoint ─────────────────────────────────────────────

@router.get("/healthcheck")
async def tools_healthcheck() -> dict[str, Any]:
    """Comprehensive health check for every registered tool.

    For each tool returns: binary available, provider configured,
    api key present, docker instance available, and actionable diagnosis.
    """
    from proxym.config import get_settings
    settings = get_settings()
    configured_providers = settings.available_providers()
    tool_providers = settings.tool_providers
    reg = ToolRegistry.get()

    results = []
    total_ok = 0
    total_degraded = 0
    total_unavailable = 0

    for tool in reg.list_tools():
        diag = _health_diag_base(tool, tool_providers)
        _apply_provider_health(diag, configured_providers)
        _apply_runtime_health(diag, tool)
        _finalize_health_status(diag)

        if diag["status"] == "ok":
            total_ok += 1
        elif diag["status"] == "degraded":
            total_degraded += 1
        else:
            total_unavailable += 1

        results.append(diag)

    return {
        "tools": results,
        "summary": {
            "total": len(results),
            "ok": total_ok,
            "degraded": total_degraded,
            "unavailable": total_unavailable,
        },
        "providers_configured": list(configured_providers.keys()),
        "tool_providers": tool_providers,
    }
