"""ievo add — install agent(s) from marketplace."""

from __future__ import annotations

import asyncio
import shutil
from pathlib import Path

import typer

from ievo.core.config import CLAUDE_AGENTS_DIR, require_project
from ievo.core.project import ProjectManifest
from ievo.core.registry import Registry
from ievo.marketplace import bundled_agent_path
from ievo.utils.console import info, step, success, warn


def add_agents(agents: list[str]) -> None:
    """Internal API: install agent(s). Called programmatically by HR agent."""
    root = require_project()
    manifest = ProjectManifest.load(root)
    asyncio.run(_add_agents(root, manifest, agents))


def add(
    agents: list[str] = typer.Argument(
        help="Agent name(s) to install, e.g. spec-writer architect coder",
    ),
) -> None:
    """[DEPRECATED] Install agent(s) from the iEvo marketplace."""
    from ievo.utils.deprecation import deprecated_command

    deprecated_command("ievo add", alternative="the HR agent (automatic agent composition)")
    add_agents(agents)


async def _add_agents(root: Path, manifest: ProjectManifest, agents: list[str]) -> None:
    registry = Registry.load_cached()

    info("Resolving dependencies...")
    await registry.fetch()

    installed_count = 0

    for agent_name in agents:
        if manifest.has_agent(agent_name):
            warn(f"{agent_name} already installed, skipping.")
            continue

        entry = registry.get(agent_name)
        if not entry:
            warn(f"{agent_name} not found in registry cache, trying direct download...")

        # Resolve dependencies
        if entry and entry.dependencies:
            for dep in entry.dependencies:
                dep_name = dep.split("@")[0]  # strip version spec
                if not manifest.has_agent(dep_name):
                    step(f"Dependency: {dep_name} required")
                    await _install_single(root, manifest, registry, dep_name)

        await _install_single(root, manifest, registry, agent_name)
        installed_count += 1

    if installed_count > 0:
        manifest.save(root)
        success(f"{installed_count} agent(s) installed.")
    else:
        info("Nothing to install.")


async def _install_single(
    root: Path,
    manifest: ProjectManifest,
    registry: Registry,
    name: str,
) -> None:
    """Install a single agent as a ``.md`` file to ``.claude/agents/``."""
    dest_dir = root / CLAUDE_AGENTS_DIR
    dest_dir.mkdir(parents=True, exist_ok=True)
    dest_file = dest_dir / f"{name}.md"

    entry = registry.get(name)
    version = entry.version if entry else "0.1.0"

    # Source priority: bundled -> GitHub download -> placeholder
    bundled = bundled_agent_path(name)
    if bundled:
        shutil.copy2(bundled, dest_file)
    elif not await registry.download_agent_md(name, dest_dir):
        _create_placeholder_agent(dest_file, name)

    manifest.add_agent(name, version)
    desc = entry.description if entry else ""
    success(f"{name}@{version} {f'— {desc}' if desc else ''}")


def _create_placeholder_agent(dest_file: Path, name: str) -> None:
    """Create a minimal placeholder agent ``.md`` when all sources fail."""
    dest_file.write_text(
        f"---\nname: {name}\ndescription: Placeholder agent\nmodel: sonnet\n---\n\n"
        f"# {name}\n\nPlaceholder. Install from marketplace for full agent.\n"
    )
