"""Skill installation for local MCP clients — ported from yt-mcp's skills.ts."""

from __future__ import annotations

import shutil
from pathlib import Path

from .openclaw import _is_openclaw_likely_installed, get_openclaw_config_path


def get_skill_install_targets(
    *,
    skill_name: str,
    source_dir: Path | str,
    home_dir: Path | str | None = None,
    available_cli_names: list[str] | None = None,
    include_openclaw: bool = False,
) -> list[dict[str, str]]:
    """Build a list of skill installation targets for all detected CLIs.
    
    Args:
        skill_name: Skill name (e.g., "use-reddit-mcp")
        source_dir: Path to the skill source directory
        home_dir: Home directory (defaults to Path.home())
        available_cli_names: Explicit list of available CLI names; defaults to binaries found on PATH
        include_openclaw: Whether to include OpenClaw in targets
    
    Returns:
        List of target dicts with keys: client, label, source_dir, target_dir
    """
    if home_dir is None:
        home_dir = Path.home()
    else:
        home_dir = Path(home_dir)
    
    source_dir = Path(source_dir)
    targets = []
    if available_cli_names is None:
        # Why: only create skill directories for CLIs that actually exist; otherwise setup manufactures ghost internal dirs.
        available_cli_names = [
            cli_name
            for cli_name in ("claude-internal", "claude", "codex-internal", "codex", "gemini-internal", "gemini")
            if shutil.which(cli_name)
        ]
        if include_openclaw and _is_openclaw_likely_installed(get_openclaw_config_path(home_dir)):
            available_cli_names.append("openclaw")
    available_cli_names = list(dict.fromkeys(available_cli_names))

    cli_targets = [
        {"client": "claude-internal", "label": "Claude Code (internal)", "dir": home_dir / ".claude-internal" / "skills"},
        {"client": "claude", "label": "Claude Code", "dir": home_dir / ".claude" / "skills"},
        {"client": "codex-internal", "label": "Codex CLI (internal)", "dir": home_dir / ".codex-internal" / "skills"},
        {"client": "codex", "label": "Codex CLI / Codex App", "dir": home_dir / ".codex" / "skills"},
        {"client": "gemini-internal", "label": "Gemini CLI (internal)", "dir": home_dir / ".gemini-internal" / "skills"},
        {"client": "gemini", "label": "Gemini CLI", "dir": home_dir / ".gemini" / "skills"},
    ]

    for cli_target in cli_targets:
        if cli_target["client"] not in available_cli_names:
            continue
        targets.append({
            "client": cli_target["client"],
            "label": cli_target["label"],
            "source_dir": str(source_dir),
            "target_dir": str(cli_target["dir"] / skill_name),
        })

    if include_openclaw and "openclaw" in available_cli_names:
        openclaw_skills_dir = home_dir / ".openclaw" / "skills"
        targets.append({
            "client": "openclaw",
            "label": "OpenClaw",
            "source_dir": str(source_dir),
            "target_dir": str(openclaw_skills_dir / skill_name),
        })

    return targets


def install_skill_target(target: dict[str, str]) -> None:
    """Install a skill to a single target location.
    
    Args:
        target: Target dict with source_dir and target_dir
    """
    source_dir = Path(target["source_dir"])
    target_dir = Path(target["target_dir"])

    if not source_dir.exists():
        raise FileNotFoundError(f"Bundled skill not found: {source_dir}")

    # Create parent, remove old, copy new
    target_dir.parent.mkdir(parents=True, exist_ok=True)
    if target_dir.exists():
        shutil.rmtree(target_dir)
    shutil.copytree(source_dir, target_dir)


def install_skills(
    *,
    skill_name: str,
    source_dir: Path | str,
    home_dir: Path | str | None = None,
    available_cli_names: list[str] | None = None,
    include_openclaw: bool = False,
) -> None:
    """Install a skill to all detected CLI targets.
    
    Args:
        skill_name: Skill name (e.g., "use-reddit-mcp")
        source_dir: Path to the skill source directory in the package
        home_dir: Home directory (defaults to Path.home())
        available_cli_names: Explicit list of available CLI names; defaults to binaries found on PATH
        include_openclaw: Whether to include OpenClaw in installation
    """
    targets = get_skill_install_targets(
        skill_name=skill_name,
        source_dir=source_dir,
        home_dir=home_dir,
        available_cli_names=available_cli_names,
        include_openclaw=include_openclaw,
    )

    for target in targets:
        try:
            install_skill_target(target)
            print(f"  OK Installed skill to {target['label']}: {target['target_dir']}")
        except Exception as e:
            print(f"  WARN Failed to install skill to {target['label']}: {e}")
