"""Discovery engine - detect agents and project structure.

Lightweight discovery for backbone generation and map display.
"""

from __future__ import annotations

from pathlib import Path
from typing import Any

import yaml

from reporails_cli.core.agents import DetectedAgent


def detect_project_structure(target: Path) -> dict[str, Any]:
    """Detect common project structure directories and config files.

    Args:
        target: Project root

    Returns:
        Dict with detected structure keys (source, tests, docs, scripts, config)
    """
    structure: dict[str, Any] = {}

    # Directory patterns: (key, candidate_dirs)
    dir_patterns: list[tuple[str, list[str]]] = [
        ("source", ["src", "lib", "app"]),
        ("tests", ["tests", "test", "__tests__"]),
        ("docs", ["docs", "documentation"]),
        ("scripts", ["scripts", "bin"]),
    ]

    for key, candidates in dir_patterns:
        for candidate in candidates:
            candidate_path = target / candidate
            if candidate_path.is_dir():
                # Use the most specific subdir if there's only one child
                # e.g., src/reporails_cli/ -> src/reporails_cli/
                children = [c for c in candidate_path.iterdir() if c.is_dir() and not c.name.startswith((".", "__"))]
                if len(children) == 1 and key == "source":
                    structure[key] = str(children[0].relative_to(target)) + "/"
                else:
                    structure[key] = candidate + "/"
                break

    # Config files at project root
    config_patterns = [
        "pyproject.toml",
        "package.json",
        "Cargo.toml",
        "go.mod",
        "Makefile",
        "Dockerfile",
        "docker-compose.yml",
        "tsconfig.json",
        ".semgrepignore",
    ]
    config_files = [f for f in config_patterns if (target / f).exists()]
    if config_files:
        structure["config"] = config_files

    return structure


def generate_backbone_yaml(target: Path, agents: list[DetectedAgent]) -> str:
    """Generate backbone.yml content from detected agents.

    Args:
        target: Project root
        agents: Detected agents

    Returns:
        YAML string for backbone file
    """
    data: dict[str, Any] = {
        "version": 2,
        "generator": "ails map",
    }

    # Build agents section
    agents_data: dict[str, Any] = {}
    for agent in agents:
        agent_data: dict[str, Any] = {}

        # Main instruction file (first root-level file)
        root_files = [f for f in agent.instruction_files if f.parent == target]
        if root_files:
            agent_data["main_instruction_file"] = str(root_files[0].relative_to(target))

        # Detected directories
        agent_data.update(agent.detected_directories)

        # First config file
        if agent.config_files:
            agent_data["config"] = str(agent.config_files[0].relative_to(target))

        agents_data[agent.agent_type.id] = agent_data

    if agents_data:
        data["agents"] = agents_data

    # Build structure section
    structure = detect_project_structure(target)
    if structure:
        data["structure"] = structure

    header = "# Auto-generated by ails map. Customize freely.\n"
    yaml_output: str = yaml.dump(data, default_flow_style=False, sort_keys=False, allow_unicode=True)
    return header + yaml_output


def generate_backbone_placeholder() -> str:
    """Generate a minimal backbone.yml placeholder.

    Created automatically during `ails check` if no backbone exists.
    Users should run `ails map --save` to populate it.

    Returns:
        YAML string for placeholder backbone file
    """
    return "# Run `ails map --save` to populate.\nversion: 2\n"


def save_backbone(target: Path, content: str) -> Path:
    """Save backbone.yml to target's .reporails directory.

    Args:
        target: Project root
        content: YAML content

    Returns:
        Path to saved file
    """
    backbone_dir = target / ".reporails"
    backbone_dir.mkdir(parents=True, exist_ok=True)

    backbone_path = backbone_dir / "backbone.yml"
    backbone_path.write_text(content, encoding="utf-8")

    return backbone_path
