from __future__ import annotations

from pathlib import Path

import yaml

from tests.pipeline_setup.suite_02_pipeline.pipeline_intent_rag.helpers.models import PhraseCase


class PhraseCatalogLoader:
    def load(self, path: Path) -> list[PhraseCase]:
        payload = yaml.safe_load(path.read_text(encoding="utf-8"))
        if not isinstance(payload, dict):
            raise ValueError(f"Invalid phrases file: expected mapping, got {type(payload).__name__}")
        items = payload.get("phrases", [])
        if not isinstance(items, list):
            raise ValueError("Invalid phrases file: `phrases` must be a list")
        cases = [self._to_case(raw) for raw in items]
        if not cases:
            raise ValueError("No phrase cases found in phrases file")
        return cases

    def filter_by_tag(self, cases: list[PhraseCase], tag: str) -> list[PhraseCase]:
        return [case for case in cases if tag in case.tags]

    def _to_case(self, raw: object) -> PhraseCase:
        if not isinstance(raw, dict):
            raise ValueError("Invalid phrase item: expected object")
        case_id = str(raw.get("id", "")).strip()
        text = str(raw.get("text", "")).strip()
        if not case_id:
            raise ValueError("Invalid phrase item: `id` is required")
        if not text:
            raise ValueError(f"Invalid phrase item `{case_id}`: `text` is required")
        tags = [str(item).strip() for item in raw.get("tags", []) if str(item).strip()]
        expected_intent = raw.get("expected_intent")
        rag_session_id = str(raw.get("rag_session_id", "")).strip() or None
        return PhraseCase(
            case_id=case_id,
            text=text,
            rag_session_id=rag_session_id,
            tags=tags,
            expected_intent=str(expected_intent).strip() if expected_intent else None,
            expect_non_empty_rag=bool(raw.get("expect_non_empty_rag", True)),
        )
