"""Agent configuration loading helpers."""

from __future__ import annotations

from pathlib import Path

from core.models import AgentConfig
from core.serialization import load_data


REQUIRED_OUTPUT_FIELDS = {"response"}
PM_REQUIRED_OUTPUT_FIELDS = {"analysis", "next_action"}


def _validate_agent_output_schema_compatibility(config: AgentConfig) -> None:
    properties = config.output_schema.get("properties", {})
    required = set(config.output_schema.get("required", []))

    if config.name == "pm":
        if not PM_REQUIRED_OUTPUT_FIELDS.issubset(properties):
            raise ValueError("pm output_schema must define PMDecision core fields")
        if not PM_REQUIRED_OUTPUT_FIELDS.issubset(required):
            raise ValueError("pm output_schema must require PMDecision core fields")
        return

    if not REQUIRED_OUTPUT_FIELDS.issubset(properties):
        raise ValueError("agent output_schema must define the required runtime fields")
    if not REQUIRED_OUTPUT_FIELDS.issubset(required):
        raise ValueError("agent output_schema must require the runtime response field")


def load_agent_config(path: Path) -> AgentConfig:
    """Load and validate one agent config file."""

    if not path.exists():
        raise FileNotFoundError(path)
    if path.suffix.lower() not in {".json", ".yaml", ".yml"}:
        raise ValueError(f"unsupported agent config format: {path.suffix}")

    config = AgentConfig.model_validate(load_data(path))
    _validate_agent_output_schema_compatibility(config)
    return config


def load_named_agents(agent_names: list[str], agents_dir: Path) -> dict[str, AgentConfig]:
    """Load agent configs by name from a directory."""

    loaded: dict[str, AgentConfig] = {}
    for name in agent_names:
        candidate_paths = [
            agents_dir / f"{name}.yaml",
            agents_dir / f"{name}.yml",
            agents_dir / f"{name}.json",
        ]
        match = next((path for path in candidate_paths if path.exists()), None)
        if match is None:
            raise FileNotFoundError(f"agent config not found for '{name}' in {agents_dir}")
        loaded[name] = load_agent_config(match)
    return loaded
