from __future__ import annotations

from typing import Any

from niannian.agents.loop_runner import AgentLoopRun, AgentLoopRunner


class AgentLoopNotConfigured(Exception):
    """Loop 未配置或未启用。"""


class AgentLoopRegistry:
    """多 Agent 协作 Loop — v0.4.1 sequential runner。"""

    def __init__(
        self,
        agents_cfg: dict[str, Any] | None = None,
        *,
        runner: AgentLoopRunner | None = None,
    ) -> None:
        raw = (agents_cfg or {}).get("agent_loops") or {}
        loops = raw.get("loops") or []
        self._loops: dict[str, dict[str, Any]] = {}
        for item in loops:
            if isinstance(item, dict) and item.get("id"):
                self._loops[str(item["id"])] = item
        self._runner = runner or AgentLoopRunner()

    def list_loops(self) -> list[dict[str, Any]]:
        out: list[dict[str, Any]] = []
        for loop_id, cfg in self._loops.items():
            out.append(
                {
                    "id": loop_id,
                    "enabled": bool(cfg.get("enabled")),
                    "mode": cfg.get("mode", "sequential"),
                    "steps": len(cfg.get("steps") or []),
                }
            )
        return out

    def get_loop(self, loop_id: str) -> dict[str, Any] | None:
        return self._loops.get(loop_id)

    def start(self, loop_id: str, *, context: dict[str, Any] | None = None) -> AgentLoopRun:
        cfg = self._loops.get(loop_id)
        if cfg is None:
            raise AgentLoopNotConfigured(f"unknown loop {loop_id!r}")
        if not cfg.get("enabled"):
            raise AgentLoopNotConfigured(f"loop {loop_id!r} is disabled")
        mode = str(cfg.get("mode") or "sequential")
        if mode != "sequential":
            raise AgentLoopNotConfigured(f"loop {loop_id!r} mode {mode!r} not supported")
        return self._runner.run(loop_id, cfg, context=context)

    def health_summary(self) -> dict[str, Any]:
        enabled = sum(1 for cfg in self._loops.values() if cfg.get("enabled"))
        return {
            "registered": len(self._loops),
            "enabled": enabled,
            "implemented": True,
            "loops": self.list_loops(),
        }
