"""Research method registry for Phase 1 framework selection."""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path
from typing import Any

import yaml


REPO_ROOT = Path(__file__).resolve().parents[2]
DEFAULT_METHOD_CONFIG = REPO_ROOT / "configs" / "research_methods.yaml"


@dataclass(frozen=True)
class ResearchMethod:
    key: str
    name: str
    best_for: list[str]
    structure_principle: str
    task_axes: list[str]
    framework_sections: list[str]
    integrated_lanes: list[str]


class ResearchMethodRegistry:
    def __init__(self, path: Path | None = None) -> None:
        self.path = path or DEFAULT_METHOD_CONFIG
        self._data = self._load()

    def _load(self) -> dict[str, Any]:
        if not self.path.exists():
            raise FileNotFoundError(f"research method config not found: {self.path}")
        data = yaml.safe_load(self.path.read_text(encoding="utf-8")) or {}
        if not isinstance(data, dict) or "methods" not in data:
            raise ValueError(f"invalid research method config: {self.path}")
        return data

    @property
    def default_method(self) -> str:
        return (self._data.get("defaults") or {}).get("method", "mckinsey_market")

    def list_names(self) -> list[str]:
        return sorted((self._data.get("methods") or {}).keys())

    def get(self, key: str | None = None) -> ResearchMethod:
        selected = key or self.default_method
        methods = self._data.get("methods") or {}
        if selected not in methods:
            raise KeyError(f"unknown research_method: {selected}")
        item = methods[selected] or {}
        return ResearchMethod(
            key=selected,
            name=item.get("name", selected),
            best_for=list(item.get("best_for") or []),
            structure_principle=item.get("structure_principle", ""),
            task_axes=list(item.get("task_axes") or []),
            framework_sections=list(item.get("framework_sections") or []),
            integrated_lanes=list(item.get("integrated_lanes") or item.get("task_axes") or []),
        )
