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

from __future__ import annotations

import asyncio
from pathlib import Path

import typer

from ievo.core.agent import AgentPackage
from ievo.core.config import AGENTS_DIR, require_project
from ievo.core.deps import McpType
from ievo.core.project import ProjectManifest
from ievo.core.registry import Registry
from ievo.utils.console import info, step, success, warn


def add(
    agents: list[str] = typer.Argument(
        help="Agent name(s) to install, e.g. spec-writer architect coder",
    ),
) -> None:
    """Install agent(s) from the iEvo marketplace."""
    root = require_project()
    manifest = ProjectManifest.load(root)

    asyncio.run(_add_agents(root, manifest, 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:
            # If not in registry, try to download anyway (marketplace may be ahead of cache)
            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")
                    # Recursively install dependency
                    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. EVO skill included in each.")
        # Check extension deps for newly installed agents
        _print_dep_summary(root, agents)
    else:
        info("Nothing to install.")


async def _install_single(
    root: Path,
    manifest: ProjectManifest,
    registry: Registry,
    name: str,
) -> None:
    """Install a single agent."""
    dest = root / AGENTS_DIR / name
    entry = registry.get(name)
    version = entry.version if entry else "0.1.0"

    downloaded = await registry.download_agent(name, dest)

    if not downloaded:
        # Create minimal local agent structure
        _create_local_agent(dest, name, version)

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


def _create_local_agent(dest: Path, name: str, version: str) -> None:
    """Create minimal agent structure locally when marketplace is unavailable."""
    import yaml

    dest.mkdir(parents=True, exist_ok=True)
    (dest / "memory").mkdir(exist_ok=True)
    (dest / "skills" / "evo").mkdir(parents=True, exist_ok=True)

    # agent.yaml
    agent_data = {
        "name": name,
        "version": version,
        "description": "",
        "author": "local",
        "model": {"primary": "sonnet", "fallback": "haiku"},
        "dependencies": [],
        "mcp": [],
        "plugins": [],
        "skills": ["evo"],
        "hooks": {
            "on_install": None,
            "on_session_start": "load_memory",
            "on_session_end": "save_memory",
            "on_error": "evo_analyze",
        },
        "disclosure": {"metadata": 100, "instructions": 400, "resources": 600},
    }
    (dest / "agent.yaml").write_text(
        yaml.dump(agent_data, default_flow_style=False, sort_keys=False)
    )

    # Empty ROLE.md
    (dest / "ROLE.md").write_text(f"# {name}\n\n<!-- Define agent instructions here -->\n")

    # Memory files
    for mf in ["CONTEXT.md", "DECISIONS.md", "VOCABULARY.md", "HISTORY.md"]:
        (dest / "memory" / mf).write_text(f"# {mf.replace('.md', '')}\n\n")

    # EVO skill placeholder
    (dest / "skills" / "evo" / "SKILL.md").write_text(
        "# EVO Skill\n\n"
        "## Workflow\n"
        "1. Identify error\n"
        "2. Classify: code / process / communication / safety / style\n"
        "3. Root cause analysis\n"
        "4. Formulate actionable rule\n"
        "5. Propose ROLE.md update (get user approval)\n"
        "6. Apply update\n"
        "7. Log to EVOLUTION_LOG.md\n"
        "8. Confirm understanding\n"
    )

    # EVOLUTION_LOG.md
    (dest / "EVOLUTION_LOG.md").write_text("# Evolution Log\n\n")


def _print_dep_summary(root: Path, agent_names: list[str]) -> None:
    """Print summary of MCP/plugin dependencies after agent install."""
    has_deps = False
    for name in agent_names:
        agent_dir = root / AGENTS_DIR / name
        try:
            pkg = AgentPackage.load(agent_dir)
        except FileNotFoundError:
            continue

        non_builtin_mcp = [m for m in pkg.mcp if m.type != McpType.BUILTIN]
        if non_builtin_mcp or pkg.plugins:
            if not has_deps:
                info("Extension dependencies detected:")
                has_deps = True

            for m in non_builtin_mcp:
                step(f"MCP: {m.name} ({m.type.value}: {m.package or m.url})")

            for p in pkg.plugins:
                step(f"Plugin: {p.name} ({p.marketplace})")

    if has_deps:
        info("Run [bold]ievo deps install[/bold] to configure.")
