"""Custom agents loader from .emdash/agents/*.md files.

This module loads user-defined agent personalities from markdown files
and makes them available for the CLI to switch between.
"""

from pathlib import Path
from typing import Optional
from dataclasses import dataclass

from emdash.utils.logger import log


@dataclass
class CustomAgent:
    """A custom agent definition."""

    name: str  # Filename without .md
    description: str  # First line of file (or first # heading)
    prompt: str  # Full markdown content


def get_agents_dir(repo_root: Optional[Path] = None) -> Path:
    """Get the agents directory path.

    Args:
        repo_root: Repository root. Uses cwd if not provided.

    Returns:
        Path to .emdash/agents/
    """
    if repo_root is None:
        repo_root = Path.cwd()
    return repo_root / ".emdash" / "agents"


def list_agents(repo_root: Optional[Path] = None) -> list[CustomAgent]:
    """List all available custom agents.

    Args:
        repo_root: Repository root directory. Uses cwd if not provided.

    Returns:
        List of CustomAgent objects, sorted by name.
    """
    agents_dir = get_agents_dir(repo_root)

    if not agents_dir.exists():
        return []

    agents = []
    for md_file in sorted(agents_dir.glob("*.md")):
        try:
            content = md_file.read_text(encoding="utf-8").strip()
            if not content:
                continue

            # Extract description from first line or heading
            first_line = content.split("\n")[0].strip()
            if first_line.startswith("#"):
                description = first_line.lstrip("#").strip()
            else:
                description = (
                    first_line[:60] + "..." if len(first_line) > 60 else first_line
                )

            agents.append(
                CustomAgent(
                    name=md_file.stem,
                    description=description,
                    prompt=content,
                )
            )
            log.debug(f"Loaded agent from {md_file.name}")
        except Exception as e:
            log.warning(f"Failed to load agent {md_file.name}: {e}")

    if agents:
        log.info(f"Loaded {len(agents)} custom agent(s) from {agents_dir}")

    return agents


def load_agent(name: str, repo_root: Optional[Path] = None) -> Optional[CustomAgent]:
    """Load a specific agent by name.

    Args:
        name: Agent name (filename without .md extension)
        repo_root: Repository root directory

    Returns:
        CustomAgent if found, None otherwise.
    """
    agents_dir = get_agents_dir(repo_root)
    agent_file = agents_dir / f"{name}.md"

    if not agent_file.exists():
        log.debug(f"Agent file not found: {agent_file}")
        return None

    try:
        content = agent_file.read_text(encoding="utf-8").strip()
        if not content:
            return None

        first_line = content.split("\n")[0].strip()
        if first_line.startswith("#"):
            description = first_line.lstrip("#").strip()
        else:
            description = first_line[:60]

        log.info(f"Loaded agent '{name}' from {agent_file}")
        return CustomAgent(
            name=name,
            description=description,
            prompt=content,
        )
    except Exception as e:
        log.warning(f"Failed to load agent {name}: {e}")
        return None


def ensure_agents_dir(repo_root: Optional[Path] = None) -> Path:
    """Ensure the agents directory exists.

    Args:
        repo_root: Repository root. Uses cwd if not provided.

    Returns:
        Path to the created/existing agents directory.
    """
    agents_dir = get_agents_dir(repo_root)
    agents_dir.mkdir(parents=True, exist_ok=True)
    return agents_dir
