"""
StapleLibrary -- bulk-preparable base component reference data.
Loaded from YAML files in app/staples/.
"""
from __future__ import annotations

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

import yaml

_STAPLES_DIR = Path(__file__).parents[2] / "staples"


@dataclass(frozen=True)
class StapleEntry:
    slug: str
    name: str
    description: str
    dietary_labels: list[str]
    base_ingredients: list[str]
    base_method: str
    base_time_minutes: int
    yield_formats: dict[str, Any]
    compatible_styles: list[str]


class StapleLibrary:
    def __init__(self, staples_dir: Path = _STAPLES_DIR) -> None:
        self._staples: dict[str, StapleEntry] = {}
        for yaml_path in sorted(staples_dir.glob("*.yaml")):
            entry = self._load(yaml_path)
            self._staples[entry.slug] = entry

    def get(self, slug: str) -> StapleEntry | None:
        return self._staples.get(slug)

    def list_all(self) -> list[StapleEntry]:
        return list(self._staples.values())

    def filter_by_dietary(self, label: str) -> list[StapleEntry]:
        return [s for s in self._staples.values() if label in s.dietary_labels]

    def _load(self, path: Path) -> StapleEntry:
        try:
            data = yaml.safe_load(path.read_text())
            return StapleEntry(
                slug=data["slug"],
                name=data["name"],
                description=data.get("description", ""),
                dietary_labels=data.get("dietary_labels", []),
                base_ingredients=data.get("base_ingredients", []),
                base_method=data.get("base_method", ""),
                base_time_minutes=int(data.get("base_time_minutes", 0)),
                yield_formats=data.get("yield_formats", {}),
                compatible_styles=data.get("compatible_styles", []),
            )
        except (KeyError, yaml.YAMLError) as exc:
            raise ValueError(f"Failed to load staple from {path}: {exc}") from exc
