"""Empfehlungs-Regeln: system-zustand → konkrete Pakete."""
from __future__ import annotations

from dataclasses import dataclass

from taninux.core import sysinfo


@dataclass
class Suggestion:
    category: str           # 'gpu', 'dev', 'shell', 'audio'
    reason: str             # human-readable description (why), EN
    packages: list[str]     # what would be installed
    priority: int = 1       # 1 high, 2 medium, 3 nice-to-have
    title: str = ""         # short title (what), EN


# ---- GPU ----

GPU_DRIVERS = {
    "nvidia": {
        "primary": ["nvidia", "nvidia-utils", "nvidia-settings"],
        "open": ["nvidia-open", "nvidia-utils"],
        "extras": ["cuda", "nvtop"],
    },
    "amd": {
        "primary": ["mesa", "vulkan-radeon", "libva-mesa-driver"],
        "extras": ["radeontop", "lact"],
    },
    "intel": {
        "primary": ["mesa", "vulkan-intel", "intel-media-driver"],
        "extras": ["intel-gpu-tools"],
    },
}


def suggest_gpu(installed: set[str]) -> list[Suggestion]:
    out: list[Suggestion] = []
    for gpu in sysinfo.gpus():
        drivers = GPU_DRIVERS.get(gpu.vendor)
        if not drivers:
            continue
        missing_primary = [p for p in drivers["primary"] if p not in installed]
        if missing_primary:
            out.append(Suggestion(
                category="gpu",
                title=f"{gpu.vendor.upper()} graphics drivers",
                reason=f"{gpu.vendor.upper()} GPU detected ({gpu.model[:50]}) — primary drivers are missing",
                packages=missing_primary,
                priority=1,
            ))
        missing_extra = [p for p in drivers.get("extras", []) if p not in installed]
        if missing_extra and not missing_primary:
            out.append(Suggestion(
                category="gpu",
                title=f"{gpu.vendor.upper()} GPU extras",
                reason="Optional tools for your GPU (monitoring, tuning)",
                packages=missing_extra,
                priority=3,
            ))
    return out


# ---- dev environments ----

DEV_ECOSYSTEMS = {
    "rust": {
        "trigger_binary": "cargo",
        "trigger_pkg": "rust",
        "missing": [
            ("rust-analyzer", "LSP für editor-integration"),
            ("sccache", "compile cache, beschleunigt rebuilds"),
            ("cargo-audit", "security-audit für deps"),
        ],
    },
    "go": {
        "trigger_binary": "go",
        "trigger_pkg": "go",
        "missing": [
            ("gopls", "LSP für editor-integration"),
            ("delve", "debugger"),
        ],
    },
    "node": {
        "trigger_binary": "node",
        "trigger_pkg": "nodejs",
        "missing": [
            ("typescript", "TS compiler"),
            ("pnpm", "schnellerer package-manager"),
        ],
    },
    "python": {
        "trigger_binary": "python",
        "trigger_pkg": "python",
        "missing": [
            ("uv", "schneller dependency-manager"),
            ("ruff", "schneller linter/formatter"),
            ("ipython", "besseres REPL"),
        ],
    },
}


def suggest_dev(installed: set[str]) -> list[Suggestion]:
    out: list[Suggestion] = []
    for eco_name, eco in DEV_ECOSYSTEMS.items():
        trigger = eco["trigger_pkg"] in installed or sysinfo.has_binary(eco["trigger_binary"])
        if not trigger:
            continue
        missing = [
            (pkg, why) for pkg, why in eco["missing"] if pkg not in installed
        ]
        if missing:
            out.append(Suggestion(
                category="dev",
                title=f"{eco_name.capitalize()} tooling",
                reason=f"{eco_name} stack detected — complementary tools are missing",
                packages=[p for p, _ in missing],
                priority=2,
            ))
    return out


# ---- modern shell tooling ----

MODERN_CLI = [
    ("bat", "syntax-highlighted cat-ersatz"),
    ("eza", "modernes ls mit icons + git-status"),
    ("fd", "user-friendly find-ersatz"),
    ("ripgrep", "schnelles grep"),
    ("fzf", "fuzzy finder"),
    ("zoxide", "smarter cd"),
    ("dust", "rust-basiertes du"),
    ("bottom", "moderner top/htop"),
    ("starship", "shell-prompt"),
]


def suggest_shell(installed: set[str]) -> list[Suggestion]:
    missing = [pkg for pkg, _ in MODERN_CLI if pkg not in installed]
    if not missing:
        return []
    return [Suggestion(
        category="shell",
        title="Modern CLI tools",
        reason=f"{len(missing)} quality-of-life terminal tools are missing",
        packages=missing,
        priority=3,
    )]


# ---- aggregate ----


def all_suggestions(installed: set[str]) -> list[Suggestion]:
    return [
        *suggest_gpu(installed),
        *suggest_dev(installed),
        *suggest_shell(installed),
    ]
